开发者学堂课程【Redis 入门实战演练: Redis 主从同步及实现(三)】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/653/detail/10839
Redis 主从同步及实现(三)
四、主从同步优化:
Redis 在2.8版本之前没有提供增量部分复制的功能,当网络闪断或者 slave Redis 重启之后会导致主从之间的全量同步,即从2.8版本开始增加了部分复制的功能。推荐就使用2.8以上的版本,尤其是3.0以上的,不推荐2.8的原因是由于没有 redis cluster 的功能。这个优化在前面讲到过一些,尤其是配置文件参数的时候。
reply-diskless-sync no
#是否使用无盘同步 RDB 文件,默认为 no,no 为不使用无盘,就需要使用磁盘,需要将 RDB 文件保存到磁盘后再发送给 slave,yes 为支持无盘,支持无盘就是 RDB 文件不需要保存至本地磁盘,而且直接通过 socket 文件发送给 slave。这些在磁盘还很快的情况下,就改为 no;若磁盘很慢,就改为 yes,不使用磁盘,因为磁盘本来就慢,用磁盘就会更慢。
repl-diskless-sync-delay 5
#Master 准备好 RDB 文件后等等待传输时间。这个时间如果有多个 slave,在等待时间之内再用 slave 连接起来,可以用 RDB 文件进行复用,就可以复用同一个 RDB 文件,就不用 master 在同步另一个 slave 时进行 RDB 文件的 down。这个延迟时间好处是可以尽可能的延迟 down 文件,坏处是如果时间越长,会导致主从同步的时间越来越长,延迟多少秒就是多少秒之后延迟同步。
reply-ping-slave-period 10
#slave 端向 server 端发送 ping 的时间区间设置,默认为10秒
reply-timeout 60
#设置超时时间,上面这两个一般保持默认即可
repl-disable-tep-nodelay no
#是否启用 TCP_NODELAY,如设置成 yes,则 redis 会合并小的 TCP 包从而节省带宽,但会增加同步延迟(40ms),造成 master 与 slave 数据不一致,假如设置成 no,则 redis master 会立即发送同步数据,没有延迟,前者关注性能,后者关注 redis 服务中的数据一致性。
reply-backlog-size1mb
#master 的写入数据缓冲区(是独立于内存大小的,这个值可以设置的更大一些。),用于记录自上一次同步后到下一次同步过程中间的写入命令,计算公式:reply-backlog-size=允许从节点最大中断时长*“主实例officet每秒写入量
,比如master每秒最大写入64mb,最大允许60秒,那么就要设置为64mb*60秒=3840MB(3.8G)。
reply-backlog-ttl3600
#如果一段时间后没有 slave 连接到 master,则 backlog size 的内存将会被释放。如果值为0则表示永远不释放这部份内存。
slave-priority 100
#Slave 端的优先级设置,值是一个整数,数字越小表示优先级越高,当 master 故障时将会按照优先级来选择slave端进行恢复,如果值设置为0,则表示该 slave 永远不会被选择。
#min-slaves-to-write 1
#设置一个 master 端的可用 slave 少于多少个
emin-slaves-max-lag 20
#设置所有 slave 延迟时间都大于多少秒时,master 不接收写操作(拒绝写入)。
上图是之前讲到过一个结构,是7.103这个 slave 可以挂到7.102的后面,所以说这个地方还是一个 slave,就类似于 MySQ L中还有一个 mysql。
实践:先连接到7.103 上去,一个是从服务器、一个是 slave 切换到 master,把它切换到102上去。103接上后,加入语句,mkdir /apps/ 根下的压缩包拷入到172.31.7.103,语句为scp redistaz,gz 172.31.7.103:/apps/
,结果如下:
再加入语句 data 观察时间是否正确,加入语句
useradd redis -s /sbin/nologin,
并把101的文件拷入到172.31.7.103上语句为:
scp /usr/lib/system/system/redis.service 172.31.7.103:/usr/lib/system/system/redis.service
然后把103的 master 指向102,并切换一下 master,拷过去后把目录权限设置修改一下,把根下的 redis 全部改成 redis 的用户语句为:chown redis.redis /apps/ -R
,之后再重启语句是systenctl restart redis
,此时 redis 就装好了,做一个打命令软件,语句为ln -sv /apps/redis/bin/redis-* /usr/bin/
,在执行命令 redis -cli、AUTH linux39
这里用配置文件来修改,进入文件把里面的参数一次性修改好,语句为vim /apps/redis/etc/redis.conf
。再一个 REPLICATION 的配置段中完成,找到 slaveof 的行修改为指向172.31.7.102的结点,再把密码修改为 linux39,如下图
改好后用语句 systemctl restart redis
重启,进入103的命令行,语句为 redis-cli、AUTH linux39、info
,查看当前的 master 是172.31.7.102、角色是 slave、状态时 up。master 上写一个数据,看数据是否可以同步到103上去,语句为 redis-cli、AUTH linux39 、KEYS*、SET keys8 value8
,,如下图:
先到102上去验证输入语句KEYS *、GET key8
可以看到存在,103的 master 是102,没有存在102上。
在103上查看是否有这个 key,语句是KEYS* 、get key8
102上的角色是 slave,它的 master 是101,他就是 slave,102是向101 同步数据的,他先是 slave 后是 master。或者说一旦配置成了 slave,即使后面还给别的结点同步数据,它还是 salve。这个内容中有一个 slave0,可以看到是连接到7.103上同步数据,注意这个状态 state 是 online 才是正确的,看 offset 的位置,102的 offset 是到101上同步数据它的位置是3621。而103 的 offset 同步数据的位置也是3621,所以说103 的数据和102是一样的,101的数据和102一样就是基于这个 offset 位置来控制
此时在配置103,使得103能够配置一个 master 是绕过102,直接指向103上的,这个就是更换master的方式,让1033直接指向101,不再向102上同步数据。第一步是要执行一个 SLAVEOF no one
就是当前的结点不属于任何一个结点的 slave,先右击选中停止。SLAVEOF no one
就认为是等于 MySQL 中的stop slave+slave reset
。如何将从服务器提升为主服务器?一个是停止 slave 的工作,第二个就是重设一下 slave 的主从同步关系,这样可以将 MySQL 变成主服务器。所以这时候就会成为 master
如果想改为7.101上,这就和以前的方法是一样的,注意这个 id 之前是因为 master 是7.102,在提升为 master 之后,这个id改变。此时的 id 是当前的7.103的 id,id2就是7.102的 id,102上的 id 就是之前的,103上的 id 如果停止 slave,那么就会变为自己的
或者把它的 master 指向101,推荐后期修改配置文件的时候不要那命令行修改,很有可能会忘。执行语句vim /apps/redis/etc/redis.conf
,进入以下界面:把 slaveof 的地址修改为172.31.7.101
之后在重启后再次进入命令行中查看,语句是systemctl restart redis、redis-cli、AUTH linux39、info
,运行结果如下:这时的 id 就直接指向101了
这就是讲解的时一主一从并且从后跟从以及一主多从的配置、还有如何把一个结点提升为 master,使其具备写的功能,也可以理解为当主的过来之后是要手动切换 master 的状态的。
如何测试把 master 提升为主?把 master 的 down 之后,slave 是可以识别 master 的 down,就是在他的 state 显示的时 down。
如果此时再写入一个数据,只要角色时 rule 就不可以书写。所以在这种情况下怎样书写使其变为 master 并具备相应的书写能力,进入之前输入语句KEYS*
查看数据,当输入SLAVEOF no one
之后,要把当前结点的 master 全部取消使其不属于任何一个 master,把它提升为 master,之后它的数据是不会消失的,并且都在就可以往里面写入数据,能写入数据就可以查看了,执行语句get key10
这就是这个结构的演变,早期时一主一从还会涉及到从的里面还有从、或者怎样切换 master、怎样提升 slave 为 master 从而具备写数据的能力,这个结构很少使用是由于不具备故障转移的功能,就是不能解决 master 宕机的问题,后面会通过其他方式来解决,后期是不需要手动到 slaveof on one 上切换,需要用一种自动切换的机制
常见问题汇总
(1) master 密码不对
配置的 master 密码不对,导致验证不通过而无法建立主从同步关系
(2) redis 版本不一致,不同的 redis 版本之间存在兼容性问题,因此各种 master 和 slave 之间必须保持版本一致,会导致不能识别对应得文件就会导致失败,不能够从磁盘导入到数据,这也会造成无法同步,会使得 master 上写的数据 slave 上看不见
(3) 无法远程连接
开启安全模式情况下,没有设置宾得地址或者密码,这个主要是配置监听地址和监听密码
版本不一致得演示,假如现在有一个104,在104上使用3.2版本的端,而现在使用的其他的都是4.0版本的,到目前的演示位置,102是slave不具备写的功能需要手动执行 slaveof no one才能提升 为 master;在104端上输入语句yum install redis
、再输入yum install epel-release
,之后在安装上 redis,语句是 yum install redis
。安装后输入语句systemctl start^C
,再查看配置文件vim /etc/redis/redis.conf
,回车后把监听地址改为 bind 0.0.0.0,其他保持不变 继续输入语句 systemctl restart reset^C
,刚刚的版本是3.12的,但编译的版本是4.0.14,所以这里执行SALVEOF 172.31.7.101 6379
,再config set masterauth linux39
再执行 KEYS *,运行后发现是没有看到的,所以输入语句tail -f /var/log/redis/redis.log
,此时会连接失败
继续添加语句 ping 172.31.7.101
,修改配置文件vim /etc/redis.conf
。在新的页面中搜索 REPLICATION,依旧选择用配置文件指过去,文件密码是 linux39,master 的地址是172.31.7.101,端口是6379,
把 redis 重启语句为systemctl restart redis
再打开日志会发现连 service 都建立不起来
进入到104上输入语句redis -cli 、info
进入详情,状态是 down,master 结点是172.31.7.101,这种导致同步报警日志都无法查看
而下图中所涉及的例子是可以再同步日志中报出版本不一致的错误,说这个 RDB 文件是不具有兼容的能力
如果把 master 结点换成102,重复上述步骤,改为 salveof 172.31.7.102
,在经过重启、打开日志的方式查看,依旧不能够同步,所以在执行时最好使用相同版本的 redis,否则会导致版本不一致导致的错误,看下图中的同步过程,前面的连接、开始同步、发动放到264个字节的数据、清空文件、导入数据到内存,最后到导入数据这个一步发生了失败,所以说版本不一致是无法建立主从同步的,结果就会导致在 master 上面看不见数据,slave 上就是没有这个数据的。
刚刚是把101的关闭掉了,现在重复刚刚的操作改为salveof 172.31.7.101
,在经过重启、打开日志的方式查看,依旧不能够同步数据的,可以选择把其中一个的版本降低或是提高,从而保持版本的一致性。