限制和风险
除非某项限制注明适用于特定 Redis 版本,否则该限制适用于两代 module。有关两者的区别,请参阅Module generations and version applicability。
目录
拓扑限制复制组两端必须运行相同的 Redis 版本两端的实例必须具有相同的架构一个复制组最多包含 16 个成员Active-Active 模式仅在 Redis 7.2 上可用一个实例最多保持一个上游连接配置限制无法关闭复制,且无法更改 Service ID不支持 AOF 持久化(Redis 7.2)最多 16 个数据库(Redis 7.2)连接名称必须是有效的模块对等端名称(Redis 7.2)命令限制某些命令不会被复制MOVE、SWAPDB 和 RESTORE 会被拒绝(Redis 7.2)连接对等端时会拒绝 FLUSHALL 和 FLUSHDB(Redis 7.2)运行风险Active-Active 要求各数据中心的时钟保持同步(Redis 7.2)提供的上游实例地址必须具备高可用性仅支持 IP 连接地址(Redis 6.0)复制会增加存储压力——建议使用本地 SSD对于复制实例,建议使用 RDB 参数模板升级运行中的组时先升级下游,再升级上游上游故障后,先断开与其的连接停用对等端不可逆Mesh 成员移除不会自动编排(Redis 7.2)Mesh 调优值会保持不变(Redis 7.2)拓扑限制
复制组两端必须运行相同的 Redis 版本
Redis 6.0(legacy module)与 Redis 7.2(new module)之间的复制不是设计支持的路径——两代 module 的协议不兼容。复制组中的每个成员都必须运行相同的 module generation。有关如何将现有组迁移到不同 generation,请参阅将 Disaster Recovery Group 从 Redis 6.0 升级到 Redis 7.2。
在 new module 中,复制组的所有成员还必须运行 Alauda Cache Service E1 v5.1.0 或更高版本。不支持 v5.1.0 成员与更早版本构建之间的链接。
两端的实例必须具有相同的架构
数据基于 Oplog 进行同步。Oplog 上下文具有相关性和幂等性,Oplog 数据无法重新分片并提交到不同的分片。此限制要求:
- Sentinel 实例的下游端只能是 Sentinel 实例。
- cluster 实例的下游端只能是 cluster 实例。
- cluster-mode 下游的分片必须与上游一致。
- cluster-mode 下游的 slot 分布必须与上游一致。
- cluster mode 不支持通过在线同步来增加或减少分片。
一个复制组最多包含 16 个成员
由于 service_id 的范围限制为 [0-15]:
- 在 Disaster Recovery 模式下,一个上游最多可以有 15 个下游实例。不支持级联——仅支持星型分布,不支持树型或环型链接。
- 在 Active-Active 模式下,一个组最多可以包含 16 个成员。
Active-Active 模式仅在 Redis 7.2 上可用
在 Redis 6.0 上,Active-Active 模式会被准入检查拒绝。两个版本都支持 Disaster Recovery。
一个实例最多保持一个上游连接
一个实例最多可以有一个 ActiveRedisConnection——即其自身的上游链接。通过在每个下游 cluster 中创建一个指向同一上游的连接来构建扇出。
配置限制
无法关闭复制,且无法更改 Service ID
启用复制后,模块会在 Redis 持久化 RDB 文件中写入 AUX 信息记录,例如相应的 offset 和 oplog id;同时,Redis 实例的主从同步中还包含特殊的同步指令。因此,为确保数据可靠性和集群可用性,模块启用后无法卸载。
出于同样的原因,spec.activeRedis.serviceID 在创建后不可变更。删除 spec.activeRedis 和更改 serviceID 都会被准入检查拒绝。
不支持 AOF 持久化(Redis 7.2)
新模块仅支持 RDB。其 CRDT 元数据和 Oplog 恢复偏移量只会持久化在 RDB 辅助部分中,而 AOF 无法携带这些信息。设置 appendonly: "yes" 会被准入检查拒绝;如果该参数以某种方式在运行时被设置,模块会将节点置于降级只读状态,在此状态下所有写入都会被拒绝——包括本地应用写入和来自对等端的复制写入。
请使用 RDB 持久化,并参阅推荐的 RDB 参数模板。
最多 16 个数据库(Redis 7.2)
customConfig.databases 必须为 <= 16。模块的数据库寻址使用 4 位,因此拒绝加载超过 16 个数据库,否则 Pod 将陷入崩溃循环。此配置会被准入检查拒绝。
连接名称必须是有效的模块对等端名称(Redis 7.2)
ActiveRedisConnection 名称会原样用作模块的对等端名称,其命名规则比 Kubernetes 更严格:必须以字母开头,并且 reset、clear、all 和 list 为保留字。违反任一规则的名称都会被拒绝。
命令限制
命令支持是完整参考——其中说明了哪些命令会返回错误并被拒绝,哪些命令仅在本地执行且永不复制,哪些写入命令会被复制以及每个命令如何解决冲突,还说明了旧版 Redis 6.0 模块有哪些不同之处。本节仅列出会影响部署的限制。
某些命令不会被复制
发布/订阅(PUBLISH/SPUBLISH 以及 SUBSCRIBE 系列)、所有 stream 命令(包括所有消费者组操作),以及集群重新分片命令对 MIGRATE/RESTORE-ASKING,都会在本地节点执行,且永不复制。每个数据中心中的相关状态彼此独立,也不会返回错误。如果需要跨数据中心的发布/订阅或 streams,请使用消息队列组件。
在 Redis 7.2 上,为 stream key 设置 TTL 也会被拒绝,因为复制过期操作会删除对等端上彼此无关的本地 streams。
MOVE、SWAPDB 和 RESTORE 会被拒绝(Redis 7.2)
新模块会直接拒绝这三个命令——在灾难恢复和 Active-Active 模式下均如此——因为无法使它们的效果在各个对等端之间最终一致。使用这些命令的应用必须在实例加入复制组之前完成修改。请参阅返回错误并被拒绝。
旧版 Redis 6.0 模块不会拒绝这些命令。
连接对等端时会拒绝 FLUSHALL 和 FLUSHDB(Redis 7.2)
清空操作仅在本地执行,且永不复制。由于在运行中的复制组内执行清空操作会使节点与其对等端无提示地发生不一致——并且会丢弃该节点已删除 key 的墓碑,从而使延迟到达的对等端写入仅在该节点上复活已删除的 key——因此,当节点连接了任何对等端时,新模块会拒绝 FLUSHALL 和 FLUSHDB。
要清空复制组,请移除连接,在每个已隔离的实例上执行清空操作,然后重新创建连接。或者,重新创建实例。
旧版模块没有此保护机制:它会复制 FLUSHALL 和 FLUSHDB,因此在 Redis 6.0 上游执行清空操作时,也会清空每个下游实例。请参阅 Redis 6.0 — 旧版模块。
运行风险
Active-Active 要求各数据中心的时钟保持同步(Redis 7.2)
冲突解决依据墙上时钟时间决定,墓碑的保留下限也按墙上时钟时间计算。时钟超前的成员会悄无声息地赢得本应失败的冲突,而接近 150 秒的时钟偏差可能导致已删除的元素重新出现。模块会测量时钟偏差并针对偏差发出告警,但绝不会阻止写入,也不会丢弃对等端——同步时钟是 operator 的责任。
在 Active-Active 组中每个集群的每个节点上运行时间同步守护进程(ntpd、chronyd 或平台等效项),并监控告警。有关测量方式、两个告警级别以及如何确认某个特定问题由时钟偏差导致,请参阅时钟同步。
提供的上游实例地址必须具备高可用性
代理地址本身不具备高可用性。如果通过 NodePort 暴露代理,请将其置于前端负载均衡器之后以确保 HA;或者使用 MetalLB 为代理提供高可用虚拟 IP。
在 Redis 7.2 的 Active-Active 模式下,该地址必须暴露代理 Service 发布的每个端口,且每个端口使用其自身的编号。Mesh 会通过模块自行固定并原样通告的端口访问成员,因此重新映射该端口会破坏 gossip。灾难恢复链接仅使用 RESP 端点。
仅支持 IP 连接地址(Redis 6.0)
下游实例连接时,仅支持 <ip:port> 连接;旧版模块不支持域名。
在 Redis 7.2 的 Active-Active 模式下,建议将 DNS 名称用于通告地址和种子条目,因为模块会在每次拨号时重新解析该名称。
复制会增加存储压力——建议使用本地 SSD
启用复制的实例会实时将 Oplog 写入存储(每秒执行一次 fsync);当 Oplog 达到限定大小(3 GB)时,Oplog 文件会被截断;清理逻辑会定期标记未使用的 Oplog 分片文件并及时将其清理。因此,上述过程会同时产生 Oplog 读写和 RDB 生成的存储开销,从而增加存储压力。建议使用本地 SSD 作为存储,以确保持久化性能。
对于复制实例,建议使用 RDB 参数模板
使用 RDB 参数模板并结合 save 参数,可以主动触发快照并主动触发 Oplog 清理,从而确保新的下游实例连接能够快速同步快照。
在 Redis 6.0 上,如果使用 AOF 参数模板,仍需设置 save 参数以确保定期进行 RDB 持久化,从而提高本地数据的可靠性;但同时启用 RDB 和 AOF 持久化会对存储提出更高的性能要求。请确认使用本地 SSD 作为存储。
在 Redis 7.2 上,完全不支持 AOF——请参阅 不支持 AOF 持久化。
升级运行中的组时先升级下游,再升级上游
升级正在进行复制的组的 Redis 版本时,应先升级下游实例。下游可以应用版本相同或更旧的上游 Oplog,但不能应用版本更新的 Oplog。在运行中的下游之前提升上游版本会返回准入警告,模块会保持受影响的边——到下游的复制会暂停,直到版本偏差得到解决。通过 versionState 和 versionHoldSince 可以在连接状态中看到处于保持状态的边。
上游故障后,先断开与其的连接
上游发生故障后,在执行故障转移之前,首先应断开下游与上游之间的同步链接,以防上游突然恢复并携带错误数据,从而污染下游。
停用对等端不可逆
spec.teardownPolicy: Decommission 会永久释放为对等端保留的 Oplog 保留、墓碑垃圾回收和堆积量统计下限。该操作无法恢复为 Detach,之后重新返回的已停用对等端会被视为全新的对等端,需要进行完整同步。仅当某个数据中心永久停用时,才应使用此操作。
Mesh 成员移除不会自动编排(Redis 7.2)
没有资源级编排机制来忘记或解除对已离开的 Mesh 成员的封禁。其记录会根据模块自身的计时器从存活成员的成员列表中过期移除,在此期间,Mesh 阶段可能报告 Degraded。
Mesh 调优值会保持不变(Redis 7.2)
只有大于零的 spec.tuning 字段才会推送到节点。清除之前设置的字段不会重置已配置的 pod——它们会保留上一次的值,直到重启。