配置Redis主从复制

TrumanWong
12/5/2024
TrumanWong

主从复制是指将一台Redis服务器的数据复制到其他的Redis服务器,主从是Sentinel(哨兵)和Cluster(集群)模式能够实施的基础。前者称为主节点master,后者称为从节点slave,数据的复制是单向的,只能由主节点到从节点。

默认情况下,每台Redis服务器都是主节点,并且一个主节点可以有零个或多个从节点,但是一个从节点只能有一个主节点。一般主节点负责接收写请求,从节点负责接收读请求,从而实现读写分离。

配置主从复制可以通过以下两种方式:

通过slaveof命令方式

启动master节点:

$ docker run -d -p 6379:6379 --name redis-master redis

启动slave节点:

$ docker run -d -p 6380:6379 --name redis-slave redis

进入slave节点,

$ docker exec -it redis-slave /bin/bash

redis-slave容器中,执行slaveof命令,设置redis-mastermaster节点:

root@596afe82d4c2:/data# redis-cli
127.0.0.1:6379> slaveof 172.17.0.1 6379
OK

进入redis-master,执行如下命令:

$ docker exec -it redis-master /bin/bash
root@71145808cbe4:/data# redis-cli
127.0.0.1:6379> set name truman
OK

进入redis-slave,验证数据是否同步:

127.0.0.1:6379> get name
"truman"

可以看到,数据已经同步过来,执行info replication可以查看主从信息:

# redis-master中执行如下命令
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:1
slave0:ip=172.17.0.1,port=6379,state=online,offset=296,lag=1
master_failover_state:no-failover
master_replid:08e2a3e8dce5160e87a56b42b458028a1f6654b1
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:296
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:296

# redis-slave中执行如下命令:
127.0.0.1:6379>  info replication
# Replication
role:slave
master_host:172.17.0.1
master_port:6379
master_link_status:up
master_last_io_seconds_ago:2
master_sync_in_progress:0
slave_read_repl_offset:506
slave_repl_offset:506
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:08e2a3e8dce5160e87a56b42b458028a1f6654b1
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:506
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:15
repl_backlog_histlen:492

当从节点可以查询到主节点写入键的值时,表示此主从架构的主从同步没有问题。

通过配置文件方式

创建如下目录:

$ mkdir -p redis-master/conf redis-slave/conf

下载redis.confredis-master/confredis-slave/conf目录下

redis-master/目录新建docker-compose.yaml,内容如下:

services:
  redis-master:
    image: docker.io/redis
    container_name: redis-master
    restart: always
    ports:
      - 6379:6379
    volumes:
      - ./conf/redis.conf:/etc/redis/redis.conf
      - ./data:/data
    command:
      redis-server /etc/redis/redis.conf

执行命令,启动master节点:

$ docker compose up -d
[+] Running 2/2
 ✔ Network redis-master_default  Created                                               0.1s 
 ✔ Container redis-master        Started                                               0.3s

redis-slave/目录新建docker-compose.yaml,内容如下:

services:
  redis-slave:
    image: docker.io/redis
    container_name: redis-slave
    restart: always
    ports:
      - 6380:6379
    volumes:
      - ./conf/redis.conf:/etc/redis/redis.conf
      - ./data:/data
    command:
      redis-server /etc/redis/redis.conf

master-slave/conf/redis.conf配置文件加入如下配置:

slaveof 172.17.0.1 6379
# 如果主节点有密码
masterauth password

执行命令,启动slave节点:

$ docker compose up -d
[+] Running 2/2
 ✔ Network redis-slave_default  Created                                                0.1s 
 ✔ Container redis-slave        Started                                                0.4s

至此,通过配置文件的方式搭建redis主从复制完成。

值得注意的是,如果master节点设置了密码认证,如果slave节点密码配置不正确,将无法建立主从连接:

127.0.0.1:6379> info replication
# Replication
role:slave
master_host:172.17.0.1
master_port:6379
master_link_status:down
master_last_io_seconds_ago:-1
master_sync_in_progress:0
slave_read_repl_offset:1
slave_repl_offset:1
master_link_down_since_seconds:-1
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:07b27bbbfb4cafcba76681b9545d766cc4bd19aa
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0

可以看到,master_link_status状态为down,通过docker logs redis-slave可以看到,主从在不断地尝试重新建立主从节点之间的连接:

$ docker logs redis-slave
...
1:S 05 Dec 2024 10:22:13.280 * Partial resynchronization not possible (no cached master)
1:S 05 Dec 2024 10:22:13.280 # Unexpected reply to PSYNC from master: -NOAUTH Authentication required.
1:S 05 Dec 2024 10:22:13.280 * Retrying with SYNC...
1:S 05 Dec 2024 10:22:13.280 # MASTER aborted replication with an error: NOAUTH Authentication required.
1:S 05 Dec 2024 10:22:13.281 * Reconnecting to MASTER 172.17.0.1:6379 after failure
1:S 05 Dec 2024 10:22:13.281 * MASTER <-> REPLICA sync started
1:S 05 Dec 2024 10:22:13.281 * Non blocking connect for SYNC fired the event.
1:S 05 Dec 2024 10:22:13.281 * Master replied to PING, replication can continue...
1:S 05 Dec 2024 10:22:13.281 * (Non critical) Master does not understand REPLCONF listening-port: -NOAUTH Authentication required.
1:S 05 Dec 2024 10:22:13.281 * (Non critical) Master does not understand REPLCONF capa: -NOAUTH Authentication required.