分布式文件存储与数据缓存 Redis高可用分布式实践(上)(二)

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: 分布式文件存储与数据缓存 Redis高可用分布式实践(上)(二)

二、Redis安装

2.1 Linux下安装Redis

下载地址

Redis官方网址:Redis

下载Redis安装包源文件

鼠标右键选择复制连接地址,在linux下使用wget下载安装包(或者直接下载到win,再上传到Linux)

wget https://github.com/redis/redis/archive/6.2.6.tar.gz

将安装包解压到/usr/local目录下

安装C语言编译环境GCC

#查看是否安装了gcc
gcc --version
#安装gcc
yum install -y gcc

编译Redis

在redis-6.2.6文件下执行编译命令,将redis源码编译成可执行的文件

[root@localhost redis-6.2.6]# make

安装Redis

在redis-6.2.6目录下执行

[root@localhost redis-6.2.6]# make install

打开src文件发现绿色的命令文件

注意:

redis-benchmark:Redis自带的基准性能测试工具

redis-check-aof:对有问题的 AOF 文件进行修复,AOF和RDB文件后面会说明

redis-check-rdb:对有问题的 RDB文件进行修复

redis-sentinel:Redis集群使用

redis-cli:客户端

redis-server:服务器启动

服务启动

前台启动:/usr/local/redis-2.6.2/src下执行

./redis-server

后台启动

修改redis.conf文件,在resid-6.2.6根目录下

daemonize  yes   #由no改为yes

在src下启动服务

[root@localhost src]# ./redis-server ../redis.conf

进入redis数据库

[root@localhost src]# ./redis-cli

2.2 Docker安装Redis

下载最新Redis镜像

docker pull redis

注意:

可以用docker pull redis命令下载最新版本的Redis镜像,也可 以用“docker pull redis:标签”命令下载指定版本的Redis。

启动Redis容器

docker run -itd --name myFirstRedis -p 6379:6379
redis:latest

观察Redis启动效果

docker logs myFirstRedis

注意:

如果直接在Linux等环境上启动Redis服务器,就能直接看到启动后的效果。

查看Redis的版本

先确保myFirstRedis容器处于Up状态。进入容器的命令行交互窗口。

docker exec -it myFirstRedis /bin/bash
redis-server --version

Redis服务器和客户端

Redis是基于键值对存储的NoSQL数据库,其中的数据是存储在 Redis服务器里的。和传统的MySQL数据库服务器相似,一个Redis服务器可以同多个客户端创建连接。

docker exec -it myFirstRedis /bin/bash
redis-cli

2.3 基础知识

默认16数据库

Redis是一个字典结构的存储服务器,一个Redis实例提供了多个用来存储数据的字典,客户端可以指定将数据存储在哪个字典中。

这与在一个关系数据库实例中可以创建多个数据库类似(如下图所示),所以可以将其中的每个字典都理解成一个独立的数据库。

Redis默认支持16个数据库,可以通过调整Redis的配置文件redis/redis.conf中的databases来修改这一个值,设置完毕后重启Redis便完成配置。

Redis 使用的到底是多线程还是单线程?

因为Redis是基于内存的操作,CPU不是Redis的瓶颈,Redis的瓶颈最有可能是机器内存的大小或者网络带宽。既然单线程容易实现,而且CPU不会成为瓶颈,那就顺理成章地采用单线程的方案了。

IO多路复用技术

redis 采用网络IO多路复用技术来保证在多连接的时候, 系统的高吞吐量。

这里“多路”指的是多个网络连接,“复用”指的是复用同一个线程。采用多路 I/O 复用技术可以让单个线程高效的处理多个连接请求(尽量减少网络IO的时间消耗),且Redis在内存中操作数据的速度非常快(内存内的操作不会成为这里的性能瓶颈),主要以上两点造就了Redis具有很高的吞吐量。

大白话解释

假设你是一个机场的空管, 你需要管理到你机场的所有的航线, 包括进港,出港, 有些航班需要放到停机坪等待,有些航班需要去登机口接乘客。最简单的做法,就是你去招一大批空管员,然后每人盯一架飞机, 从进港,接客,排位,出港,航线监控,直至交接给下一个空港,全程监控。

遇到的问题:

  • 很快你就发现空管塔里面聚集起来一大票的空管员,交通稍微繁忙一点,新的空管员就已经挤不进来了。
  • 空管员之间需要协调,屋子里面就1, 2个人的时候还好,几十号人以后 ,基本上就成菜市场了。
  • 空管员经常需要更新一些公用的东西,比如起飞显示屏,比如下一个小时后的出港排期,最后你会很惊奇的发现,每个人的时间最后都花在了抢这些资源上。

切换数据库

select number

示例:

