您的位置:首页 > 数据库 > Redis

redis的主从架构简述

2018-01-31 17:43 302 查看
利用redis的replication功能实现主从架构,一主多从,主节点负责写请求,同步复制到从节点,从节点负责读请求,所有的读请求均匀的打在从节点上,而且到QPS再增加的时候,只要水平的增加从节点的数量即可。
所以整个的思路是:redis replication --> 主从架构 --> 读写分离 --> 水平扩容
redis采用异步方式复制数据到slave节点,slave node 在做复制的时候是不会阻塞master node的正常工作,也不会阻塞对自己的查询工作,但是当复制完成需要删除旧数据的时候,加载新数据集的时候,会暂停对外服务
如果采用了主从架构,那么也建议必须开启master node的持久化
1 主从架构的核心原理
当启动一个slave node的时候,它会发送一个PSYNC命令给master node
如果这是slave node重新连接master node,那么master node 仅仅会复制给slave部分缺少的数据,否则如果是slave node第一次连接master node,那么会触发一次full resynchronization
那么当开始full resynchronization的时候,master启动一个后台线程,生成一份RDB快照文件,并发送给slave,slave会先把该文件写入本地磁盘,然后再从本地磁盘加载到内存中。
同时master也会将内存中缓存的写命令发送给slave,slave也会同步这些数据。
slave node如果跟master node有网络故障,断开了连接,会自动重连。
master node 如果发现有多个slave node连接,仅仅会启动一个rdb slave操作,用一份数据服务所有slave node
2 主从复制的断点续传
如果主从复制过程中,网络连接断掉了,那么可以接着上次复制的地方,继续复制下去,而不是从头开始复制一份。
master node和slave node都会保存一个replica offse和master id,offset就是保存在backlog中,如果master 和 slave网络连接断掉了,slave会让master从上次的replice offset开始继续复制
但是如果没有找到对应的offset,那么就会执行一次resynchronization。
3 无磁盘化复制
master在内存中直接创建rdb,然后发送给slave,不会在本地磁盘落地。
repl-diskless-sync
repl-diskless-sync-delay 等待一定时长后再开始复制,因为要等更多的slave重新连接过来
4 过期key处理
slave不会过期key,只会等待master过期key,如果master过期了一个key,或者通过LRU淘汰了一个key,那么会模拟一条del命令发送给slave
完整的复制流程
(1)slave node启动,仅仅保存master node的信息,包括master node的host和ip,但是复制流程没有开始,master node 的host和ip是从redis.conf里的slaveof配置的
(2)slave node内部有个定时任务,每秒检查是否有新的master node要连接和复制,如果发现,就跟master node建立socket连接
(3)slave 发送ping命令给master node,如果master 设置了requirepass,那么slave node必须发送masterauth的口令过去进行认证
(4)master node第一次执行全量复制,将所有数据发送给slave node
(5)master node后续持续将写命令,异步复制给slave node

2 数据同步相关的核心机制

(1)master 和 slave 都会维护一个offset
master会在自身不断累加offsetslave也会在自身不断累加offset
slave每秒都会上报自己的offset给master,同时master也会保存每个slave的offset,就能知道互相之间的数据不一致的情况
(2)backlog
master node有一个backlog,默认1M大小
master node给slave node复制数据的时候,也会将数据在backlog中同步写一份
backlog主要是用来做全量复制中断时的增量复制的

(3)master run_id
info server 可以看到master 的run_id
如果根据host + ip定位master node是不靠谱的,如果master node 重启或者数据出现了变化,run id就发生变化了,那么slave node应该根据不同的run id区分,run id不同就做全量复制
如果需要不更改run id重启redis,可以会用redis-cli debug reload命令
(4)psync
从节点使用psync从master node进行复制,psync runid offset
master node会根据自身的情况返回响应信息,可能是FULLLRESYNC runid offset触发全量复制,可能是CONTINUE触发增量复制
如果发现run id变化了就触发全量复制,如果run id没有变化就根据offset进行增量复制

3 全量复制

(1)master 执行bgsave在本地生成一份rdb快照文件
(2)master node将rdb快照文件发送给slave node,如果rdb复制时间超过60秒(repl-timeout),那么slave node就会认为复制失败,可以适当调大这个参数
(3)对于千兆网卡的机器,一般每秒传输100M,6G文件,很可能超过60s
(4)master node在生成rdb时,会将所有新的写命令缓存在内存中,在slave node保存了rdb之后,在将新的写命令复制给slave node
(5)client-output-buffer-limit slave 256M 64M 60 ,如果在复制期间,内存缓冲区持续消耗超过64M,或者一次性超过256M,那么停止复制,复制失败
(6)slave node接收到rdb之后,清空自己的旧数据,然后重新加载rdb到自己的内存中,同时基于就的数据版本对外提供服务
(7)如果slave node开启了AOF,那么会立即执行BGREWRITEAOF,重写AOF
rdb生成,rdb通过网络拷贝,slave旧数据清理,slave aof rewrite很耗费时间,如果复制的数据量在4G到6G之间,那么很可能全量复制时间消耗1分半到2分钟

4 增量复制
(1)如果全量复制过程中,master-slave网络连接断掉了,那么slave重新连接master时,会触发增量复制
(2)master直接从自己的backlog中获取部分丢失数据,发送给slave node,默认backlog就是1M
(3)master就是根据slave发送的psync中的offset来从
backlog中获取数据的

5 heartbeat
主从节点互相都会发送heartbeat信息
master默认每隔10秒发送一次heartbeat,slave node每隔1秒发送一个heartbeat
6 异步复制
master每次接受到写命令后,现在内部写入数据,然后异步发送给slave node

主从节点读写分离的配置:
1 在从节点上要配置slaveof masterip masterport
同时在从节点上开启强制读,只接受读的请求, slave-read-only 默认是开启的

2 开启集群安全认证
master上开启 requirepass
slave上开启 masterauth 登陆的时候要 -a 指定一个口令,否则不能set 要不就是说在登陆后 执行auth + 口令 才可执行set
3 bind 改成绑定自己的ip地址
例如主节点改成自己的ip地址 bind 192.168.124.11 登陆的时候必须 -h 指定一个自己的ip以确定是从节点还是主节点

当出现(error) NOAUTH Authentication required.
可以打入 auth redis-pass
或者是启动的时候 redis-cli -a redis-pass
当关闭redis服务时 redis-cli -a redis-pass SHUTDOWN

redis的自带的压测工具

redis自己提供的redis-benchmark压测工具,是最快捷最方便的,当然啦,这个工具比较简单,用一些简单的操作和场景去压测

1、对redis读写分离架构进行压测,单实例写QPS+单实例读QPS

redis-3.2.8/src

./redis-benchmark -h 192.168.31.187

-c <clients> Number of parallel connections (default 50)
-n <requests> Total number of requests (default 100000)
-d <size> Data size of SET/GET value in bytes (default 2)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: