先学习:Redis架构简介-CSDN博客
Redis压测
Redis一般应用于高并发的场景,所以一定要对Redis的性能做压测。
Redis提供了压测脚本redis-benchmark,可以对Redis进行快速的基准测试。
# 20个线程,100W个请求,测试redis的set指令(写数据)
redis-benchmark -a 123qweasd -t set -n 1000000 -c 20
...
Summary:
throughput summary: 116536.53 requests per second ##平均每秒11w次写
latency summary (msec):
avg min p50 p95 p99 max
0.111 0.032 0.111 0.167 0.215 3.199
Redis数据持久化
Redis持久化相关的配置,可以分为几个策略:
- 无持久化:不保证数据安全,只将Redis当做缓存用
- RDB(RedisDatabase):按照一定的时间间隔缓存Redis所有的数据快照
- AOF(Append Only File):记录Redis收到的每一次写操作,在之前的基础上进行追加新的操作
- RDB+AOF:
RDB特点
- RDB文件紧凑,适合定期备份,非常适合灾难恢复
- 主线程启动一个子线程进行RDB备份
- 数据备份时,需要将内存的数据克隆一份,如果数据量比较大,容易造成Redis短暂的服务停用。
- 不能进行实时备份,丢失数据风险
AOF特点
- Redis默认1s进行一次AOF写入,数据更安全
- AOF出现数据记录不完整的情况,可以使用redis-check-aof工具恢复
- AOF文件通常比RDB文件更大
- 写操作频繁的情况下,AOF的备份性能比RDB更慢
[root@192-168-65-214 appendonlydir]# redis-check-aof --fix appendonly.aof.1.incr.aof
混合持久策略(RDB+ AOF):
redis.conf配置文件中做配置
# Redis can create append-only base files in either RDB or AOF formats. Using
# the RDB format is always faster and more efficient, and disabling it is only
# supported for backward compatibility purposes.
aof-use-rdb-preamble yes
RDB
文件名默认dump.rdb。
何时触发RDB备份:
- 达到配置文件的配置要求
手动执行save或者bgsave指令时,会触发RDB快照。 其中save方法会在备份期间阻塞主线程。bgsve则不会阻塞主线程,会占用更多的cpu和内存。
主从复制(看Redis版本)
配置文件备份策略:
# Save the DB to disk.
# save <seconds> <changes> [<seconds> <changes> ...]
# save ""
# Unless specified otherwise, by default Redis will save the DB:
# * After 3600 seconds (an hour) if at least 1 change was performed
# * After 300 seconds (5 minutes) if at least 100 changes were performed
# * After 60 seconds if at least 10000 changes were performed
# You can set these explicitly by uncommenting the following line.
# save 3600 1 300 100 60 10000 -- 备份策略
- rdbcompression 是否启用RDB压缩,默认yes。 如果不想消耗CPU进行压缩,可以设置为no
- stop-writes-oin-bgsave-error 默认yes, 在快照写入失败时,也能确保redis继续接受新的写入请求。如果配置成no,表示你不在乎数据不一致或者有其他的手段发现和控制这种不一致。
- rdbchecksum 默认yes。在存储快照后,还可以让redis使用CRC64算法来进行数据校样做会增加大约10%的性能消耗。如果希望获得最大的性能提升,可以关闭此功能。
rdb日志恢复指令:redis-check-rdb, 因为rdb文件是二进制文件,所以不太容易篡改。
AOF
文件
# The base name of the append only file.
# Append-only file names are created by Redis following a specific pattern.
# The file name's prefix is based on the 'appendfilename' configuration
# parameter, followed by additional information about the sequence and type.
# For example, if appendfilename is set to appendonly.aof, the following file
# names could be derived:
# - appendonly.aof.1.base.rdb as a base file. -- rdb文件是二进制数据文件
# - appendonly.aof.1.incr.aof, appendonly.aof.2.incr.aof as incremental files. -- incr.aof是增量的操作日志
# - appendonly.aof.manifest as a manifest file. -- manifest文件信息元数据
appendfilename "appendonly.aof"
现在的AOF已经具备了RDB+AOF的功能。并且,拆分增量文件的方式,也能够进一步控制aof文件的大小。 虽然AOF具备了RDB的功能,但是因为AOF数据通常在不断变化,还是建议定期做RDB的备份。
appendonly.aof.1.incr.aof增量文件。里面其实就是按照Redis的协议记录了每一次操作。
127.0.0.1:6379> keys *
(empty array)
127.0.0.1:6379> set k1 v1
OK
127.0.0.1:6379> set k2 v2
OK
这组指令的文件示例:
配置
- appendonly 是否开启aof。 默认是不开启的。
- appendSync同步方式, 默认1s同步一次
- appenddirname AOF文件目录
- auto-aof-rewrite-percentage, auto-aof-rewrite-min-size 文件触发重写策略。
- no-appendfsync-on-rewrite aof重写期间是否同步
AOF日志恢复
修复的过程实际上就是将aof文件(appendonly.aof.1.incr.aof日志文件)的最后那一条不完整的指令删除掉。
主从复制Replica机制
配置方式
配从不配主原则
REPLICAOF host port|NO ONE : 一般配置到redis.conf中。
SLAVEOF host port|NO ONE: 在运行期间修改slave节点的信息。如果该服务已经是某个主库的从库了,那么就会停止和原master的同步关系。
-- 查看主从状态
127.0.0.1:6379> info replication
默认情况下,从库是只读的,不允许写入数据。因为数据只能从master往数据,就会造成数据不一致。但是从库没有禁止CONFIG、DEBUG等管理指令,这些指令如果和主节点不一致,还是容易造成数据不一致。
replica-read-only yes -- redis.conf中的配置
rename-command CONFIG "" 。 -- redis.conf中增加这个配置,屏蔽掉slave上的CONFIG指令。
复制时机
主从复制。当Master数据有变化时,自动将新的数据异步同步到其他slave中。
主从复制过程
哨兵机制Sentinel机制
配置方式
sentinel.conf
如何发现Master宕机
- S_DOWN(主观下线):通过心跳检测,一个Sentinel节点认为 Redis Master节点宕机了。
- O_DOWN(客观下线): 当一个Sentinel认为Redis Master宕机了,Redis的Sentinel就会互相进行沟通,当超过quorum(Sentinel集群的半数)个Sentinel节点都认为master已经出现S_DOWN后,就会将master标记为O_DOWN。
切换新Master过程
<1> master变成O_DOWN后,Sentinel集群Leader的节点负责协调整个故障切换过程。
<2>Sentinel会在剩余健康的Slave节点中选举出一个节点作为新的Master。选举采用采用的Raft算法, 选举的规则如下:
- 首先检查是否有提前配置的优先节点:各个服务节点的redis.conf中的replica-priority配置最低的从节点。这个配置的默认值是100。
- 如果配置都一样,检查复制偏移量offset最大的从节点。也就是找同步数据最快的slave节点。因为他的数据相对更全。
- 如果offset还是一样,最后按照slave的RunID字典顺序最小的节点。
<3>切换新的主节点。 Sentinel Leader给新的mater节点执行 slave of no one操作,将他提升为master节点。 然后给其他slave发送slave of 指令。让其他slave成为新Master的slave。
<4>如果旧的master恢复了,Sentinel Leader会让旧的master降级为slave,并从新的master上同步数据,恢复工作。
集群Cluster机制
配置方式
cluster-enabled yes -- 开启集群模式
cluster-config-file nodes-6379.conf -- 指定一个给集群进行修改的配置问文件
将多个独立的Redis服务整合成一个统一的集群:
--cluster create表示创建集群。
--cluster-replicas 表示为每个master创建一个slave节点。
接下来,Redis会自动分配主从关系,形成Redis集群。
[root@192-168-65-214 cluster]# redis-cli -a 123qweasd --cluster create --cluster-replicas 1 192.168.65.214:6381 192.168.65.214:6382 192.168.65.214:6383
192.168.65.214:6384 192.168.65.214:6385 192.168.65.214:6386
Redis在分配主从关系时,会优先将主节点和从节点分配在不同的机器上。
集群模式下的问题
1. 批量指令原子性问题
127.0.0.1:6381> mset k1 v1 k2 v2 k3 v3
(error) CROSSSLOT Keys in request don't hash to the same slot
不同的key对应到不同的槽位,分不到了不同的服务器,就出现分布式事务问题。
解决方案:
127.0.0.1:6381> CLUSTER KEYSLOT k1
(integer) 12706
127.0.0.1:6381> CLUSTER KEYSLOT roy{k1}
(integer) 12706
127.0.0.1:6381> CLUSTER KEYSLOT roy:k1
(integer) 12349
-- 使用相同的hash tag,能保证这些数据都是保存在同一个节点上的。
-- 如果key中有{}, 只根据{}中的内容计算槽位。
127.0.0.1:6381> mset user_{1}_name roy user_{1}_id 1 user_{1}_password 123
-> Redirected to slot [9842] located at 192.168.65.214:6382
OK
2. 数据倾斜
大量的数据被存储到集群中的某个热点Redis节点上
解决方案:
- 调整key的结构,尤其是那些访问频繁的热点key,让数据能够尽量平均的分配到各个slot上。
- 调整slot的分布,将那些数据量多,访问频繁的热点slot进行重新调配,让他们尽量平均的分配到不同的Redis节点上。
集群通信协议
Redis集群之间通过gossip协议进行频繁的通信,用于传递消息和更新节点状态。gossip协议包含多种消息,包括ping,pong,meet,fail等等。
gossip集群是去中心化的,各个节点彼此之间通过gossip协议互相通信,保证集群内部各个节点最终能够达成统一。
Redis集群中,每个节点都有一个专门用于节点之间进行gossip通信的端口,就是自己提供服务的端口+10000.因此,在部署Redis集群时,要注意防火墙配置,不要把这个端口屏蔽。
集群选举Master
当slave发现自己的master变为FAIL状态时,便尝试进行Failover,以期成为新的master。由于挂掉的master 可能会有多个slave,从而存在多个slave竞争成为master节点的过程, 其过程如下:
1》slave发现自己的master变为FAIL
2》将自己记录的集群currentEpoch加1,并广播FAILOVER_AUTH_REQUEST信息(currentEpoch代表选举周期)
3》其他节点收到该信息,只有master响应,判断请求者的合法性,并发送FAILOVER_AUTH_ACK,对每一个 epoch只发送一次ack(master应该根据特定的决定响应结果)
4》尝试Failover的slave收集master返回的FAILOVER_AUTH_ACK
5》slave收到超过半数master的ack后变成新Master
6》slave广播Pong消息通知其他集群节点
注意:slave节点并不是在master节点一进入 FAIL 状态就马上尝试发起选举,而是有一定延迟,确保mater FAIL状态在集群中传播,slave如果立即尝试选举,其它masters或许尚未意识到FAIL状态,可能会拒绝投票.