# 默认使用 0 号数据库
redis 127.0.0.1:6379> SET db_number 0 
OK
# 使用 1 号数据库
redis 127.0.0.1:6379> select 1   
OK
127.0.0.1:6379[1]>

为当前数据库添加数据

127.0.0.1:6379> set k3 30
OK

清空当前库

Redis Flushdb 命令用于清空当前数据库中的所有 key。

127.0.0.1:6379>flushdb

通杀全部库

Redis Flushall 命令用于清空整个 Redis 服务器的数据(删除所有数据库的所有 key )。

redis 127.0.0.1:6379> FLUSHALL

为什么默认端口6379?

意大利的一位广告女郎名字叫Merz全名Alessia Merz。

6379 = Merz

三、Redis数据类型

3.1 key键类型

keys

查看当前库中所有的key 。

keys *

有3个通配符 *, ? ,[]

  • *: 通配任意多个字符
  • ?: 通配单个字符
  • []: 通配括号内的某1个字符

但是在实际生产环境中不建议使用该命令。新版本也进行了替代:

[root@localhost src]# ./redis-cli --scan "*"
"k1"

exists

判断某个key是否存在,返回1表示存在,0不存在。

exists key

示例:

#查看k1是否存在,如果存在返回1
127.0.0.1:6379> exists k1
(integer) 1
# 查看k1 k2 k3是否存在,如果k1 k2存在,k3不存在,则返回2
127.0.0.1:6379> exists k1 k2 k3
(integer) 2

注意:

可以设置多个key,只返回存在的个数,但不返回哪一个存在/不存在。

type

查看当前key 所储存的值的类型。返回当前key所储存的值的类型,如string 、list等。

type key

示例:

127.0.0.1:6379> type k1
string

del

删除已存在的key,不存在的 key 会被忽略。

del key

示例:

可以设置多个key,返回删除成功的个数。

#  删除k1,如果成功返回1,失败返回0
del k1
# 删除k1 k2 k3,如果k1 k2存在,k3不存在,则返回2
del k1 k2 k3

expire

给key设置time秒的过期时间。设置成功返回 1 。 当 key 不存在返回 0。

expire key time

示例:

# 给k1设置30秒后删除
127.0.0.1:6379> expire k1 30
(integer) 1

应用场景是手机验证码

ttl

以秒为单位返回 key 的剩余过期时间。

ttl key

示例:

127.0.0.1:6379> ttl k1
(integer) 25

注意:

当 key 不存在时,返回 -2 。 当 key 存在但没有设置剩余生存时间时,返回 -1 。 否则,以秒为单位,返回 key 的剩余生存时间。

persist

移除给定 key 的过期时间,使得 key 永不过期。

persist key

示例:

persist k1

3.2 String类型

简介

String是Redis最基本的类型,一个key对应一个value。String是二进制安全的,意味着String可以包含任何数据,比如序列化对象或者一张图片。String最多可以放512M的数据。

set

用于设置给定 key 的值。如果 key 已经存储其他值, set 就重写旧值,且无视类型。

set key value

示例:

127.0.0.1:6379> set k1 v1
OK

get

用于获取指定 key 的值。如果 key 不存在,返回 nil 。

get key

示例:

127.0.0.1:6379> get k1
"v1"

append

将给定的value追加到key原值末尾。

append key value

示例:

127.0.0.1:6379> append k2 "aaa"
(integer) 5
127.0.0.1:6379> get k2
"20aaa"

注意:

  • 如果 key 已经存在并且是一个字符串, append 命令将 value 追加到 key 原来的值的末尾。
  • 如果 key 不存在, append 就简单地将给定 key 设为 value ,就像执行 set key value 一样。

strlen

获取指定 key 所储存的字符串值的长度。当 key 储存的不是字符串值时,返回一个错误。

127.0.0.1:6379> strlen k2
(integer) 5

setex

给指定的 key 设置值及time 秒的过期时间。如果 key 已经存在, setex命令将会替换旧的值,并设置过期时间。

setex key time value

示例:

#向Redis中设置一个k1的键值对并且10秒后过期
127.0.0.1:6379> setex k1 10 v1
OK

应用场景是短信验证码

setnx

只有在key不存在时设置key的值

setnx key value

示例:

127.0.0.1:6379> setnx k1 v1
(integer) 0
127.0.0.1:6379> setnx k4 v4
(integer) 1

getrange

获取指定区间范围内的值,类似between........and 的关系

getrange key start end

示例:

127.0.0.1:6379> set k5 abcd123xxx
OK
127.0.0.1:6379> getrange k5 2 4
"cd1"

setrange

获取指定区间范围内的值,类似between........and 的关系

setrange key offset value

示例:

127.0.0.1:6379> set k6 abcd1234
OK
127.0.0.1:6379> setrange k6 1 xxx
(integer) 8
127.0.0.1:6379> get k6
"axxx1234"

