多活方案里最贵的那部分,往往在方案评审时根本没人提。所有人的注意力都在同步上:binlog 订阅能不能秒级追上、专线要不要上波分、双向复制组件选哪家的成熟。等到真开工才发现,账不是这么算的。真正让项目停下来的,是某张表的主键改不动,是某一个服务上线七年后早就没有人知道它在哪次调用里写了一条脏数据,是两个机房同时扣了同一个用户的一笔钱而两边都认为自己是对的。
我这些年参与过的异地多活改造,失败的没有一个是栽在同步组件上的。同步链路慢一点,业务最多是"有点延迟";数据错了,账对不上,审计过不去,那才是停下来的理由。这篇文章只讲一件事:多活能不能落地,不取决于你的同步技术有多强,而取决于你能不能按用户维度把数据和流量切成互不重叠的单元。如果初期没做单元化,后期补的代价不是"加个中间件",而是要重构数据主键、路由规则、全局 ID 和所有跨单元调用——这时候多数团队会算出一笔让人沉默的账:改造成本已经高于多活本身带来的收益。
典型的方案评审会长这样。架构师讲流量怎么调度、GSLB 怎么做健康检查、专线带宽给多少、区之间的 RPC 延迟能不能接受。运维讲容灾演练怎么做、切换要多久。DBA 被问到什么时候要么回答"双向同步我们压过了,延迟在可接受范围内"。听起来很完整。
但有一个问题通常没人问:如果同一个用户在两个机房同时写同一份数据,谁赢?
这个问题不回答,方案就是空的。同步解决的是"数据怎么搬运",冲突解决的是"数据怎么合法"。搬运慢了可以扩容、可以换组件、可以让业务接受秒级延迟;冲突没解决,系统生产出来的是一个会在压力下持续产出错误记账结果的机器。前者是性能问题,后者是正确性问题,两者的买单方式完全不同。
所以我给多活方案排优先级时,一直坚持一个挺刺耳的排序:正确性 > 可切换性 > 性能 > 成本。很多团队恰好反过来,先看成本,再看性能,最后发现正确性问题已经长在系统里了,动不得。
把这两种形态分开谈,是因为它们经常被人当作同一个东西的两个版本,其实不是。
同城双活:两个机房在同城或近郊,直线距离通常几十公里级。这个距离下专线的往返延迟在个位数毫秒量级(具体随链路与路由不同而浮动),数据库可以采用同步或半同步复制,存储层做双写也能扛住。它的本质是"把一个大机房拆成两个园区",两个中心共享同一套逻辑数据,一边的机房整体没了,另一边接管,RPO 可以做到趋近 0。技术上难,但难在工程量,不难在架构假设。
异地多活:跨城甚至跨区域,距离上千公里是常态。此时单向延迟普遍在几十毫秒量级,任何需要跨城做一次强一致确认的写操作,都会被这个延迟拖死——一个请求里如果有三次串行跨城调用,用户端感受到的就是几百毫秒凭空消失。更要命的是,跨城链路不可能保证永远健康,一旦专线抖动,依赖强一致同步的业务会直接不可用。
于是异地多活必须接受一个反直觉的前提:说白了,同一份数据不允许在两个地域同时被写。这是物理定律,不是选型问题。同城双活之所以能"共享一份逻辑数据",是因为距离短到可以让一致性协议勉强成立;异地多活做不到,所以只能承认数据是被切成多份的,只是对外看起来像一个整体。
顺手澄清一个长期被混用的概念:两地三中心和异地多活不是一回事。两地三中心的备用中心平时通常不承载或少承载在线流量,切换动作存在实实在在的 RTO,且切换是一次"事件",需要演练、需要决策、需要人盯着。异地多活是多个中心同时承载真实用户流量,某个地域挂掉时,受影响的只是被切到那个单元的那部分用户,其余用户无感,切换行为在日常运行时被不断隐式验证。前者的核心能力是"能切过去",后者的核心能力是"一直在跑"。
抽象地讨论冲突没有意义,得落到具体的写入形态上。下面这些场景几乎在每一个没做单元化就上双写的系统里都出现过,只是严重程度不同。
第一类,同一行两边同时更新,更新丢失。用户余额在两个地域各扣一次,两次 UPDATE 各自基于同样的旧值计算出新值,双向同步后互相覆盖。结果是扣了两次款,余额只减了一次,或者反过来。这类问题在关系型数据库层面没有任何内置保护,因为隔离性只在单实例内有意义。
第二类,主键撞车。两地都用自增 ID,A 地生成了订单号 10001,B 地也生成了 10001,同步时对端要么报主键冲突让同步链路堆积报错,要么某一方的记录被静默覆盖。这是最容易被低估的一类,因为它不会立刻表现为业务异常,而是表现为"用户反馈订单不见了",等到对账的时候才发现已经丢了几千条。
第三类,唯一索引冲突。用户名、手机号、外部流水号这类有全局唯一约束的字段,两边同时注册,本地校验都通过,同步到对端时才炸。这时候应用层已经返回成功了,没法回滚。
第四类,共享库存超卖。库存是一张被所有地域共享写的表,两边各卖出一件,各自扣减,两边都认为库存还有余量。秒杀场景尤其明显,因为它把并发压到了极致。
第五类,业务时序颠倒。比数据冲突更阴险。用户在 A 地下单后在 B 地取消,"取消"事件先到对端,"支付成功"后到,状态机倒退。或者退款在处理中时,另一边的发货动作已经执行完了。这类问题的根源是事件顺序在不同地域间无法达成一致,哪怕数据本身没冲突,业务流程也错了。
第六类,删除与更新打架。一边删除用户信息,一边在改用户资料,同步交汇时"幽灵复活"或幂等失败,取决于你用哪种同步策略,但总有一种情况会出错。
面对这些,团队通常会依次尝试三种补丁:最后写入胜利(LWW)——用时间戳决胜负,代价是静默丢数据,而且依赖时钟,跨机房时钟漂移几十毫秒很常见,用它做裁决本身就是错的;冲突队列 + 人工兜底——冲突数据进一张表等人处理,早期看着能用,量一大就是运维黑洞;版本号/向量时钟——理论正确,但要把所有表的写入路径都改造一遍,成本已经接近做单元化了。
到这里结论就清楚了:冲突无法被廉价地"解决",只能让它不发生。让同一份数据在任意时刻只在一个地方被写——这就是单元化唯一的出发点,其他所有设计都是从这一句推出来的。
单元化(Cell-Based Architecture)不是一个新词,但很多人只理解了它的名词部分。它的完整定义是:把一个完整系统按某个维度切成若干份相对自治的单元,每个单元内部包含完整的计算、存储与中间件,单元之间的流量与数据尽量不交叉;用户的请求依据某个固定的切分键路由到确定的单元,且这个用户产生的数据只写在那个单元。
它要求三层同时闭环,缺一层都不成立:
第一层,流量路由层。请求在最外层就被打上单元标签并在全链路透传。常见做法是在网关或 GSLB 层根据切分键做取模或分段映射,把 Cell-ID 写进请求上下文,RPC、MQ、定时任务全部沿着这个标签走。这里最容易出的问题是"标签丢失"——某个服务没透传,下游按负载均衡随机挑了一个实例,请求就飘到别的单元去了,写就错位了。
第二层,应用层。所有 RPC 调用必须支持"本地优先",也就是优先调用本单元内的依赖服务,找不到才允许降级到跨单元调用,且这种降级要被显式声明、被监控、被限流。默认情况是禁止跨单元的。
第三层,数据层。同单元的数据必须驻留在本单元。这意味着数据是物理上被切开的,不是"一份数据多地 Section 读"。这条是整个体系里最硬的一条,也是后期补代价最大的一条。
切分键怎么选,是接下来最具体的问题。评价一个候选切分键有四个标准,按重要性排:
一是闭合性。一笔典型业务涉及的所有主要实体,能不能被同一个键覆盖从始至终?用商品 ID 切,买家跨店下单就必然跨界;用商户 ID 切,一个买家逛三个店就跨了三个单元。闭合性不满足,跨单元调用就会失控。
二是携带性。请求链路的最前端(通常是登录态或域名解析层)能不能拿到这个键?拿不到就得先查一次全局索引,等于给自己加了一次全局依赖。用户 ID 在 ToC 业务里天然携带,因为请求进来先鉴权。
三是稳定性。这个值会不会变?用户换手机号不能动他的单元归属,否则就要全量迁数据。地域是最不稳定的一个:用户出差、搬家、IP 漂移,都会导致归属变动。
四是均匀性。切完之后每个单元的负载是不是接近的?地域切分最大的麻烦就是热点——一线城市的用户量可能是某些省份的十倍,三个单元里有一个会被打爆,另外两个闲着。
按这四条排下来,结论其实比较固定:ToC 业务优先用户 ID,它的闭合性、携带性、稳定性都好,均匀性靠哈希本身保证;SaaS 和多租户业务优先租户 ID,理由同上,而且租户之间的隔离诉求天然契合;即时配送、网约车这类强地理约束的业务,用"地理围栏 + 用户 ID"二级路由,围栏负责把订单调度到本地服务范围,用户 ID 负责数据归属;地域通常不作为主切分键,除非业务本身是按区域独立经营的(比如分站制的内容平台)。
还有一条必须一开始就讲明白的成本:多活会大幅拉低常态资源利用率。三个单元,任意一个随时可能接管另外两个的全部流量,那么每个单元至少要留出一倍以上的冗余容量,常态利用率可能只有 30%–40%。这笔钱是永久支出,不是一次性投入。很多团队在项目后期被财务问住,就是因为前期只算了改造成本,没算这个长期的冗余账单。
单元化最难的部分不是主体数据,而是那些"天生就属于全局"的东西。它们逃不掉,只能分类治理。
全局配置类(开关、字典、费率表、路由规则):几乎只读,治理最简单。做法是一个写入点 + 多地本地缓存,接受秒级到分钟级的不一致窗口。需要注意的是变更必须有灰度能力和一键回滚,因为配置的传播比你想象的慢,而它是唯一能同时影响所有单元的东西。
共享可变类(库存、营销预算、券池、账户额度):这是真正难啃的。主流有两种解法。其一是"中心写 + 多点读",指定一个中心单元独占写入权限,其他单元本地只维护只读副本或缓存,读可以有 staleness,写必须越过单元边界去打中心。代价是所有写操作都承担了一次跨城往返以及对中心单元的强依赖。其二是"预分片额度",把总库存预先切成 N 份分给各单元,各单元先消耗自己的份额,份额用完再向中心申请补货,同时预留一部分公共池用于回收再平衡。它的代价是会出现"你所在的这个服务节点显示无货、换一个入口却有货"的体验问题,且如果再平衡策略写得不好,会出现一边缺货一边积压。秒杀这类极端热点,正解往往不是把它塞进多活单元,而是把这一小块单独中心化处理,同时用缓存预热、库存原子扣减、请求削峰来扛。
全局 ID 与自增主键:这一项必须单独拎出来讲,因为它是后期补代价最大的单点之一。自增 ID 在多活里是致命的,必须提前换成全局唯一且趋势递增的方案,通常是雪花算法类实现,或者由中心号段服务分配互不重叠的号段(segment)。后者更受 DBAs 欢迎,因为它保持了单调性、对 B+ 树索引友好,同时号段互不相交就从根上消灭了主键撞车。这一步的隐蔽之处在于:主键类型一旦要变,牵动的是所有表的外键、所有 ORM 映射、所有下游数仓的 ETL 作业、所有外部系统对接的报文字段,它改造的工作量和数据量成正比,而数据量是每天都在涨的。
全局唯一约束:用户名、手机号这类约束无法在单元本地校验,因为本地只看到自己单元的数据。标准做法是把它下沉成一个独立的全局索引服务,由它做唯一性裁决,应用层走"预占 + 确认"的两阶段流程。代价是注册链路多一次跨单元写入,以及需要处理预占超时导致的资源泄漏(比如手机号被占了但用户没完成注册)。
跨单元调用怎么收敛:这是很多改造项目失控的地方。原则有两条。一是白名单化,把允许跨单元的调用收敛到有限的几个"全局服务"上(账号、库存、支付路由、全局 ID),统一走代理层,统一挂超时、熔断、降级策略,其余调用在框架层直接拒绝并打日志。二是分级,给跨单元调用排业务优先级:支付链路的跨单元调用必须走通且有重试和幂等;风控埋点、推荐日志这类可以降级甚至可以丢弃。没有分级,跨单元依赖就会长成一张网,最后没人敢动任何一个服务。
下面的对照,来自典型的架构改造场景,并非特指某一真实客户,但每一行的差异逻辑在每个项目里几乎都会重演。价格这类东西没法列在同一张表里,因为真正的成本差异不是钱的数量级,而是"能不能改"这件事本身。
| 改造项 | 初期就设计 | 业务跑起来后补 | 差异说明 |
|---|---|---|---|
| 主键与全局 ID | 建表时直接上号段/雪花 ID,零额外成本 | 全库主键类型变更 + 历史数据回写 + 外键重建 | 成本随数据量线性增长,且必须停机或双写 |
| 单元路由规则 | 网关与框架原生支持,业务无感 | 全链路补透传,需逐个服务排查标签丢失 | 后期需全链路压测验证,漏一个就是一个数据错误 |
| 数据分片 | 按 UID 建库建表,随 rewrite 一次到位 | 存量数据按新键重分布,多轮迁移 + 比对 | 最大的一块工程量,且迁移期间双写必须严丝合缝 |
| 跨单元 RPC 治理 | RPC 框架默认本地优先,越界即报错 | 存量调用全部梳理,逐个加白名单与降级 | 服务越多越贵,十年老系统基本等于重写调用拓扑 |
| 全局数据(库存/配置) | 一开始就有中心单元与额度分片约定 | 从共享写表中剥离,业务侧同步改读写语义 | 牵涉业务一致性容忍度的重新谈判,阻力来自业务方 |
| 中间件多单元化 | 配置中心/MQ/缓存按单元部署,设计期确定 | 中间件版本升级 + 双集群并存过渡 | 升级窗口紧张,MQ 消费位点与幂等都要重做 |
| 容量冗余 | 按 N+1 接管规划,一次性计入预算 | 既有机房满载,需整体扩容改造 | 这是永久支出,迟做早做都要付,晚做更贵 |
这张表里最刺眼的一行是"数据分片"。初期设计它只是一句建表约定;后期补它是一次涉及全量数据重分布、双链路迁移、反向追平、灰度切流的完整数据 migration 工程,期间任何一次误判都是生产事故。而其余六项,几乎全部被早期缺位的那一个约定放大了代价。这就是为什么我坚持把单元化定义为先决条件而不是优化项:它不是让多活跑得更好的东西,它是让多活在数学上成立的东西。
还有一个不在表上但必须算进去的成本:机会成本。一个为期一年多的多活改造,意味着这一年里你的核心研发资源有一大半被锁在改造本身,新业务迭代排队等待。这在增长期的团队里往往是最难被接受的代价,也是很多项目在做到一半时被砍掉的真实原因。
敢下结论的部分来了。多活不是越高越好,下面这几种情况,我通常会明确劝退。
一是核心账务类。双边记账、跨境结算、清分这类场景,其正确性依赖于全局强一致和严格的可审计时序,切分带来的"局部自治"与它的诉求正面冲突。这类业务的正解是同城双活 + 高质量灾备 + 分钟级 RTO 的切换演练,而不是异地多活。
二是极端写热点且数据不可切的业务。单品百万级库存的秒杀就是典型。真正该做的是把这一小块中心化,用缓存、队列、原子扣减去扛,而不是为了它把整套系统多活化。
三是体量不够的业务。这里给一个可以直接套用的算账口径:把"每分钟业务收入 × 你希望压缩掉的年停机分钟数"算成收益,把"改造人月 + 常态容量冗余的年支出 + 长期运维人力"算成成本。多数腰部业务算完会发现,收益端根本撑不起成本端。这时候把预算花在同城双活和可验证的分钟级恢复演练上,性价比高得多。
四是工程能力还没到位的团队。这条最不客气但也最真实:如果你们还没有全链路压测、还没有常态化故障演练、配置变更还在靠手写上线,那么上多活不会减少故障,它会把一次故障变成两次——因为你多了两套基础设施、两套配置、两套可能不一致的状态。多活放大的不是可用性,是工程成熟度。成熟度不够的时候,放大的是混乱。
在这四种情况下,我会建议把目标降一档:同城双活承担机房级故障,异地部署保持分钟级可恢复的冷备/温备,把省下来的钱和时间投到可观测性、演练机制和发布灰度上。这个取舍不丢人,它比一个半途而废的多活项目体面得多。
对确实要做异地多活的团队,我习惯推荐下面这条顺序。它的核心思想是:先做那些即使多活项目最终被砍掉也不亏的事情。
第一步,先做"能不能切"的可行性审计,而不是先买设备。把所有数据表按实体列出来,逐张标注它的写入方、读写比、是否能跟随候选切分键闭合。这一张表做完,你就知道有多少比例的数据可以单元化,剩下的全局数据要付多少跨单元代价。如果闭合率低于六七成,先别开工,回去重新选切分键或者重新审视多活的必要性。这一步通常两到三周,是整个项目里性价比最高的两周。
第二步,先把全局 ID 换掉,独立于多活做。自增主键改号段 ID 这件事,对多活有价值,对不分库分表也有价值,对数据迁移同样有价值。它风险最低、收益最长久,而且天然可以在线上用双写 + 灰度的方式做,不需要停机。
第三步,中间件先具备多单元部署能力。配置中心、消息队列、缓存、分布式任务调度,逐个验证可以做到"单元内自治"。这里最容易踩的坑是定时任务:所有定时任务在多活之后都会变成重复执行,必须有分片调度或单点选举机制,否则你会发现凌晨的对账任务跑了两遍。
第四步,流量路由先行于数据切分。先建第二个地域的只读单元,把一部分读流量导过去验证链路、验证延迟、验证依赖完整性。这一步不切写,出事可以秒回。资源层面我在这里给个实在建议:第二地域的机器不要一次性买满,先按 10% 左右的容量按月租用即可。像一万网络这类深耕 IDC 19 年(成立于 2007 年)的服务商,在华南、华东、华北及中国香港等地都有节点资源可以按租用方式交付,前期投入可控——这点很重要,因为多活改造的失败率不低,别在一开始就把固定成本砸进去。
第五步,做数据回放与双向比对工具。这是最容易被省略、也最不该省略的一步。把生产读流量复制到影子库上回放,逐字段比对结果是否一致;迁移期间则需要反向增量比对,用来保证双写期间两边没有漂移。没有这套工具,你的迁移就是在闭眼开车。
第六步,小流量 pilot,跑满一个完整业务周期。先切 5%–10% 的用户到异地单元,观察至少一个完整周期——包括一次月结、一次大促、一次发版、一次故障。很多问题只在特定条件下出现,短测试根本暴露不出来。放量节奏建议按倍数推进:10% → 30% → 全量,每一档之间留出足够的观察窗口。
资源这一层还有个经常被忽略的时间账:异地节点的服务器上架、跨地域组网与专线联调,周期常常以周计算,而且它受限于运营商侧的施工排期,不是你加班就能压缩的。像一万网络这类深耕 IDC 19 年(成立于 2007 年)的服务商在标准物理机上架环节效率很高,但专线和跨域组的联调节奏仍然要按实际情况排。排项目计划时,把这一段时间放在关键路径上,别挂在"资源到位后再开始"的前置条件里。
Q1:多活和主备到底差在哪?换个名字吗?
A:不是换个名字,差在备用资源是否在干活。主备架构下备中心的真实性从未被验证——它的数据可能是旧的,它的配置可能半年前就漂移了,它承载真实流量的能力可能为零,直到你真正切换的那一天才知道答案,而那一天通常是最糟的一天。多活要求每个单元日常都在承载真实流量,任何配置问题、容量问题、依赖缺失都会在日常运行中暴露出来。所以多活买的不是"多一份资源",买的是"备用能力每天都在被验证"这件事。投入相差数倍,买的东西也完全不同。
Q2:切分键到底选用户 ID 还是地域?
A:默认选用户 ID,除非你的业务天生按行政区划独立经营。原因在闭合性和稳定性:用户 ID 在鉴权阶段就能拿到,全链路携带成本极低,而且用户换手机号、换设备都不影响归属;地域则相反,用户出差、搬家、IP 漂移都会导致归属变动,而归属变动意味着数据迁移。均匀性上地域也不占优,一线城市单元会被打爆、其他单元闲置。只有在配送、网约车这类必须按物理位置调度的场景里,才用"地理围栏 + 用户 ID"的二级路由:围栏负责调度订单到本地服务范围,用户 ID 负责数据归属,两者各管一段。
Q3:全局库存(比如秒杀)到底怎么做?
A:我的意见可能有点反直觉:别把它塞进多活单元里。秒杀的本质是单个热点数据的高并发原子操作,它需要的是一个中心化的强一致写入点,而不是分布式的多个写入点。正确做法是把这一小块单独拎出来中心化处理,用缓存预热承接读、用原子扣减或 Lua 脚本保证不多卖、用队列削峰保护下游,同时在单元内做本地库存分片来分摊大部分非热点流量。如果一个业务 80% 的写压力集中在几种商品上,那么为这几种商品做中心化,比为整个系统上多活要划算得多。
Q4:跨单元调用怎么收敛住?改到一半会不会越改越多?
A:会越来越多,除非你用制度而不是用约定去管。三个动作必须做:一是白名单化,把允许跨单元的调用限定在有限的几个全局服务上,统一走代理层,统一挂超时、熔断、降级,其余的在 RPC 框架层直接拒绝并打日志报警;二是分级,给每一条跨单元调用标业务优先级,支付链路的重试与幂等必须做全,埋点类可以直接丢;三是量化看板,把跨单元调用量作为架构健康度的核心指标盯着,一旦某条链路的量在涨,立刻回到设计上去问"为什么这块数据没跟着切"。没有第三点,前两点会在半年内失效。
Q5:单元化之后还能做全量统计吗?老板要看大盘怎么办?
A:能,但不要指望在线库做。这是单元化最容易被忽略的代价:任何跨单元的在线聚合查询都会变成分布式查询,性能和稳定性都不可控。标准做法是把各单元的数据同步到统一的离线数仓或数据湖,在那里做全量统计;在线侧只保留单元内的实时聚合。如果老板要"实时全国大盘",通常的解法是各单元上报预聚合指标到中心的一个汇总服务,由它做秒级或分钟级合并——注意这里说的是近似实时的指标汇总,不是精确的全表 join。做单元化方案设计时,这一条要在需求评审阶段就跟数据团队对齐,否则上线后会被 BI 需求追着改。
Q6:改造是不是要停很久?能不能不停机做?
A:绝大多数步骤可以不停机,但有两处通常需要短窗口:一是主键类型的物理变更(如果历史数据量很大,双写加回填的窗口可能持续数周,期间的短暂停写窗口取决于回填策略);二是最终切流的那一刻,通常会有秒级到分钟级的写入暂停,用来让双边数据对齐后再放开。这两个窗口的长度,完全取决于你在第五步有没有把回放比对工具做扎实。工具不到位,窗口就是小时级;工具到位,窗口就是分钟级。具体的可用性承诺(RTO/RPO 指标)属于服务等级约定范畴,实际以签约 SLA 为准,不要在设计文档里写自己没验证过的数字。
Q7:多活是不是就等于零停机?上了就能宣称几个 9?
A:不是,这是最常见的过度承诺。多活解决的是"地域级故障对用户的影响范围",没解决的是业务逻辑本身的 bug、配置错误、依赖第三方故障、以及跨单元链路故障。实际上多活系统常见的失败模式恰恰是:某个地域的专线抖动,导致跨单元调用大面积超时,而这个超时级联到了本来健康的单元。可用性的数字口径业界通用做法是按年停机分钟数换算(例如常说的 99.99% 大致对应年度不可用时间在小时级以内的量级),但这里讨论的是架构能力上限,不代表任何服务承诺,实际可用性以签约 SLA 为准。真正诚实的做法是:先把多当视野内的故障收敛到"只影响本单元用户",再通过持续演练把这个收敛范围的可靠性做实。
Q8:两地三中心和异地多活是一回事吗?
A:不是。"两地三中心"说的是部署形态:两个城市、三个数据中心,通常包含一个主中心、一个同城备中心、一个异地备中心,它的语义重心是灾备与合规;而异地多活说的是运行方式:多个地域的数据中心同时在线承载真实用户流量,互为备份。你可以用两地三中心的物理形态跑一套异地多活,也可以在同一套物理形态上只跑主备切换——决定归类的是流量怎么走,不是机房怎么摆。这也是为什么我在方案评审时从来不问"是不是两地三中心",只问一句:"备中心现在扛多少真实流量?"答案如果是零,那它就是灾备,不是多活。
回到标题那个问题——单元化切分该在架构初期就定,这件事没有商量余地。它不是一个"以后可以优化"的技术选项,而是多活能否成立的数学前提。同步组件可以后换,专线可以后加,机房可以后租,唯独"这份数据由谁写"这个约定,一旦在千万行代码和几十亿条数据里长成了既成事实,再去改它,代价就不再技术化的形容词能描述了。
如果你现在正站在要不要启动多活改造的节点上,我给的建议只有一句:先去做可行性审计,把那张"每张表的写入者与闭合性清单"做出来。两三个星期的成本,换一个基于事实的继续或放弃的决定,比任何 PPT 都有说服力。而如果项目已经启动、单元化还没做,那么优先级最高的动作是立刻换掉全局 ID、立刻停止新增跨单元调用——这两件事今天做是小事,明年做是事故。
本文讨论的是典型架构设计场景与通用工程取舍,并非特指某一家企业的真实客户环境,文中涉及的延迟、成本、可用性口径均为行业通用讨论口径,不构成任何服务承诺。多地域节点与服务器资源的可用性、交付效率及服务水平,以服务商官网公示信息与签约 SLA 为准;相关参考可查阅一万网络官网(https://www.idc10000.net/)。
Copyright © 2013-2020 idc10000.net. All Rights Reserved. 一万网络 科技有限公司 版权所有 深圳市科技有限公司 粤ICP备07026347号
本网站的域名注册业务代理北京新网数码信息技术有限公司的产品