https://www.bilibili.com/video/BV1cr4y1671t?p=101
https://blog.csdn.net/weixin_54232666/article/details/128825763
单节点Redis的并发能力是有上限的,要进一步提高Redist的并发能力,就需要搭建主从集群,实现读写分离。
主从搭建
这里使用一台虚拟机,开启3个redis实例。
准备三份不同的配置文件和目录,配置文件所在目录也就是工作目录。
创建三个文件夹,名字分别叫7001、7002、7003
java
cd /tmp && mkdir 7001 7002 7003
复制配置文件
java
# 方式一:逐个拷贝
cp /usr/local/src/redis-6.2.6/redis.conf 7001
cp /usr/local/src/redis-6.2.6/redis.conf 7002
cp /usr/local/src/redis-6.2.6/redis.conf 7003
# 方式二:管道组合命令,一键拷贝
echo 7001 7002 7003 | xargs -t -n 1 cp /usr/local/src/redis-6.2.6/redis.conf
修改每个文件夹内的配置文件,将端口分别修改为7001、7002、7003,将rdb文件保存位置都修改为自己所在目录(在/tmp目录执行下列命令)
java
sed -i -e 's/6379/7001/g' -e 's/dir .\//dir \/tmp\/7001\//g' 7001/redis.conf
sed -i -e 's/6379/7002/g' -e 's/dir .\//dir \/tmp\/7002\//g' 7002/redis.conf
sed -i -e 's/6379/7003/g' -e 's/dir .\//dir \/tmp\/7003\//g' 7003/redis.conf
3个ssh窗口,分别启动3个redis实例 (finalshell没找到如何开多窗口)
java
# 第1个
redis-server 7001/redis.conf
# 第2个
redis-server 7002/redis.conf
# 第3个
redis-server 7003/redis.conf
现在三个实例还没有任何关系,要配置主从可以使用replicaof 或者slaveof(5.0以前)命令。
有临时和永久两种模式:
-
修改配置文件(永久生效)
在redis.conf中添加一行配置:
slaveof <masterip> <masterport>
-
使用redis-cli客户端连接到redis服务,执行slaveof命令(重启后失效):
slaveof <masterip> <masterport>
slave机与master建立关系
java
# 连接 7002
redis-cli -p 7002 -a 1325
# 执行slaveof
slaveof 192.168.6.129 7001
# 连接 7003
redis-cli -p 7003 -a 1325
# 执行slaveof
slaveof 192.168.6.129 7001
然后连接 7001节点,查看集群状态
java
# 连接 7001
redis-cli -p 7001 -a 1325
# 查看状态
info replication
发现竟然没有从结点,但是从节点那边都显示已经连接上了
可能是因为虚拟机实例的ip问题
虚拟机本身有多个lP,为了避免将来混乱,我们需要在rdis.conf文件中指定每一个实例的绑定ip信息,格式如下:
java
#redis实例的声明IP
replica-announce-ip 192.168.6.129
一键修改,/tmp目录下运行
java
# 在配置文件第一行追加 replica-announce-ip 192.168.6.129
sed -i '1ireplica-announce-ip 192.168.6.129' 7001/redis.conf
sed -i '1ireplica-announce-ip 192.168.6.129' 7002/redis.conf
sed -i '1ireplica-announce-ip 192.168.6.129' 7003/redis.conf
printf '%s\n' 7001 7002 7003 | xargs -I{} -t sed -i 'la replica-announce-ip 192.168.6.129' {}/redis.conf
后台redis重启得杀进程
还是不管用
给从节点打开前台连接(可以看到日志和报错,在配置中改daemonize no),再执行slaveof 192.168.6.129 7001
应该是master连接需要密码导致的
把配置文件中requirepass 1325
注释掉
终于有了
在master set num 1222
在slave keys *
成功了
不能在从节点写
数据同步原理
主从第一次同步是全量同步
master如何判断slave是不是第一次来同步数据呢?(根据replid来判断,不一致则为第一次)
1、Replication Id,简称replid,是数据集的标记,id一致则说明是同一数据集,每一个master都有唯一的replid,slave则会继承master节点的replid,第一次来主会把id同步给从节点
2、offset偏移量,随着记录在repl------baklog中的数据增多,slave完成同步时也会记录当前同步的offset。如果slave的offset小于master的offset,说明slave数据落后于master,需要更新
因此slave做数据同步,必须向master声明自己的replication id和offset,master才可以判断到底需要同步哪些数据
如果slave重启后同步,则执行增量同步
repl_baklog的存储是一个环形的,存满了会覆盖。repl_baklog大小是有上限的,写满后会覆盖最早的数据,如果slave断开太久,导致未备份的数据被覆盖了,则无法基于log增量同步,只能再次全量同步
优化Redis主从
1、在master中配置repl-diskless-sync yes启动无磁盘赋值,避免全量同步时的磁盘IO(全量同步写入RDB文件时候是写入磁盘的效率太低了,我们配置写入网络然后直接发给从节点)提高全量同步性能
2、Redis单节点上的内存占用不要太大,减少RDB导致的过多磁盘IO(不用写太多)提高全量同步性能角度
3、适当提高repl_baklog的大小,发现slave宕机时尽快实现故障恢复,尽可能避免全量同步
4、限制一个master的slave节点数量,如果实在太多slave,则可以采用主从从链式结构,减少master压力
总结+面试题
1、Redis主从节点是长连接还是短连接?
长连接
2、主从复制架构中,过期key如何处理?
主节点处理了一个key或者通过淘汰算法淘汰了一个key,这个时间主节点模拟一条del命令发送给从节点,从节点收到该命令后,就进行删除key的操作。
3、Redis 是同步复制还是异步复制?
Redis 主节点每次收到写命令之后,先写到内部的缓冲区,然后异步发送给从节点。