由于*问题,slave更改为了replica
Redis默认采用异步复制的持久化方案(RDB),具备低延迟、高性能的特点。这是大多数Redis的自然复制模式。
主从复制(master-replica)-读写分离这是基于RDB持久化方案的全量数据复制模式。
1.主从复制-读写分离介绍
为了解决高并发场景下Redis的性能问题,需要对单例Redis进行横向扩展;我们都知道在缓存中读的并发量要远远大于写的并发量。所以就产生了一种读写分离的方法:
将读和写分开,master节点可以进行读写操作,而slave节点只能进行读操作(conf文件可以修改),因此读写分离是一种基于RDB持久化方案的主从架构。
2.读写分离核心流程
首先需要从slave节点初始化进行分析,因为slave节点只能进行读操作,所以它如何拥有初始数据是第一步。
- 当salve节点初始化时会首先ping向master节点,如果ping通,salve就会把master上的rdb文件复制到slave节点,然后加载到内存中。
- 后续当master节点有写操作时,master会将相同操作命令传输给salve节点,然后salve进行执行即可。
3.三种工作机制
- 当master和slave链接良好时,master向slave发送命令流来完成salve更新;
- 当master和salve链接中断时,由于网络原因或master和salve检测超;salve将尝试重新连接并尝试进行部分重新同步,这意味着同步的是断开连接那段时间的命令流
- 当无法进行部分重新同步时,salve将进行全部重新同步。这涉及了一个更复杂的过程,需要master创建所有的快照并发给salve。
4.主副本之间如何进行协商的?
试想master每向Redis副本发送一次命令流,是否需要等待副本处理完成?(因为副本可能由于某种原因没有处理完这个命令流)
答:这是不需要的,副本会定期确认与master接收的数据量。所以master知道副本已经处理了哪个命令,这具有可选的同步复制。
5.Redis复制的特点
Ⅰ.Redis复制在主控端是非阻塞的(异步复制),意味着当一个或多个副本进行同步数据时,master仍然可以进行数据查询。
Ⅱ.Redis复制在副本也是非阻塞的(异步复制),在副本执行同步时,仍然可以被查询。但当副本进行初始化时,需要删除本身的旧数据集加载新数据集,这短暂的期间是不能被客户端连接的。在Redis4.0以后,允许在conf进行配置删除旧数据集发生在不同的线程中,但是加载新数据集仍发生在主线程中,所以这个时间段仍是阻塞的。
Ⅲ.一个master可以连接多个副本,一个副本也可以连接多个副本,类似于级联结构。
Ⅳ.避免了master将整个数据写入磁盘的成本。
6.Redis复制的工作原理
每个Redis实例都有Replication ID,每个主机也存在一个偏移量,该偏移量随着主机向副本发送命令流的字节而增加。
当副本要连接主机时,会通过PSYNC命令发送它的旧主机Replication ID和Offset。这样主机只需要向副本发送增量部分。
发送Offset(偏移量)我们应该都明白它是为了定位缓冲区发送的起始位置,向副本发送它缺少的那部分数据。那Replication ID有什么用呢?
其实这是为了让主机将自身的Replication ID与副本发送的Replication ID做对比,判断是否相同,如果相同则可以进行增量复制。如果不相同,所以主机已经被更换,需要进行全量复制。
完全同步的工作流程:
主机生成RDB文件,在这个同时缓冲从客户端接收到的新的写命令;主机向副本发送RDB文件,副本将其保存在磁盘并加载到内存中;最后主机将所有缓冲的命令发送给副本。
总结:
Redis在进行全量同步时,master会将内存数据通过bgsave落地rdb文件;同时将接收到的客户端写指令存放到复制缓冲区中。当rdb快照构建完毕之后,master会将rdb和复制缓冲队列中的数据全部发送给replica(副本),可以看出全量同步对系统的性能和资源访问造成影响。
在Redis2.8之前,Redis只支持全量复制;2.8之后引入了PSYNC,增加了一个复制积压缓冲,master在将写指令发送给replica之后,也会在复制积压缓冲存放一份。当由于网络波动导致master与replica连接断开并重新连接时,replica会向master发送replid(复制id)和偏移量,如果master的replid和副本发送的replid相同并且偏移量仍在复制积压缓冲,则master使用增量复制。
Redis4.0之后,引入了PSYNC2,这是对PSYNC的优化,额外加入了一个replid2。每个Redis实例启动之后都会被分配一个长度为40的随机字符串最为replid的初始值,当replica连接master之后,会将master的replid替换自己的replid;replid2会存储上次主机的replid,这样一来如果master发送变动,则master的replid与replica的replid或者replid2相同,仍然可以使用增量复制。
7. 主从复制-读写分离实战
模拟三台Redis服务器,一台6379为主机,另外的6380和6381为副本。
1.首先在Linux服务器下载安装Redis服务
下载安装包:wget https://download.redis.io/releases/redis-6.2.6.tar.gz
解压:tar -zxvf redis-6.2.6.tar.gz
编译:make
安装:make PREFIX=/path install (path为安装路径)
安装之后会发现只有一个bin目录。
2.建立相应的文件保存数据、日志、配置文件
mkdir -p /opt/redis/data
mkdir -p /opt/redis/conf
mkdir -p /opt/redis/
touch redis-6379.conf
touch redis-6380.conf
touch redis-6381.conf
3.将redis解压目录下的redis.conf文件复制一份到/opt/redis/conf
复制:cp redis.conf /opt/redis/conf
重命名:mv redis.conf redis-common.conf
4.修改redis-common.conf配置文件
点击ESC->输入:/搜索词 ,即可进行搜索,键盘点击n表示寻找下一个
(1)修改protected-mode的值为no
(2)修改daemonize的值为yes:表示后台启动redis
(3)注释掉bind(注释掉表示所有的都可以访问)
(4)注释掉port
(5)注释掉logfile
(6)注释掉dbfilename
(7)修改目录
(8)打开masterauth(从服务器访问主服务器所需要的密码)
(9)注释掉pidfile
5.编辑redis-6379.conf、redis-6380.conf、redis-6381.conf
最后一个slaveof表示主机地址,这里的6379为主机,所以不需要配置。
6.启动
./redis-server /opt/redis/conf/redis-6379.conf
./redis-server /opt/redis/conf/redis-6380.conf
./redis-server /opt/redis/conf/redis-6381.conf
使用ps -ef|grep redis进行查看进程
7.测试
复制三个窗口,连接三个客户端,输入info replication查看信息。