副本在设置 maxmemory 时会应用逐出策略吗?

最后更新于 2024 年 3 月 22 日

问题

在 Redis 复制拓扑中,当逐出策略设置为 noeviction 以外的值时,逐出键的决定是仅基于主节点的读/写操作,还是也基于副本节点的读操作?

回答

Redis OSS 复制拓扑允许在副本上进行读操作,因此这个问题适用于 Redis 或 Redis Stack 复制拓扑。Redis Enterprise 和 Redis Cloud 数据库不支持在副本分片上进行读操作。读操作会影响键的最后访问时间或访问频率,这可能导致主节点和副本节点上逐出的键不同,从而导致主节点与其副本之间的数据不一致。

来自文档

当主节点和副本实例连接良好时,主节点通过向副本发送命令流来保持副本的更新,以复制由于以下操作导致的主节点数据集上的效果:客户端写入、键过期或被逐出,以及任何其他改变主节点数据集的操作。

因此,逐出和过期都会复制到副本。另请注意,副本不会因为内存不足(OOM)条件而主动逐出键。

默认情况下,副本会忽略 maxmemory(除非在故障转移后或手动提升为主节点)。这意味着键的逐出将由主节点处理,当主节点逐出键时,会将 DEL 命令发送给副本。

您可以通过在主服务器上设置严格的 maxmemory 值来验证主节点如何传播逐出命令。

CONFIG SET maxmemory <BYTES>

然后,您可以连接一个以副本模式运行的 redis-cli 会话到主节点。

redis-cli --replica
sending REPLCONF capa eof
SYNC with master, discarding 213 bytes of bulk transfer...
SYNC done. Logging commands from master.

然后,在主节点上插入一些数据,直到达到内存不足(OOM)条件。

SET hello world
(error) OOM command not allowed when used memory > 'maxmemory'

并从 redis-cli 验证 DEL 命令是否已传播。

"ping"
"ping"
"DEL","collection"
"DEL","hello"
"ping"

参考资料

有关逐出机制的说明,请参阅文档