Redis 主从复制——masteruser
默认情况下,主从节点的连接用户是 default 用户,但在很多生产环境中 default 用户都会被禁止(禁用)使用。同时为了遵循权限最小原则,建议为主从复制专门设置一个用户用于连接认证。在 Redis 中,可以配置从节点以哪个用户连接主节点,该配置为 masteruser。
主从复制配置
在 Redis 主从复制中,可以指定主从复制的连接用户,即从节点以什么用户连接主节点。默认是 default 用户,但也可指定其他用户。如何指定呢?
需要主从节点都配置 ACL,设置用户密码以及权限。例如,设置一个专门用于主从复制的用户 replica,并授予其主从复制所必需的命令权限:
postgres@slpc:/etc/redis$ sudo cat users.acl
user replica on #0ac34389d10624a1f24a923b63b0d8a739350686f8149ef4149f6c4a3703a42e ~* &* -@all +replconf +psync +ping
在 redis.conf 中添加如下配置:
masteruser replica # 指定从节点连接主节点所使用的用户
masterauth <PASSWORD>
主从复制的日志分析
从节点日志:
130232:S 21 Jan 2026 14:26:04.515 * Before turning into a replica, using my own master parameters to synthesize a cached master: I may be able to synchronize with the new master with just a partial transfer.
130232:S 21 Jan 2026 14:26:04.515 * Ready to accept connections
130232:S 21 Jan 2026 14:26:04.516 - DB 0: 2 keys (0 volatile) in 4 slots HT.
130232:S 21 Jan 2026 14:26:04.516 * Connecting to MASTER 192.168.232.128:6379 # 连接主节点
130232:S 21 Jan 2026 14:26:04.516 * MASTER <-> REPLICA sync started
130232:S 21 Jan 2026 14:26:04.517 * Non blocking connect for SYNC fired the event.
130232:S 21 Jan 2026 14:26:04.518 * Master replied to PING, replication can continue...
130232:S 21 Jan 2026 14:26:04.519 * Trying a partial resynchronization (request 41d1777223513929c644c859b467a1eed109a8e0:13885).
130232:S 21 Jan 2026 14:26:04.520 * Successful partial resynchronization with master.
130232:S 21 Jan 2026 14:26:04.520 # Master replication ID changed to adbfa6dda0b49450836902276f0cf2040e554271
130232:S 21 Jan 2026 14:26:04.520 * MASTER <-> REPLICA sync: Master accepted a Partial Resynchronization.
主节点日志:
166002:M 21 Jan 2026 14:26:03.553 * Ready to accept connections
166002:M 21 Jan 2026 14:26:03.553 - DB 0: 2 keys (0 volatile) in 4 slots HT.
166002:M 21 Jan 2026 14:26:04.495 - Accepted 192.168.232.137:40060
166002:M 21 Jan 2026 14:26:04.498 * Replica 192.168.232.137:6379 asks for synchronization
166002:M 21 Jan 2026 14:26:04.498 * Partial resynchronization request from 192.168.232.137:6379 accepted. Sending 0 bytes of backlog starting from offset 13885.
166002:M 21 Jan 2026 14:26:04.509 - Accepted 192.168.232.138:56888
166002:M 21 Jan 2026 14:26:04.512 * Replica 192.168.232.138:6379 asks for synchronization
166002:M 21 Jan 2026 14:26:04.513 * Partial resynchronization request from 192.168.232.138:6379 accepted. Sending 0 bytes of backlog starting from offset 13885.
源代码分析
当执行 replicaof 命令时,会调用 replicaofCommand 函数:
replicaofCommand(client *c)
--> replicationSetMaster(c->argv[1]->ptr, port);
--> connectWithMaster(); // 连接 master
// 发起连接,传入主节点 ip、port
--> connConnect(server.repl_transfer_s, server.masterhost, server.masterport, server.bind_source_addr, syncWithMaster)
当连接成功后,会调用 syncWithMaster 函数:
void syncWithMaster(connection *conn) {
/* If this event fired after the user turned the instance into a master
* with SLAVEOF NO ONE we must just return ASAP. */
if (server.repl_state == REPL_STATE_NONE) {
connClose(conn);
return;
}
// 发送 AUTH 命令
// 从节点向主节点进行认证:如果配置了 masteruser,则使用 masteruser 用户进行认证,
// 密码为读取 masterauth 配置得到的值
if (server.repl_state == REPL_STATE_SEND_HANDSHAKE) {
/* AUTH with the master if required. */
if (server.masterauth) {
char *args[3] = {"AUTH",NULL,NULL};
size_t lens[3] = {4,0,0};
int argc = 1;
if (server.masteruser) { // 添加认证用户
args[argc] = server.masteruser;
lens[argc] = strlen(server.masteruser);
argc++;
}
args[argc] = server.masterauth; // 添加认证密码
lens[argc] = sdslen(server.masterauth);
argc++;
err = sendCommandArgv(conn, argc, args, lens); // 向主节点发送认证信息
if (err) goto write_error;
}
// 发送 REPLCONF 命令
// 1. 告诉主节点,从节点的监听 port
sendCommand(conn,"REPLCONF",
"listening-port",portstr, NULL);
// 2. 告诉主节点,从节点能力信息:
sendCommand(conn,"REPLCONF",
"capa","eof","capa","psync2",NULL);
}
// 尝试进行部分同步,会向主节点发送 PSYNC 命令
slaveTryPartialResynchronization(conn,1);
}