incr

将 key 中储存的数字值增一。

incr key

示例:

#因为Redis中不存在k1,所以先初始化为0,再递增,值为1
127.0.0.1:6379> incr k1
(integer) 1
# incr k1 存在k1,递增后k1的值为2
127.0.0.1:6379> incr k1
(integer) 2
# 如果value不是数字就会报错
127.0.0.1:6379> set k2 v2
OK
127.0.0.1:6379> INCR k2
(error) ERR value is not an integer or out of range

注意:

  • 如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 incr 操作。
  • 如字符串类型的值不能表示为数字、或者是其他类型,那么返回一个错误。

decr

将 key 中储存的数字值减一。

decr key

示例:

127.0.0.1:6379> decr k1
(integer) 1
127.0.0.1:6379> decr k1
(integer) 0
127.0.0.1:6379> decr k1
(integer) -1
127.0.0.1:6379> decr k1
(integer) -2
#如果 
set k2 v2 
decr k2 因为k2不为数值,Redis返回一个错误

注意:

  • 如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 decr 操作。
  • 如字符串类型的值不能表示为数字、或者是其他类型,那么返回一个错误。

incrby/decrby key step

将key存储的数字值按照step进行增减。

127.0.0.1:6379> incrby k1 10
(integer) 20

注意:

  • 如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 incrby/decrby 命令。
  • 如字符串类型的值不能表示为数字、或者是其他类型,那么返回一个错误。

mset

同时设置一个或多个 key-value 。

mset key1 value1 key2 value2

示例:

127.0.0.1:6379> mset k1 v1 k2 v2 k3 v3
OK

mget

返回所有(一个或多个)给定 key 的值。

mget  key1 key2

示例:

127.0.0.1:6379> mget k1 k2 k3
1) "v1"
2) "v2"
3) "v3"

注意:

如果给定的 key 里面,有某个 key 不存在,那么这个 key 返回特殊值 nil 。

getset

将给定key值设为value,并返回key的旧值(old value),简单一句话(先get然后立即set)。

getset key value

示例:

127.0.0.1:6379> getset k1 wcc
"v1"
127.0.0.1:6379> get k1
"wcc"

使用场景

value 除了是字符串以外还可以是数字。

  • 计数器
  • 统计多单位的数量
  • 粉丝数
  • 对象缓存存储
  • 分布式锁

3.3 List类型

简介

List是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)。底层是一个双向链表,对两段操作性能极高,通过索引操作中间的节点性能较差。

lpush/rpush

从左边(头部)/右边(尾部)插入一个或多个值。

lpush/rpush key1 value1  value2 value3……

示例:

#从左边放入v1 v2 v3
127.0.0.1:6379> lpush k1 v1 v2 v3 
(integer) 3

#从右边放入v4 v5 v6
127.0.0.1:6379> rpush k1 v4 v5 v6
(integer) 6

lrange

返回key列表中的start和end之间的元素(包含start和end)。 其中 0 表示列表的第一个元素,-1表示最后一个元素。

lrange key start end

示例:

127.0.0.1:6379> lrange k1 0 -1
1) "v3"
2) "v2"
3) "v1"
127.0.0.1:6379>

lpop/rpop

移除并返回第一个值或最后一个值。

lpop/rpop  key

示例:

127.0.0.1:6379> lpop k1
"v3"
127.0.0.1:6379> rpop k1
"v1"

注意:

值在键在,值光键亡。

lindex

获取列表index位置的值(从左开始)。

lindex key index

示例:

127.0.0.1:6379> lindex k1 0
"v2"

llen

获取列表长度。

llen key

示例:

127.0.0.1:6379> llen k1
(integer) 1

lrem

从左边开始删除与value相同的count个元素。

lrem key count value

示例:

#从左边开始删除k1列表中2个v2元素
127.0.0.1:6379> lrange k1 0 -1
1) "v7"
2) "v6"
3) "v5"
4) "v4"
5) "v3"
6) "v2"
7) "v1"
8) "v2"
127.0.0.1:6379> lrem k1  2 v2
(integer) 2
127.0.0.1:6379> lrange k1 0 -1
1) "v7"
2) "v6"
3) "v5"
4) "v4"
5) "v3"
6) "v1"

linsert

在列表中value值的前边/后边插入一个new value值(从左开始)。

linsert key before/after value newvalue

示例:

# 在v1前面插入一个v8
127.0.0.1:6379> linsert k1 before v1 v8
(integer) 7
127.0.0.1:6379> lrange k1 0 -1
1) "v7"
2) "v6"
3) "v5"
4) "v4"
5) "v3"
6) "v8"
7) "v1"

lset

将索引为index的值设置为value

lset key index value

示例:

