redis主从架构搭建及原理

什么情况下需要搭建redis主从架构

官方表明redis单机的读速度是110000次/s,写速度是81000次/s。但随着客户端连接数的增加redis的性能会逐步递减,这个时候如果还需要支持10W+的qps就需要搭建redis集群了。

redis主从架构模型

redis有两种架构模型:一种是主从架构,一种是分布式架构。这里主要介绍一下redis主从架构,也就是一主多从,主机节点负责写的请求,从节点来分摊读的请求。


redis主从架构

要注意的是这个架构写请求的瓶颈并不高,因为只有一个节点能接收写的操作,但可以不断增加slave节点来满足更多的读请求。

主从结构也可以呈现树状
从节点也可以从其他从节点来同步数据,这样可以减少主节点的压力。

主从树状结构

搭建redis主从架构

我们先准备两个节点来搭建一主一从的架构,先在两台机器上分别安装好单机的redis,可以参照这篇文章redis单机安装最佳实践

搭建好后在其中一个节点执行这个命令,可以看到当前节点的信息。当前节点是master节点,它有0个slave节点(在v5.x版本以前slave表示从节点,之后换成replication)。

127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:0
min_slaves_good_slaves:0
master_replid:c5221e5a3720c4ae102f6fe2fecfaa96c653b4ce
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:40538
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:5242880
repl_backlog_first_byte_offset:1
repl_backlog_histlen:40538

我们开始更改redis.conf的配置。我在实例中使用了两台虚拟机分别是

  • 192.168.20.198:6379(master),
  • 192.168.20.199:6379(slave)。

在slave更改以下配置

# 配置master的ip和端口
replicaof 192.168.20.198 6379 
# 设置访问master的密码
masterauth red123456
# 配置从不的过从中服务是否可用
# yes:主从复制中,从服务器可以响应客户端请求
# no:主从复制中,从服务器阻塞,有客户端请求时会返回:SYNC with master in progress
replica-serve-stale-data yes
# 配置从节点是否只读,只有在slave上配置可以生效
replica-read-only yes
# slave根据指定时间间隔向master发送ping请求
# 确保master和slave之间的心跳
repl-ping-replica-period 10

在master更改以下配置

# 复制缓冲区的大小
# 缓存区的作用就是用于slave离线后的数据存放,缓冲区越大,slave离线时间就可以越长
# 缓冲区只有在有slave连接的时候才会分片内存,没有slave一段时间后内存就会被释放出来,默认是1m
# 默认没有开启
repl-backlog-size 5mb

# master在没有slave多久后会将缓冲区释放,单位为秒
# 默认没有开启
repl-backlog-ttl 3600

# redis提供可以让master停止写入的方式,这里配置的1意思是只有健康的slave<2时master就无法写入
# master最少有多少个健康的slave存活才能写入数据
# 设置为0则关闭该功能,默认也是0
# 默认没有开启
min-replicas-to-write 1
# 延迟小于min-replicas-max-lag秒的slave才认为是健康的slave
# 默认没有开启
min-replicas-max-lag 10

更改完成后重启两个redis实例,再执行以下命令查看是否配置成功:

127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:1
min_slaves_good_slaves:1
slave0:ip=192.168.20.199,port=6379,state=online,offset=40594,lag=1
master_replid:a95f80f29e0a599c48b4164df0c0d0aac2fc47dc
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:40594
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:5242880
repl_backlog_first_byte_offset:40539
repl_backlog_histlen:56

connected_slaves:1表示有一个成功连接的slave节点,然后可以在master节点set值,在slave节点get看是否可以同步。

redis主从复制原理

Redis的主从复制过程大体上分3个阶段:建立连接数据同步命令传播

建立连接

  1. 建立连接,在slave节点配置文件中配置了replicaof的配置后,redis启动的时候就会执行replicaof命令,创建一个与master节点的连接。
  2. 发送心跳,建立连接之后,slave节点会向master节点定时发送ping命令,确认master节点是否可用,如果可用则进行连接,否则重连。
  3. 身份认证,如果master节点设置了requirepass选项,那么slave服务器必须配置masterauth密码与master一致才能通过验证
  4. 身份验证通过后master节点会把slave节点的信息保存下来
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:2
min_slaves_good_slaves:2
slave0:ip=192.168.20.199,port=6379,state=online,offset=40594,lag=1
slave1:ip=192.168.20.200,port=6379,state=online,offset=40594,lag=1

