zl程序教程

您现在的位置是:首页 >  数据库

当前栏目

Redis 主从复制的搭建

Redis 搭建 主从复制
2023-09-14 09:01:47 时间

Redis为什么需要主从复制 


在单机版(仅有一个Redis)的Redis中,数据的读写操作都只能靠一个Redis完成,当数据量大的时候,无法满足我们的需求

 

什么是Redis主从 


Redis主从同步。数据可以从主服务器向任意数量的从服务器上同步,从服务器可以是关联其他从服务器的主服务器。这使得Redis可执行单层树复制。存盘可以有意无意的对数据进行写操作。由于完全实现了发布/订阅机制,使得从数据库在任何地方同步树时,可订阅一个频道并接收主服务器完整的消息发布 记录。同步对读取操作的可扩展性和数据冗余很有帮助。

 

Redis主从拓扑


    a)一主一从:用于主节点故障转移从节点,当主节点的“写”命令并发高且需要持久化,可以只在从节点开启AOF(主节点不需要),这样即保证了数据的安全性,也避免持久化对主节点的影响

    b)一主多从:针对“读”较多的场景,“读”由多个从节点来分担,但节点越多,主节点同步到多节点的次数也越多,影响带宽,也加重主节点的稳定

    c)树状主从:一主多从的缺点(主节点推送次数多压力大)可用些方案解决,主节点只推送一次数据到从节点B,再由从节点B推送到C,减轻主节点推送的压力。

 

主从环境的搭建


环境如下:主从的配置相对于MySQL的主从来说配置非常的简单,只需要修改几行配置文件重启一下就行了

主机

角色

ip

centos7.4

master

192.168.179.102

centos7.4

slave

192.168.179.103

centos7.4

slave

192.168.179.104

主库配置192.168.179.102

[root@localhost ~]# vim /usr/local/redis/6379.conf
bind 0.0.0.0 监听所有ip

[root@localhost src]# /etc/init.d/redis_6379 restart  
Starting Redis server...

从库配置 192.168.179.103/104,两台配置如下

[root@localhost ~]# vim /usr/local/redis/6379.conf
bind 0.0.0.0
replicaof  192.168.179.102  6379  --指定隶属于谁

[root@localhost src]# /etc/init.d/redis_6379 start
Starting Redis server...

[root@localhost utils]# /usr/local/redis/bin/redis-cli  --主库

127.0.0.1:6379> info replication   -- --只查看replication信息
# Replication
role:master
connected_slaves:2  ----目前有两个从库在连接
slave0:ip=192.168.179.104,port=6379,state=online,offset=6146,lag=0   --offet类似于mysql pos点,指定从哪同步
slave1:ip=192.168.179.103,port=6379,state=online,offset=6146,lag=0
master_replid:999f89051b48418f2b1f498996d9a6f77a4feb5f
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:6146
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:6146

 

[root@localhost ~]# /usr/local/redis/bin/redis-cli   --从库

127.0.0.1:6379> info replication
# Replication
role:slave
master_host:192.168.179.102
master_port:6379
master_link_status:up
master_last_io_seconds_ago:10
master_sync_in_progress:0
slave_repl_offset:6146
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:999f89051b48418f2b1f498996d9a6f77a4feb5f
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:6146
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:3669
repl_backlog_histlen:2478

以上主从就配置成功了

 

全量同步


Redis全量复制一般发生在Slave初始化阶段,这时Slave需要将Master上的所有数据都复制一份。具体步骤如下:

  1. 从服务器连接主服务器,发送SYNC命令
  2. 主服务器接收到SYNC命名后,开始执行BGSAVE命令生成RDB文件并使用缓冲区记录此后执行的所有写命令
  3. 主服务器BGSAVE执行完后,向所有从服务器发送快照文件,并在发送期间继续记录被执行的写命令
  4. 从服务器收到快照文件后丢弃所有旧数据,载入收到的快照
  5. 主服务器快照发送完毕后开始向从服务器发送缓冲区中的写命令
  6. 从服务器完成对快照的载入,开始接收命令请求,并执行来自主服务器缓冲区的写命令,下面是从库redis的日志信息