#将索引为0的值改为aaa
127.0.0.1:6379> lset k1 0 aaa
OK
127.0.0.1:6379> lrange k1 0 -1
1) "aaa"
2) "v6"
3) "v5"
4) "v4"
5) "v3"
6) "v8"
7) "v1"

使用场景

  • 消息队列
  • 排行榜
  • 最新列表


相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
1月前
|
NoSQL Redis
Redis的数据淘汰策略有哪些 ?
Redis 提供了 8 种数据淘汰策略,分为淘汰易失数据和淘汰全库数据两大类。易失数据淘汰策略包括:volatile-lru、volatile-lfu、volatile-ttl 和 volatile-random;全库数据淘汰策略包括:allkeys-lru、allkeys-lfu 和 allkeys-random。此外,还有 no-eviction 策略,禁止驱逐数据,当内存不足时新写入操作会报错。
81 16
|
2天前
|
存储 缓存 NoSQL
解决Redis缓存数据类型丢失问题
解决Redis缓存数据类型丢失问题
116 85
|
1月前
|
缓存 NoSQL 关系型数据库
大厂面试高频:如何解决Redis缓存雪崩、缓存穿透、缓存并发等5大难题
本文详解缓存雪崩、缓存穿透、缓存并发及缓存预热等问题,提供高可用解决方案,帮助你在大厂面试和实际工作中应对这些常见并发场景。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:如何解决Redis缓存雪崩、缓存穿透、缓存并发等5大难题
|
1月前
|
存储 缓存 NoSQL
【赵渝强老师】基于Redis的旁路缓存架构
本文介绍了引入缓存后的系统架构,通过缓存可以提升访问性能、降低网络拥堵、减轻服务负载和增强可扩展性。文中提供了相关图片和视频讲解,并讨论了数据库读写分离、分库分表等方法来减轻数据库压力。同时,文章也指出了缓存可能带来的复杂度增加、成本提高和数据一致性问题。
【赵渝强老师】基于Redis的旁路缓存架构
|
1月前
|
缓存 NoSQL 关系型数据库
Redis和Mysql如何保证数据⼀致?
在项目中,为了解决Redis与Mysql的数据一致性问题,我们采用了多种策略:对于低一致性要求的数据,不做特别处理;时效性数据通过设置缓存过期时间来减少不一致风险;高一致性但时效性要求不高的数据,利用MQ异步同步确保最终一致性;而对一致性和时效性都有高要求的数据,则采用分布式事务(如Seata TCC模式)来保障。
64 14
|
1月前
|
缓存 NoSQL Redis
Redis 缓存使用的实践
《Redis缓存最佳实践指南》涵盖缓存更新策略、缓存击穿防护、大key处理和性能优化。包括Cache Aside Pattern、Write Through、分布式锁、大key拆分和批量操作等技术,帮助你在项目中高效使用Redis缓存。
252 22
|
1月前
|
缓存 NoSQL PHP
Redis作为PHP缓存解决方案的优势、实现方式及注意事项。Redis凭借其高性能、丰富的数据结构、数据持久化和分布式支持等特点,在提升应用响应速度和处理能力方面表现突出
本文深入探讨了Redis作为PHP缓存解决方案的优势、实现方式及注意事项。Redis凭借其高性能、丰富的数据结构、数据持久化和分布式支持等特点,在提升应用响应速度和处理能力方面表现突出。文章还介绍了Redis在页面缓存、数据缓存和会话缓存等应用场景中的使用,并强调了缓存数据一致性、过期时间设置、容量控制和安全问题的重要性。
40 5
|
1月前
|
存储 NoSQL 算法
Redis分片集群中数据是怎么存储和读取的 ?
Redis集群采用哈希槽分区算法,共有16384个哈希槽,每个槽分配到不同的Redis节点上。数据操作时,通过CRC16算法对key计算并取模,确定其所属的槽和对应的节点,从而实现高效的数据存取。
49 13
|
1月前
|
存储 NoSQL Redis
Redis的数据过期策略有哪些 ?
Redis 采用两种过期键删除策略:惰性删除和定期删除。惰性删除在读取键时检查是否过期并删除,对 CPU 友好但可能积压大量过期键。定期删除则定时抽样检查并删除过期键,对内存更友好。默认每秒扫描 10 次,每次检查 20 个键,若超过 25% 过期则继续检查,单次最大执行时间 25ms。两者结合使用以平衡性能和资源占用。
49 11
|
1月前
|
监控 NoSQL 测试技术
【赵渝强老师】Redis的AOF数据持久化
Redis 是内存数据库,提供数据持久化功能,支持 RDB 和 AOF 两种方式。AOF 以日志形式记录每个写操作,支持定期重写以压缩文件。默认情况下,AOF 功能关闭,需在 `redis.conf` 中启用。通过 `info` 命令可监控 AOF 状态。AOF 重写功能可有效控制文件大小,避免性能下降。