数据同步

身份验证通过后master和slave就开始同步数据了,slave执行PSYNC命令向master同步数据。

同步数据分为:完整重同步(full resynchronization)部分重同步(partial resynchronization)

完整重同步

完整重同步流程大致是这样的:


完整重同步流程图
  • 当slave节点第一次连接到master节点的时候就会执行完整重同步,此时slave节点向master发送的同步命令是psync ? -1,master节点向slave节点返回FULLRESYNC <runid> <offset>,slave节点会把<runid><offset>这两个值保存起来,用来做数据的增量更新
  • 同时master节点会执行bgsave命令,把当前redis里的所有内存数据写到rdb快照文件里。
  • 写完rdb文件后master会把rdb文件同步给全部的slave节点,在发送的同时如果有新的请求命令写入master节点,master会把新的请求命令写入到buffer缓冲区。

要注意的是如果同步rdb文件的时间超过60秒就会同步失败,如果master节点数据较大,需要在master的redis配置文件里修改repl-timeout配置的默认值。

  • slave节点接收到master的rdb文件后就会清除自己的全部数据,然后加载master的rdb文件,加载完毕后master节点就会把buffer缓冲区的数据再同步给slave节点。
  • slave节点接收buffer缓冲区的数据后就会开始执行,并同时更新自己的offset值,以保证始终和master节点数据保持一致。

master节点和slave节点都会维护自己的offset(slave的offset是第一次full resynchronization获取到的),会随着接收到的命令请求递增。slave节点会每秒上报自己的offset给master,master会把所有slave节点的offset保存起来,这样master节点就知道所有slave节点数据同步的情况。当slave节点掉线重新发送psync命令后,master就会根据自己的offset和slave的offset做比较来判断是触发full resynchronization还是partial resynchronization

部分重同步

全部重排序是一个很耗时的操作,当slave节点重新连接到master节点的时候master会尽可能只让slave同步增量的数据,只同步增量的数据就是部分重同步,大概的流程是这样的:


部分重同步流程图
  • 当slave节点断线从新连接到master节点的时候就会执行部分重同步(大部分情况下),slave会发送psync <runid> <offset>给master,master会判断<runid>是否和自己的<runid>一致,以及<offset>值是否可以从缓冲区同步所有断线期间的数据,如果都满足条件就会向slave发送+COUNTINUE命令开始部分重同步,否则就会就会返回FULLRESYNC <runid> <offset>开始完整重同步

runid是master节点重启后随机生成的一个唯一标识,也就是说每次master节点重启都会导致slave节点全部重同步,如果想重启主节点服务而不改变run id,使用redis-cli debug reload命令。
buffer缓冲区是一个固定长度的队列,默认是1M,如果缓冲区写满了redis就会用新命令覆盖旧的命令,这会导致slave断线时间较长就没办法同步掉线期间全部数据而触发full resynchronization,可以更改redis的配置repl-backlog-size的大小来允许slave可以断线更长的时间

  • 接下来就和上面讲的全部重同步一样,接收master缓冲区的数据,接收master的新命令,维护自己的<offset>
命令传播

当完成数据同步之后,master和slave节点的数据暂时达到一致状态,为了持续能够使master和slave节点的数据保持一致性,master会对slave节点执行命令传播操作,即每执行一个写命令就会向slave节点发送同样的写命令。
在命令传播阶段,slave节点会默认以每秒一次的频率向master服务器发送心跳检测

REPLCONF ACK <replication_offset>

replication_offset是当前从服务器的复制偏移量,该命令的作用有三个

  • 检测主slave服务器的网络连接状态
  • 辅助实现min-slaves选项
  • 检测命令丢失
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,542评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,596评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,021评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,682评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,792评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,985评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,107评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,845评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,299评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,612评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,747评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,441评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,072评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,828评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,069评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,545评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,658评论 2 350