一)搭建主从架构:
单节点Redis的并发能力是有限的,所以说要想进一步提高Redis的并发能力,就需要搭建主从集群,实现读写分离,因为对于Redis来说大部分都是读多写少的场景,更多的要进行读的压力,最基本都要是三台机器,一主两从;
计划是在一个linux服务器上面开启3个Redis实例来进行模拟主从集群
在真实的开发环境中,可以是IP地址不相同,但是端口号可以相同
一)要在同一台linux服务器开启个实例,必须要准备三份不同的配置文件和目录,配置文件所在的目录就是工作目录,下面我们就在tmp目录下面的temp目录下面创建了三个目录
7001 7002 7003
二)关闭AOF持久化方式,启用RDB持久化方式
三)拷贝redis.conf配置文件到每一个实例目录
四)修改每一个实例的端口和工作目录
修改每一个文件夹下面的配置文件,将端口号修改成7001 7002 7003,将RDB文件保存位置都修改为自己的文件所在的目录
五)打开三个窗口,分别启动redis
六)搭建主从节点,在两个从结点之间执行命令slaveof IP地址 端口号
info replication来去检查主节点的连接信息
Redis主从第一次同步是全量同步,会将内存生成快照,整体发送给salve,下面来解析一下全量同步的过程
1)从节点要执行一个replicaof命令,建立连接,并且指定master的IP地址和端口号,一旦建立成功slave就可以向master发送请求了,来进行请求数据同步;
2)主节点会进行判断你是否是第一次来,如果你是第一次来,那么主节点会把所有的数据返回给从节点,如果你不是第一次来,那么只是会返回部分的数据,你缺多少,我给你多少
3)如果是第一次来,那么主节点会向从节点发送自己的版本信息,然后从节点会将这个版本的信息记录;
4)如果主节点判断是全量同步,那么主节点的主线程会执行bgsave命令,生成一个子进程来生成一个RDB文件,这样对于主进程没有什么影响,主进程继续去处理用户请求;
5)RDB文件里面记录了完整的内存信息,然后主进程会发送这个RDB信息发送给我们的从节点,从节点拿到这个RDB文件就是相当于是拿到了主节点的全部数据了,然后从节点会把本地的RDB文件进行清空,然后会进行加载发送过来的RDB文件,这样master和slave节点基本一致;
6)因为在bgsave异步执行的过程中,那么主进程还是会进行处理用户的请求的,那么会有新的数据写入到主节点的内存中,但是这些新的数据并没有发送给主节点,所以master的主进程除了要进行处理新的数据之外,主进程还会把这些命令记录到repl_backlog这样的内存缓冲区中,repl_backlog这样的缓冲区会进行记录在bgsave期间收到的新的命令,只要未来从节点成功收到了bgsave的RDB文件再来执行repl_backlog中的所有命令,就是master节点的完整数据;
7)主节点会将repl_backlog中的所有的命令发送给从节点,从节点去执行接收到的命令,从而保证master和slave节点中的数据是完全一致的,后续再来有独立进程将这些repl_backlog中的命令发送给slave节点
8)全量同步速度比较慢,只有在第一次建立连接才去做;
由此可知master是如何来进行判断slave是不是第一次来进行同步数据呢?
1)Replication ID:简称为是replid,是数据集的标记,ID相同则说明是同一数据集,每一个master都具有唯一的ID,后续的salve会进行继承master节点的repliID
2)offset:也被称之为是偏移量,随着记录在repl_backlog中的数据增多而逐渐增大,slave在完成同步的时候也会进行记录当前同步的offset,如果slave的offset小于master节点的offset,说明slave数据落后于master,需要进行数据的更新,slave中的offset是永远小于master中的offset的,因为从节点的offset是从主节点中拷贝过来的,如果主节点的offset值等于从节点的offset值,说明主从数据一致
3)因此slave在做数据同步的时候,必须向master声明自己的replication ID和offset(判断进度),master才可以进行判断自己到底要同步哪些数据;
master是如何来进行判断slave节点是不是第一次来做同步的?
1)直接判断offset是否为0即可;
2)难道说主要offset大于0就一定是第一次做同步吗?就一定不是第一次来吗?假设你的offset很大,但是此时发送过来的主节点的Replication ID和主节点ReplicationID不相同,你是从其他的master节点拷贝过来的,所以此时的offset是无意义的;
3)总结:因为每一个节点都存在着唯一的Replication ID,所以判断从节点是否是第一次来进行更新数据的依据是,如果主节点的Replication ID和从节点的Replication ID相同,那么说明不是第一次,如果Replication ID不相同,则说明是第一次;
全量同步的流程:
1)从节点向主节点请求增量同步
2)master节点会进行判断从节点的Replication ID是否和主节点自己的Replication ID是否一致,如果不同,说明要进行全量同步,拒绝增量同步;
3)master的主进程会开启一个分进程将完整的内存数据生成RDB文件,然后将这个RDB文件发送给slave节点
4)接下来从节点会清空本地数据,会进行加载master中的RDB文件;
5)主节点的主进程会将RDB期间的命令记录在repl_backlog,并会开启一个新的进程将log中的命令发送给slave;
6)slave会不断的执行log中的命令;
主从第一次同步是全量同步,但是如果slave重启之后进行同步,那么一定是执行增量同步,那么在slave再重启的这一段时间,主节点是一定会进行执行用户输入的命令的
1)从节点会向主节点发送Replication ID和offset,主节点判断过了Replication ID和从节点的ReplicationID是相同的,那么主节点会直接向从节点返回一个continue;
2)那么此时主节点想从节点发送数据的时候,就不用写RDB文件了,只不过是从节点在重启的时候丢失了一部分数据,这部分数据就在主节点的repl_backlog里面;
3)既然从节点向主节点发送了一个offset数据,那么主节点只需要定位到repl_backlog中的offset为止(从节点发送过来的offset值)再继续向后读取就可以了,也就是hirepl_backlog中去除掉offset之后的数据,此时从节点只需要执行这些命令就可以把剩下的数据给补上了;