Redis主从复制

前些天发现了一个巨牛的人工智能 学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站

在实际生产环境,Redis不可能只有单机配置,一旦服务器出现问题, 可能会导致数据丢失或其他严重问题

在分布式系统中为了解决单点问题 ,通常会把数据复制多个副本部署到其他服务器 ,满足故障恢复和负载均衡等需求。

Redis 也是如此,它为我们提供了复制的功能,实现了相同数据的多个 Redis 副本。复制功能是Redis的基础,哨兵和集群都是在复制的基础上构建的。


例如,有两台Redis服务器,可以设置一台为主机(Main),一台为从机(Secondary)。

主机通过复制机制将数据重写到从机上

主机以写操作为主,从机以读操作为主,通过读写分离 来减轻负担,当主机崩溃时,还可以把从机的数据当作实时备份

若配置了多台从机,还可以通过轮询的方式进一步减轻压力

Redis服务器默认都是主节点(Master),要想让它变为某个主节点的从节点,有三种配置方式:

  1. 配置文件:replicaof [主节点IP] [主节点Port](Redis启动时)
  2. 启动参数:redis-server --replicaof [主节点IP] [主节点Port](Redis 启动时),重启后失效
  3. 客户端命令:REPLICAOF [主节点IP] [主节点Port](运行期间立即生效),在重启后会失效

若主节点配置了密码(requirepass参数),在从节点的配置文件中需要有masterauth [主节点密码]参数,才能通过身份验证并建立主从复制关系

配置演示(一主多从)

要模拟多台Redis,可以用启动多个redis-server,但是要配置不同的端口号

我们将主节点端口为默认6379,而将两个从节点的配置文件(redis.conf)的port改为其他端口

bash 复制代码
# 从节点1
# 配置端口号
# Accept connections on the specified port, default is 6379 (IANA #815344).
# If port 0 is specified Redis will not listen on a TCP socket.
port 6380

# 配置pid文件,通过该文件查看该redis的pid
# Note that on modern Linux systems "/run/redis.pid" is more conforming
# and should be used instead.
pidfile /var/run/redis_6380.pid

# 配置日志文件路径
# Specify the log file name. Also the empty string can be used to force
# Redis to log on the standard output. Note that if you use standard
# output for logging but daemonize, logs will be sent to /dev/null
logfile /myredis/log/6380.log

# 配置RDB文件名
# The filename where to dump the DB
dbfilename dump6380.rdb # 加上端口号更好辨认

# 若开启了AOF,需要修改AOF文件名
# - appendonly.aof.1.base.rdb as a base file.
# - appendonly.aof.1.incr.aof, appendonly.aof.2.incr.aof as incremental files.
# - appendonly.aof.manifest as a manifest file.
appendfilename "appendonly6380.aof"

# 配置主节点密码
# If the master is password protected (using the "requirepass" configuration
# directive below) it is possible to tell the replica to authenticate before
# starting the replication synchronization process, otherwise the master will
# refuse the replica request.
#
masterauth [主节点密码]

# 通过配置文件设置replicaof
replicaof 127.0.0.1 6379
bash 复制代码
# 从节点2
# 配置端口号
# Accept connections on the specified port, default is 6379 (IANA #815344).
# If port 0 is specified Redis will not listen on a TCP socket.
port 6381

...... # 下面与从节点1的配置类似

配置完成后,依次启动三个redis-server:

bash 复制代码
redis-server /myredis/redis.conf # 主节点
redis-server /myredis/redis-replica1.conf # 从节点1
redis-server /myredis/redis-replica2.conf # 从节点2

现在三台Redis都在后台运行

bash 复制代码
[root@learn-linux myredis]# ps axj | grep redis-server
      1  218905  218905  218905 ?             -1 Ssl      0   0:00 redis-server *:6379
      1  220269  220269  220269 ?             -1 Ssl      0   0:00 redis-server *:6380
      1  220453  220453  220453 ?             -1 Ssl      0   0:00 redis-server *:6381
 208341  220626  220625  197307 pts/0     220625 S+       0   0:00 grep --color=auto redis-server

现在登上主节点客户端,用INFO REPLICATION可以看到该Redis的主从关系

bash 复制代码
127.0.0.1:6379> INFO REPLICATION
# Replication
role:master # 主节点
connected_slaves:2 # 有两台从节点
slave0:ip=127.0.0.1,port=6380,state=online,offset=840,lag=1 # 第一台
slave1:ip=127.0.0.1,port=6381,state=online,offset=840,lag=1 # 第二台
......

在登录从节点客户端时,需要用-p [端口号]指定端口,否则会默认登6379

bash 复制代码
[root@learn-linux myredis]# redis-cli --askpass --raw -p 6380
Please input password: ***********
127.0.0.1:6380> 

在从节点INFO REPLICATION,也可以看到该Redis的主从关系

bash 复制代码
127.0.0.1:6380> INFO REPLICATION
# Replication
role:slave # 从节点
master_host:127.0.0.1 # 主节点IP
master_port:6379 # 主节点端口
master_link_status:up # 主从连接状态
......

