4. redis 主从架构redis replication:实现高并发高可用 单台redis的局限性:
- 内存上,单个Redis的内存不宜过大,内存过大会导致主从同步时全量同步时间过长,而且在实例重启恢复时也会消耗很长的数据加载时间,一般控制在10G以内即可。
- CPU 的利用率上,单个 Redis 实例只能利用单个核心,这单个核心在面临海量数据的存取和管理工作时压力会非常大。
- 单机redis,能够支撑QPS大概在5万左右,如果上千万的用户访问,redis就承载不了,成为了高并发的瓶颈。
redis 主从架构redis replication:实现高并发高可用。
4.1. redis replication架构 4.1.1. redis是实现系统高并发的重要缓存技术
mysql能支持的高并发,是通过一系列复杂的分库分表,订单系统,事务控制等达到的,且QPS只到几万,不会再高。除非一些特殊情况,如服务器性能特别好,配置特别高,维护做的特别好,且整体的操作不是太复杂。真正的超高并发,QPS上十万,甚至是百万。平台提供高并发最重要的是缓存架构,而redis是实现缓存架构最重要的技术。使用redis技术搭建缓存架构(读写分离、多级缓存架构、热点缓存),能支撑真正的上十万,甚至上百万的高并发。读写分离一般都是用来支撑读高并发,写的请求比较少,可能写请求也就一秒钟几千,而读一秒钟二十万次左右。
4.1.2. redis replication架构
Redis replication 是一种 master-slave 模式的复制机制,这种机制使得 slave 节点可以成为与 master 节点完全相同的副本。架构如下:
文章图片
1、redis采用异步方式复制数据到slave节点,不过redis 2.8开始,slave node会周期性地确认自己每次复制的数据量。
2、一个master node是可以配置多个slave node。
3、slave node也可以连接其他的slave node。
4、slave node做复制的时候,是不会阻塞 master node的正常工作。
5、slave node在做复制的时候,也不会阻塞对自己的查询操作,它会用旧的数据集来提供服务; 但是复制完成的时候,需要删除旧数据集,加载新数据集,这个时候就会暂停对外服务了。
6、slave node主要用来进行横向扩容,做读写分离,扩容的slave node可以提高读的吞吐量。
我们知道,单个 Redis 节点也是可以直接工作的。那为什么一个 Redis 节点(master)还需要一个或多个副本(slave)呢?或者说 replication 到底想要解决什么问题
4.1.2.1. redis replication实现读扩展
一个 master 用于写,多个 slave 用于分摊读的压力。
文章图片
4.1.2.2. redis replication实现高可用
如果 master 挂掉了,可以提升(promote)一个 slave 为新的 master,进而实现故障转移(failover)。
【redis缓存架构详解(五)- redis 主从架构-redis replication原理分析】
文章图片
4.2. master持久化、备份对主从架构的安全意义 1、master node必须做持久化
**使用主从架构,必须开启master node的持久化!不建议用slave node作为master node的数据热备。**master的持久化关闭,可能在master宕机重启的时候数据是空的(RDB和AOF都关闭了),此时就会将空数据复制到salve ,导致slave node数据也丢了。
2、master node必须做好备份方案
使用主从架构,master要做好各种备份方案,如果本地的所有文件丢失了;
,可以从备份中挑选一份rdb去恢复master, 这样才能确保master启动的时候,能从rdb、aof文件中加载数据,保证master有数据,从而也保证了各个slave node有数据。即使采用了哨兵sentinel高可用机制,slave node可以自动接管master node,但是也可能sentinel还没有检测到master failure,master node就自动重启了,还是可能导致上面的所有slave node数据清空故障
4.3. redis主从复制核心原理 4.3.1. 主从架构复制的核心原理
文章图片
4.3.1.1. 主要原理
1、当启动一个slave node的时候,它会发送一个PSYNC命令给master node,此时slave node仅保存master node的信息,包括master node的host和ip,但是复制流程没开始。master host和ip是配置在redis.conf里面的slaveof。4.3.1.2. 数据同步相关的核心机制
(1)slave node内部有个定时任务,每秒检查是否有新的master node要连接和复制,如果发现,就跟master node建立socket网络连接
(2)slave node发送ping命令给master node
(3)口令认证,如果master设置了requirepass,那么salve node必须发送masterauth的口令过去进行认证
2、如果slave node重新连接master node,那么master node仅仅会复制给slave部分缺少的数据;
3、如果slave node第一次连接master node,那么会触发一次full resynchronization
(1)开始full resynchronization的时候,master会启动一个后台线程,开始生成一份RDB快照文件。
(2)此时如果客户端有写入数据到master,所有写命令缓存在内存中。
(3)RDB文件生成完毕之后,master会将这个RDB发送给slave,slave会先写入本地磁盘,然后再从本地磁盘加载到内存中。
(4)然后master会将内存中缓存的写命令发送给slave,slave也会同步这些数据。
4、slave node如果跟master node有网络故障,断开了连接,会自动重连。
5、master如果发现有多个slave node都来重新连接,仅仅会启动一个rdb save操作,用一份数据服务所有slave node。
数据同步:指第一次slave连接msater时执行的全量复制,这个过程细节如下:
1、master和slave都会维护一个offset:维护数据不一致的情况
(1)master会在自身不断累加offset,slave也会在自身不断累加offset。
(2)slave每秒都会上报自己的offset给master,同时master也会保存每个slave的offset。
offset不仅仅使用在全量复制,主要是master和slave都要知道各自数据的offset,才能知道互相之间的数据不一致的情况。
2、backlog:记录复制点,方便后期的增量复制
(1)master node有一个backlog,默认是1MB大小。
(2)master node给slave node复制数据时,也会将数据在backlog中同步写一份。
(3)backlog主要是用来做全量复制中断网后的增量复制。
3、master run id:用于slave node定位master node
(1)通过info server 命令,可以看到master run id。
(2)根据ip + host 定位 master node,是不靠谱的,如内网环境,给某个master 所在的服务实例修改内网Ip后,slave node就定位不到master node。
(3)master node重启或者数据出现了变化,slave node应该根据不同的run id 区分,run id不同就做全量复制。
(4)如果需要不更改run id重启redis,可以使用redis-cli debug reload命令。
4、psync
(1)从slave节点使用psync到master node进行复制,psync runid offset。
(2)master node会根据自身的情况返回响应信息,可能是FULLRESYNC runid offset触发全量复制,可能是CONTINUE触发增量复制。
4.3.1.3. 全量复制
(1)master执行bgsave,在本地生成一份rdb快照文件rdb生成后、通过网络拷贝到slave,slave旧数据的清理、slave aof rewrite,很耗费时间
(2)master node将rdb快照文件发送给salve node,如果rdb复制时间超过60秒(repl-timeout),那么slave node就会认为复制失败,可以适当调节大这个参数
(3)对于千兆网卡的机器,一般每秒传输100MB,6G文件,很可能超过60s
(4)master node在生成rdb时,会将所有新的写命令缓存在内存中,在salve node保存了rdb之后,再将新的写命令复制给salve node
(5)client-output-buffer-limit slave 256MB 64MB 60,如果在复制期间,内存缓冲区持续消耗超过64MB,或者一次性超过256MB,那么停止复制,复制失败
(6)slave node接收到rdb之后,清空自己的旧数据,然后重新加载rdb到自己的内存中,同时基于旧的数据版本对外提供服务
(7)如果slave node开启了AOF,那么会立即执行BGREWRITEAOF,重写AOF
如果复制的数据量在4G~6G之间,那么很可能全量复制时间消耗到1分半到2分钟
4.3.1.4. 增量复制
(1)如果全量复制过程中,master-slave网络连接断掉,那么salve重新连接master时,会触发增量复制。4.3.1.5. heartbeat
(2)master直接从自己的backlog中获取部分丢失的数据,发送给slave node,默认backlog就是1MB。
(3)msater就是根据slave发送的psync中的offset来从backlog中获取数据的。
4.3.1.6. 异步复制主从节点互相都会发送heartbeat信息。master默认每隔10秒发送一次heartbeat,salve node每隔1秒发送一个heartbeat
master每次接收到写命令之后,先在内部写入数据,然后异步发送给slave node。4.3.2. 主从复制的断点续传
从redis 2.8开始,redis 就支持主从复制的断点续传,如果主从复制过程中,网络连接断掉了,那么可以接着上次复制的地方,继续复制下去,而不是从头开始复制一份。
原理:
4.3.3. 无磁盘化复制master node会在内存中保存一个backlog,master和slave都会保存一个replica offset,还有一个master id,offset就是保存在backlog中的。如果master和slave网络连接断掉了,slave会让master从上次的replica offset开始继续复制。但是如果没有找到对应的offset,那么就会执行一次resynchronization
master在内存中直接创建rdb,然后发送给slave,不会在本地磁盘创建。
在redis.conf中有两个配置:
文章图片
repl-diskless-sync :是否开启无磁盘复制4.3.4. 过期key处理
repl-diskless-sync-delay:等待一定时长再开始复制,因为要等更多slave重新连接过来
slave不会出现过期的key,只会等待master过期的key。如果master过期了一个key,或者通过LRU淘汰了一个key,那么会模拟一条del命令发送给slave。