【Redis】主从复制

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 主节点每次收到写命令之后,先写到内部的缓冲区,然后异步发送给从节点。

相关推荐
Loganer几秒前
MongoDB分片集群搭建
数据库·mongodb
LKID体4 分钟前
Python操作neo4j库py2neo使用之创建和查询(二)
数据库·python·neo4j
刘大浪29 分钟前
后端数据增删改查基于Springboot+mybatis mysql 时间根据当时时间自动填充,数据库连接查询不一致,mysql数据库连接不好用
数据库·spring boot·mybatis
无敌岩雀36 分钟前
MySQL中的索引
数据库·mysql
a_安徒生1 小时前
linux安装TDengine
linux·数据库·tdengine
程序员学习随笔1 小时前
PostgreSQL技术内幕19:逻辑备份工具pg_dump、pg_dumpall
数据库·postgresql
尘浮生2 小时前
Java项目实战II基于微信小程序的校运会管理系统(开发文档+数据库+源码)
java·开发语言·数据库·微信小程序·小程序·maven·intellij-idea
偶尔。5352 小时前
什么是事务?事务有哪些特性?
数据库·oracle
安迁岚2 小时前
【SQL Server】华中农业大学空间数据库实验报告 实验六 视图
数据库·sql·mysql·oracle·实验报告
xoxo-Rachel2 小时前
(超级详细!!!)解决“com.mysql.jdbc.Driver is deprecated”警告:详解与优化
java·数据库·mysql