1734:S 05 Apr 2020 14:43:15.568 * Ready to accept connections
1734:S 05 Apr 2020 14:43:15.568 * Connecting to MASTER 192.168.179.102:6379
1734:S 05 Apr 2020 14:43:15.568 * MASTER <-> REPLICA sync started
1734:S 05 Apr 2020 14:43:15.568 * Non blocking connect for SYNC fired the event.
1734:S 05 Apr 2020 14:43:15.569 * Master replied to PING, replication can continue... 
--ping一下从库看看从库有没有挂掉
1734:S 05 Apr 2020 14:43:15.569 * Trying a partial resynchronization (request 7b5a7b0d851a90d076fc50ea625e6ff7f05fa3f8:841).
1734:S 05 Apr 2020 14:43:15.574 * Full resync from master: 999f89051b48418f2b1f498996d9a6f77a4feb5f:0  --全量同步开始
1734:S 05 Apr 2020 14:43:15.574 * Discarding previously cached master state.
1734:S 05 Apr 2020 14:43:15.604 * MASTER <-> REPLICA sync: receiving 175 bytes from master
1734:S 05 Apr 2020 14:43:15.604 * MASTER <-> REPLICA sync: Flushing old data
1734:S 05 Apr 2020 14:43:15.604 * MASTER <-> REPLICA sync: Loading DB in memory --这个DB是RDB,从磁盘将RDB文件载入磁盘
1734:S 05 Apr 2020 14:43:15.604 * MASTER <-> REPLICA sync: Finished with success

 

增量同步


Redis增量复制是指Slave初始化后开始正常工作时主服务器发生的写操作同步到从服务器的过程。 增量复制的过程主要是主服务器每执行一个写命令就会向从服务器发送相同的写命令,从服务器接收并执行收到的写命令。

如果重启slave之后会发现不是再使用全量同步而是使用增量同步

14683:S 04 Sep 2020 10:07:40.386 * DB loaded from disk: 0.000 seconds
14683:S 04 Sep 2020 10:07:40.386 * Before turning into a replica, using my master parameters to synthesize a cached master: I may be able to synchronize with the new master with just a partial transfer.
14683:S 04 Sep 2020 10:07:40.387 * Ready to accept connections
14683:S 04 Sep 2020 10:07:40.388 * Connecting to MASTER 127.0.0.1:6379
14683:S 04 Sep 2020 10:07:40.389 * MASTER <-> REPLICA sync started
14683:S 04 Sep 2020 10:07:40.389 * Non blocking connect for SYNC fired the event.
14683:S 04 Sep 2020 10:07:40.390 * Master replied to PING, replication can continue...
14683:S 04 Sep 2020 10:07:40.390 * Trying a partial resynchronization (request 4297f4998a5efd077f69167529a71543818bcbf8:2378).
14683:S 04 Sep 2020 10:07:40.391 * Successful partial resynchronization with master.
14683:S 04 Sep 2020 10:07:40.392 * MASTER <-> REPLICA sync: Master accepted a Partial Resynchronization.

Redis的主从复制下,一旦主节点由于故障不能提供服务,需要人工将从节点晋升为主节点,同时还要通知应用方更新主节点地址,对于很多应用场景这种故障处理的方法是无法接受的。但是Redis从2.8开始正式提供了Redis Sentinel(哨兵)架构来解决这个问题。

 

主从复制设置密码


主库的配置文件设置了密码

[root@localhost ~]# vim /usr/local/redis-repl/6379/6379.conf 
requirepass 123456

重启主库之后从库报错 

11460:S 22 Sep 2020 21:16:55.822 * (Non critical) Master does not understand REPLCONF listening-port: -NOAUTH Authentication required.
11460:S 22 Sep 2020 21:16:55.822 * (Non critical) Master does not understand REPLCONF capa: -NOAUTH Authentication required.
11460:S 22 Sep 2020 21:16:55.822 * Partial resynchronization not possible (no cached master)
11460:S 22 Sep 2020 21:16:55.823 # Unexpected reply to PSYNC from master: -NOAUTH Authentication required.
11460:S 22 Sep 2020 21:16:55.823 * Retrying with SYNC...
11460:S 22 Sep 2020 21:16:55.823 # MASTER aborted replication with an error: NOAUTH Authentication required.

修改从库配置文件,重启可以在日志当中观察同步成功

[root@localhost ~]# vim /usr/local/redis-repl/6380/6380.conf 
masterauth 123456
假设我们有两台redis服务器,其主从IP地址分别为:192.168.1.11、192.168.1.12。
如果我们在主redis服务器上设置了密码,即:在redis.conf配置文件中使用了requirepass 12345678(你设置的密码);
那么我们在从redis服务器上的配置文件redis.conf中使用了slaveof 192.168.1.11 6379后发现:主从复制失败。
解决方案是:在从redis服务器上的配置文件redis.conf中找到:masterauth <master-password>这一行,然后在这一行的下面写上
masterauth 12345678(主redis服务器密码)。这时候我们再分别重启主redis服务器和从redis服务器,则发现主从复制成功!