Redis主从复制怎么做到多活分布式服务,聊聊它的那些功能和用法
- 问答
- 2026-01-19 00:01:32
- 3
Redis的主从复制本身是一个“一主多从”的结构,它的核心设计初衷是为了数据备份和读写分离,实现高可用,但它本身并不是一个严格意义上的“多活”架构,你问的“多活分布式服务”,更准确地说,是业界基于主从复制的思想,通过一些额外的技术和架构设计,来实现类似多活或者更高级别的分布式服务能力,我们来聊聊这个过程的演进、相关的功能和用法。
基础:主从复制的核心工作方式
必须理解基础的主从复制是怎么一回事,想象一下,你有一个主要的Redis服务器(我们叫它主库),它负责处理所有客户端的写请求(比如新增、修改、删除数据),你可以配置一个或多个备用的Redis服务器(我们叫它从库),一旦配置好主从关系,从库会做以下几件事:
- 连接主库:从库启动后,会主动建立一个到主库的网络连接。
- 同步数据:连接成功后,主库会执行一个叫
BGSAVE的操作,也就是在后台把当前内存中的所有数据拍一个快照,生成一个叫RDB的文件,然后把这个文件发送给从库,从库会清空自己的旧数据,再加载这个RDB文件,这样就从零状态变得和主库数据完全一致了。(来源:Redis官方文档关于复制的说明) - 持续同步:在初始同步完成后,主库每当有新的写命令被执行,都会把这个命令本身(而不是数据结果)异步地发送给所有连接的从库,从库接收到命令后,会在自己的内存中重新执行一遍,从而保证数据实时更新,这个过程叫做“命令传播”。
用法:配置起来很简单,通常是在从库的配置文件(redis.conf)里加一行 replicaof <masterip> <masterport>,或者直接在从库运行时用命令 REPLICAOF <masterip> <masterport> 来指定它的主库是谁。

功能与局限:这个模式实现了数据冗余(一份数据在多台机器上有备份)和读写分离(读请求可以发给从库,减轻主库压力),但它的“活”是分主次的,只有主库能写,从库只能读,如果主库挂了,虽然数据还在从库上,但整个系统就失去了写能力,需要人工干预把某个从库“扶正”成新的主库,这就会有一段时间的服务不可用,这离“多活”还差得远。
迈向高可用:哨兵(Sentinel)机制
为了解决主库故障后自动切换的问题,Redis引入了哨兵。(来源:Redis官方文档关于Sentinel的说明)哨兵本身是一个独立的进程,你通常需要部署奇数个(比如3个或5个)哨兵实例来组成一个集群。

哨兵的主要职责是“监控”和“决策”:
- 监控:哨兵会不断地检查主库和从库是否在正常干活。
- 自动故障转移:如果大多数哨兵都认为主库“失联”了,它们就会集体投票,从剩下的从库中选举出一个新的主库。
- 通知:哨兵会通知客户端(需要有相应的SDK支持)主库地址发生了变化,让客户端连接到新的主库上去。
用法:你需要配置哨兵自己的配置文件(sentinel.conf),告诉它要监控的主库是谁,客户端不再直接连接Redis服务器,而是先连接哨兵集群,询问当前的主库地址是什么。
功能提升:哨兵模式实现了高可用,主库挂掉后,能在几十秒内自动完成切换,业务几乎无感知(取决于客户端重连机制),但这仍然是“主从”模式,只是实现了自动化的主备切换,写操作仍然集中在单一主节点上,不是“多活”。

挑战“多活”:更复杂的分布式方案
真正的“多活”(Multi-Active),指的是多个地点的数据中心或多个集群都能同时接受写请求,这对于基础Redis主从复制来说是极具挑战的,因为会引发严重的数据冲突问题,用户在A地写入X=1,同时在B地另一个主库写入X=2,那最终X应该是什么值?Redis内核本身不解决这个问题。
要实现类似多活的效果,通常需要站在更上层的架构层面来解决:
-
基于客户端分片(Sharding)的集群模式:这是Redis官方提供的分布式方案。(来源:Redis官方文档关于Cluster的说明)它把整个数据集自动分割成16384个槽位(slots),然后你可以组建一个由多个主节点组成的集群,每个主节点负责一部分槽位,每个主节点还可以有自己的从节点。
- 用法:数据根据key被散列到不同的槽位,进而被路由到对应的主节点上读写,客户端需要支持集群协议。
- 功能:这实现了水平扩展,写压力可以分散到多个主节点上,从某个角度看,每个主节点在自己的数据分片上是“活”的,可以视为一种“多活”,但它不是任意节点都能写任意数据,数据是分治的,所以通常不把它等同于跨地域的多活。
-
跨地域双向复制与冲突解决:这是实现业务层面“多活”的关键,业界有一些第三方工具和方案(比如基于Kafka等消息队列),可以在两个独立的Redis主从集群之间建立双向数据同步。
- 用法:A集群的写操作被捕获并发送到消息队列,然后被B集群消费并执行,反之亦然。
- 功能与挑战:这确实让两个集群都能写入了,但最棘手的就是数据冲突,解决方案通常很“业务化”,
- 最后写入获胜(LWW):给每个数据带上时间戳,只保留最新的。
- 自定义合并逻辑:对于像购物车这种数据,冲突时可能是合并商品项,而不是覆盖。
- 避免冲突:最常用的方法,通过业务设计让特定类型的数据只会在一个地域被修改(比如用户数据路由到其所属地域的机房)。
总结一下:Redis的主从复制是构建分布式服务的基石,它提供了数据同步的基本能力,通过哨兵,可以实现高可用的主备切换,而要迈向更复杂的“多活”分布式服务,则需要结合官方集群模式进行数据分片,或者利用更上层的架构和业务逻辑,来处理跨数据中心的双向复制和不可避免的数据冲突问题,它是一个从简单到复杂,根据业务需求不断演进的过程。
本文由雪和泽于2026-01-19发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:http://www.haoid.cn/wenda/83337.html
