单节点Redis的并发能力是有上限的,要进一步提高Redis的并发能力,就需要搭建主从集群,实现读写分离。
这里就在一台虚拟机上开启3个Redis实例模拟主从集群
1.先创建三个目录以给的端口号命名:7001,7002,7003。
2.将配置文件拷贝到三个目录中。
cp redis-6.2.4/redis.conf ./7001/redis.conf
3.修改每个实例的端口,工作目录。
修改每个文件夹内的配置文件,将端口分别修改为7001、7002、7003,将rdb文件保存位置都修改为自己所在目录(绝对路径即可)
4.修改每个实例的声明IP
虚拟机本身有多个IP,为了避免将来混乱,我们需要在redis.conf文件中指定每一个实例的绑定ip信息,格式如下:
replica-announce-ip ip地址 端口号
vim中中如何查找某个字符串?
解决:
在底行模式下输入/要查找的字符串+回车,可以按n或N查找其他位置。如果未找到,底行会显示E468:Pattern not found: pattern
5.启动
redis-server ../7001/redis.conf:像这样启动这三个实例
6.开启主从关系
现在三个实例还没有任何关系,要配置主从可以使用replicaof 或者slaveof(5.0以前)命令。
有临时和永久两种模式:
1.修改配置文件(永久生效)
在redis.conf中添加一行配置:
slaveof
有密码的时候还要配置:masterauth 密码
2.使用redis-cli客户端连接到redis服务,执行slaveof命令(重启后失效):
slaveof
注意:在5.0以后新增命令replicaof,与salveof效果一致。
连接主redis:redis-cli -p 7001
6.1:查看集群状态
info replication
结果:
注意:防火墙一定要关闭或开放端口。
7.测试:
在主节点设置值在子节点可以取到值,但无法在子节点设置值。
主从第一次同步是全量同步
第一阶段:
1.首先从节点向主节点建立连接,发起数据同步的请求。
2.主节点判断从节点是否是第一次连接。
3.发现是第一次来先发送给从节点自己的数据版本信息,从节点保存这个版本信息。
第二阶段:要将数据全部发送给从节点。
1.主节点执行bgsave:生成RDB,生成完后发送RDB文件给从节点。
2.从节点拿到数据后清空本地数据,加载RDB文件。
3.由于bgsave是异步执行的,所以还未能完全同步,主节点在记录RDB期间会将所有得到的新的命令保存到repl_baklog(内存缓冲区中)
第三阶段:
1.主节点发送内存缓冲区中的命令,子节点只需要再执行这些收到的命令就可以与主节点的数据完全一致。
master如何判断slave是不是第一次来同步数据
解决:
1.Replication id:简称replid,是数据集的标记,id一致说明是同一数据集。每一个master都有唯一地replid,slave则会继承master节点的replid.
2.offset:偏移量,随着记录在repl_baklog中的数据增多而逐渐增大。slave完成同步时也会记录当前同步的offset.如果slave的offset小于master的offset,说明slave数据落后于master,需要更新。
因此:slave做数据同步,必须向master声明自己的replication id 和offset,master才可以判断到底需要同步哪些数据。
主节点同步
从节点同步
总结:
全量同步的流程:
slave节点请求增量同步
master节点判断replid,发现不一致,拒绝增量同步
master将完整内存数据生成RDB,发送RDB到slave
slave清空本地数据,加载master的RDB
master将RDB期间的命令记录到repl_baklog,并持续将log中的命令发送给slave
slave执行接收到的命令,保存与master之间的同步
主从同步第一次是全量同步,但如果slave重启后同步,则执行增量同步。
repl_baklog本质是一个数组,这个数组比较特殊,大小是固定的,当这个数组的数据记满后,会从0在开始记,会把原来的数据给覆盖了。
注意:只要子节点和主节点的差距不要超过这个环的存储上限,子节点永远可以实现和主节点的增量同步。但是如果差距太大,超过了这个环的存储上限就没法做增量同步了。
可以的情况:
不可以的情况:
注意:此时,子节点的offset消失了。当子节点还想同步时只能去master内存中找了,只能做全量同步。
总结:repl_baklog大小有上限,写满后会覆盖最早的数据。如果slave断开时间过久,导致尚未备份的数据被覆盖,则无法基于log做增量同步,只能再次全量同步。
1.适当提高repl_baklog的大小,发现slave宕机时尽快实现故障恢复,尽可能避免全量同步。
1.在master中配置repl-diskless-sync yes :启用无磁盘复制,避免全量同步时的磁盘IO.
(正常复制需要生成RDB文件,先在磁盘写文件,然后通过网络发送给子节点。磁盘读写比较慢导致全量同步效率比较低。)当要写RDB时不再写磁盘IO流,而是直接写在网络中直接发给子节点,减少了一次读写,性能提高。(适合磁盘慢,网络快的时候,如果网络不快,可能导致阻塞。)
2.Redis单节点上的内存占用不要太大,减少RDB导致的过多磁盘IO
1.限制一个master上从节点数量,如果实在是太多slave,则可以采用主->从->从链式结构,减少master压力。
全量同步:
master将完整内存数据生成RDB,发送RDB到slave,后续命令则记录在repl_baklog,逐个发送给slave。
增量同步:
slave提交自己的offset到master,master获取repl_baklog中从offset之后的命令给slave。
执行全量同步的时机:
slave节点第一次连接master节点时。
slave节点断开时间太久,repl_baklog中的offset已经被覆盖时。
执行增量同步的时机:
slave节点断开又恢复,并且在repl_baklog中能找到offset时。