Redis复制(replica)
Redis复制(replica)
说明
主从复制。master主机为主,slave为从。master主机写,slave主机读。
当master数据变化的时候,自动将新的数据异步同步到其他slave数据库。
以实现读写分离,容灾恢复,数据备份,水平扩容支持高并发。
配置主从复制
在一台服务器上启动多个redis server的准备工作。由于演示是一台服务器上启动多个redis实例,不同实例要使用不同端口和进程
1.复制三份redis配置文件
2.以6379端口为主,其他两个为从。先修改6379master主机的配置文件
- 设置master主机的访问密码
- 修改daemonize为yes
- 注释掉bind的信息
- 设置protected-mode为no
- 指定当前实例的进程 ID 文件的位置。确保每个实例具有唯一的进程 ID 文件路径。
- 指定log文件生成目录及文件名
- 设置dbfilename以当前端口号命名
3.修改6380slave主机的配置文件
- 6380slave主机与master基本一致,需要将所有6379的字样改为6380。然后进行下面的操作
- 设置要访问的master主机的IP及端口
- 设置访问master主机需要的访问密码
3.修改6381的配置文件,修改点同6380
4.启动三台redis server
[root@iZ2ze4jd3wbsstj2idalpgZ ~]# redis-server /myredis/redis6379.conf [root@iZ2ze4jd3wbsstj2idalpgZ ~]# redis-server /myredis/redis6380.conf [root@iZ2ze4jd3wbsstj2idalpgZ ~]# redis-server /myredis/redis6381.conf
5.三个redis实例分别启动成功
[root@iZ2ze4jd3wbsstj2idalpgZ ~]# redis-cli -p 6379 127.0.0.1:6379> auth xxxxxx OK 127.0.0.1:6379> ping # 6379启动成功 PONG [root@iZ2ze4jd3wbsstj2idalpgZ ~]# redis-cli -p 6380 127.0.0.1:6380> auth xxxxxx OK 127.0.0.1:6380> ping # 6380启动成功 PONG [root@iZ2ze4jd3wbsstj2idalpgZ ~]# redis-cli -p 6381 127.0.0.1:6381> auth xxxxxx OK 127.0.0.1:6381> ping # 6381启动成功 PONG 127.0.0.1:6381>
6.进入6379master实例中,使用info replication命令查看主从关系和配置信息
[root@iZ2ze4jd3wbsstj2idalpgZ ~]# redis-cli -p 6379 -a xxxxxx Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe. 127.0.0.1:6379> INFO replication # 查看关系 # Replication role:master # 当前实例角色为master connected_slaves:2 # 有两个slave实例下面是两个slave主机的信息 slave0:ip=127.0.0.1,port=6381,state=online,offset=854,lag=0 slave1:ip=127.0.0.1,port=6380,state=online,offset=840,lag=1 master_failover_state:no-failover master_replid:a83530ea0ef427b70de1432f10fb9d11075f8a4d master_replid2:0000000000000000000000000000000000000000 master_repl_offset:854 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:854 127.0.0.1:6379>
常用命令
info replication
说明:查看复制节点的主从关系和配置信息
演示:
[root@iZ2ze4jd3wbsstj2idalpgZ ~]# redis-cli -p 6380 127.0.0.1:6380> auth xxxxxx OK 127.0.0.1:6380> INFO replication # Replication role:slave master_host:127.0.0.1 master_port:6379 master_link_status:up master_last_io_seconds_ago:3 master_sync_in_progress:0 slave_read_repl_offset:1835 slave_repl_offset:1835 slave_priority:100 slave_read_only:1 replica_announced:1 connected_slaves:0 master_failover_state:no-failover master_replid:fe59ffab2d5bee73b30f121ca1870ea9ff0e03dd master_replid2:0000000000000000000000000000000000000000 master_repl_offset:1835 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:1835 127.0.0.1:6380>
slaveof no one
说明:当前数据库停止与其他master数据库的同步。即从salve角色转为master角色。仅本次连接生效
演示:
127.0.0.1:6380> slaveof no one # 将当前slave设置为master OK 127.0.0.1:6380> INFO replication # Replication role:master # 设置成功 connected_slaves:0 master_failover_state:no-failover master_replid:80a58b3a19ee9cca28cb186d5ff044f682e27e8d master_replid2:fe59ffab2d5bee73b30f121ca1870ea9ff0e03dd master_repl_offset:1905 second_repl_offset:1906 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:1905 127.0.0.1:6380>
slaveof
说明:在运行期间修改slave节点的信息,如果该数据已经是某个主数据库的从数据库,那么会停止和原主数据库的同步关系转而和新的主数据库同步。仅本次连接生效
演示:
[root@iZ2ze4jd3wbsstj2idalpgZ ~]# redis-cli -p 6381 127.0.0.1:6381> auth xxxxxx OK 127.0.0.1:6381> INFO replication # Replication role:slave master_host:127.0.0.17 master_port:6379 # 当前slave指向的的master时端口为6379的 master_link_status:up master_last_io_seconds_ago:0 master_sync_in_progress:0 slave_read_repl_offset:2073 slave_repl_offset:2073 slave_priority:100 slave_read_only:1 replica_announced:1 connected_slaves:0 master_failover_state:no-failover master_replid:fe59ffab2d5bee73b30f121ca1870ea9ff0e03dd master_replid2:0000000000000000000000000000000000000000 master_repl_offset:2073 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:338 repl_backlog_histlen:1736 127.0.0.1:6381> slaveof 127.0.0.1 6380 #修改master从6379改为6380 OK 127.0.0.1:6381> INFO replication # Replication role:slave master_host:127.0.0.1 master_port:6380 #修改成功 master_link_status:down master_last_io_seconds_ago:-1 master_sync_in_progress:0 slave_read_repl_offset:2255 slave_repl_offset:2255 master_link_down_since_seconds:3 slave_priority:100 slave_read_only:1 replica_announced:1 connected_slaves:0 master_failover_state:no-failover master_replid:fe59ffab2d5bee73b30f121ca1870ea9ff0e03dd master_replid2:0000000000000000000000000000000000000000 master_repl_offset:2255 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:338 repl_backlog_histlen:1918 127.0.0.1:6381>
场景演示
case1:从机不可执行写入命令
[root@iZ2ze4jd3wbsstj2idalpgZ myredis]# redis-cli -p 6380 # 6380为slave从机 127.0.0.1:6380> auth xxxxxx OK 127.0.0.1:6380> set k1 v1 #k1 set 失败 (error) READONLY You can't write against a read only replica. 127.0.0.1:6380>
case2:master关机后,slave会怎么样
结论:slave角色不变,其指向的master状态为down。待master重启后仍保持其主从关系
[root@iZ2ze4jd3wbsstj2idalpgZ myredis]# redis-cli -p 6379 127.0.0.1:6379> auth xxxxxx OK 127.0.0.1:6379> SHUTDOWN # 关闭master not connected> quit [root@iZ2ze4jd3wbsstj2idalpgZ myredis]# redis-cli -p 6380 # 登录slave 127.0.0.1:6380> auth xxxxxx OK 127.0.0.1:6380> INFO replication # 查看当前slave实例的主从关系 # Replication role:slave # 角色仍是slave master_host:127.0.0.1 master_port:6379 master_link_status:down #master状态为down,但其角色仍是slave master_last_io_seconds_ago:-1 master_sync_in_progress:0 slave_read_repl_offset:2114 slave_repl_offset:2114 master_link_down_since_seconds:32 slave_priority:100 slave_read_only:1 replica_announced:1 connected_slaves:0 master_failover_state:no-failover master_replid:a83530ea0ef427b70de1432f10fb9d11075f8a4d master_replid2:0000000000000000000000000000000000000000 master_repl_offset:2114 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:827 repl_backlog_histlen:1288 127.0.0.1:6380>
case3:某台slave down后,master继续写入,从机重启后数据是否会丢失
结论:不会丢失
[root@iZ2ze4jd3wbsstj2idalpgZ myredis]redis-cli -p 6381 127.0.0.1:6381> auth xxxxxx OK 127.0.0.1:6381> SHUTDOWN # down掉slave not connected> quit [root@iZ2ze4jd3wbsstj2idalpgZ myredis] redis-cli -p 6379 -a xxxxxx Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe. 127.0.0.1:6379> set k1 abcdefg # master写入k1 OK 127.0.0.1:6379> quit [root@iZ2ze4jd3wbsstj2idalpgZ myredis] redis-server /myredis/redis6381.conf # 重启6381slave [root@iZ2ze4jd3wbsstj2idalpgZ myredis] redis-cli -p 6381 -a xxxxxx Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe. 127.0.0.1:6381> get k1 #在从机上查看刚才down机时master写入的数据 "abcdefg" 127.0.0.1:6381>
case4:上一个slave可以是下一个slave的master。
为什么这么做:可以有效减轻主master的写压力。
步骤:将下一个slave配置文件中的replicaof字段修改为上一个slave实例的IP及端口,并设置上一个salve的访问密码(masterauth)
127.0.0.1:6380> info replication # Replication role:slave # 6380为slave master_host:127.0.0.1 master_port:6379 # 6379为它的master master_link_status:up master_last_io_seconds_ago:7 master_sync_in_progress:0 slave_read_repl_offset:2563 slave_repl_offset:2563 slave_priority:100 slave_read_only:1 replica_announced:1 connected_slaves:1 slave0:ip=127.0.0.1,port=6381,state=online,offset=2563,lag=1 # 6381为它的slave master_failover_state:no-failover master_replid:fe59ffab2d5bee73b30f121ca1870ea9ff0e03dd master_replid2:0000000000000000000000000000000000000000 master_repl_offset:2563 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:2256 repl_backlog_histlen:308 127.0.0.1:6380>
注意点:
slave启动成功连接到master后会发送一个sync命令,把master主机上已有的数据全部复制下来,slave自身原有数据会被master数据覆盖清除。后续master的写入操作,slave会同步复制。
slave从机中途变更转向:会清楚之前的数据,重新建立拷贝最新的。
缺点
1.由于所有的写操作都是先在Master上操作,然后同步更新到Slave上,所以从Master同步到Slave机器有一定的延迟,当系统很繁忙的时候,延迟问题会更加严重,Slave机器数量的增加也会使这个问题更加严重。
2.master如果挂了,默认情况下不会在slave节点中自动重选一个master。不想每次都人工干预,就需要使用无人值守安装、。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构