若该Redis服务在成为从节点之前有自己的数据,在成为从节点后也会被覆盖,数据都是主节点的备份

  • 主节点宕机重启后,主从关系依然在;但如果从节点是通过客户端命令或启动参数配置的,重启后主从关系消失
  • 主从关系中,从节点默认为只读模式,不能写入数据
bash 复制代码
# 从节点1
127.0.0.1:6380> set k1 v1
READONLY You can't write against a read only replica.

若要修改也可以在配置文件中找到replica-read-only参数,改为no即可(修改从节点会造成主从数据不一致,建议线上不要修改)

bash 复制代码
# Since Redis 2.6 by default replicas are read-only.
#
# Note: read only replicas are not designed to be exposed to untrusted clients
# on the internet. It's just a protection layer against misuse of the instance.
# Still a read only replica exports by default all the administrative commands
# such as CONFIG, DEBUG, and so forth. To a limited extent you can improve
# security of read only replicas using 'rename-command' to shadow all the
# administrative / dangerous commands.
replica-read-only yes
  • 从节点启动后,先进行一次全量复制,后续跟随(写一条跟一条)
  • 如果已有跟随的主节点,也可以通过REPLICAOF [主节点IP] [主节点Port]临时变更,跟随其他主节点

若从节点不想与主节点绑定了,可以执行REPLICAOF NO ONE,停止与其他数据库同步,转为主节点 。断开后不会丢去原有数据

但如果主从复制配置是通过redis.conf配置文件生效的,在该从节点重启后,仍然会恢复从节点

树形拓扑

当主节点的从机变多后,主节点负载压力会变大 ,这时如果将一些从节点转移到另外一个从节点下,就可以有效减轻主节点负担

也就是说,从节点也可以当其他节点的主节点 ,直接replicaof指向ip+port即可

但即使该Redis服务某个节点的主节点,只要它还是某个节点的从节点,就依然是只读模式,不能写入

主从节点⼀般部署在不同机器上,复制时的网络延迟 就成为需要考虑的问题,这一点在树形拓扑中会更明显 :越往枝叶的节点,网络延迟越大,因为需要等该从节点的主节点先同步

Redis 为我们提供了repl-disable-tcp-nodelay参数用于控制是否关闭 TCP_NODELAY ,默认为 no,即开启 tcp- nodelay 功能

bash 复制代码
# Disable TCP_NODELAY on the replica socket after SYNC?
#
# If you select "yes" Redis will use a smaller number of TCP packets and
# less bandwidth to send data to replicas. But this can add a delay for
# the data to appear on the replica side, up to 40 milliseconds with
# Linux kernels using a default configuration.
#
# If you select "no" the delay for data to appear on the replica side will
# be reduced but more bandwidth will be used for replication.
#
# By default we optimize for low latency, but in very high traffic conditions
# or when the master and replicas are many hops away, turning this to "yes" may
# be a good idea.
repl-disable-tcp-nodelay no
  • 当关闭时,主节点产生的命令数据无论大小都会及时地发送给从节点 ,这样主从之间延迟会变小 ,但增加了网络带宽的消耗 。适用于主从之间的网络环境良好的场景,如同机房部署。
  • 当开启时,主节点会合并较小的 TCP 数据包从而节省带宽 。默认发送时间间隔取决于 Linux 的内核,一般默认为 40 毫秒。这种配置节省了带宽但增大主从之间的延迟 。适用于主从网络环境复杂的场景,如跨机房部署。

主从复制优缺点

优点:解决了单点问题,单个Redis节点可用性不高,性能有限

缺点:

  1. 当从节点变多后,复制数据的延时会越来越明显
  2. 主机挂了, 从机不会升级成主机 . 只能通过人工干预的方式恢复,这就需要引入哨兵(Sentinel)来解决
相关推荐
慧都小妮子1 小时前
Wyn商业智能国产数据库适配:数据接入、分析缓存与审计日志验证清单
数据库·数据分析·数据可视化·审计日志·商业智能
沫璃染墨1 小时前
从零入门计算机网络系列(十八):TCP连接管理详解——从三次握手与四次挥手到TIME_WAIT机制
运维·服务器·网络·c++·网络协议·tcp/ip·tcp
Felven2 小时前
华为鲲鹏920s芯片serdestool工具使用说明
linux·运维·服务器·华为·鲲鹏920·serdestool
Joy T2 小时前
Redis Lua 原子限流:Lua 脚本、竞态条件与并发控制
数据库·redis·lua·限流·竞态条件·redis scripting
LabVIEW开发2 小时前
Omron PLC:接 LabVIEW 常踩的 5 个坑
服务器·网络·labview·labview知识·labview功能·labview程序
杨凯凡2 小时前
MySQL 死锁怎么排查?InnoDB 锁等待与 Spring Boot 整事务重试实战
数据库·spring boot·mysql
Aloudata2 小时前
Claude 做数据分析的这两年:一份复盘与发展线索
大数据·数据库·人工智能·数据挖掘·数据分析·dataagent
Decay__2 小时前
01_SQLServer 体系架构全解 —— 实例进程、关系引擎、SQLOS 与事务日志深入
运维·数据库·sql·mysql·架构
zhanghaha13143 小时前
C# 系列教程_12 字符串 string 保姆级系统教程(面向新手,大量示例 + 原理讲解)
开发语言·数据库·c#