知识卡片

回滚兼容性的三条秘籍

结构图卡

内容

服务必须对回滚提供支持,这一点不允许商量——但现实中团队总能找到各种理由说”这次改动回滚不了”,其中三类理由最常见,也都有对应的解法。理由一:数据改动之后格式跟以前不兼容了,回退也不能正常工作。秘籍:设计开发时就要考虑好兼容性问题——比如数据库改字段这种操作就不要做,改成”另加一个字段”;数据存储格式最好采用支持数据版本、支持前后兼容的方案;最差情况下,也要在变更实施之前想清楚数据兼容性问题,没有回滚脚本就不给更新,起码做到有备而战。理由二:变更删掉了东西,回退之后数据也没了。秘籍:把”删除”这个操作拆成两个阶段——第一阶段只是禁止访问这份数据(不是真的删除),等发布之后确认真没问题了,再发布第二阶段,第二阶段才真正删掉数据;这样第一阶段实施之后如果需要回滚,还能回得去,因为数据其实还在。理由三:变更发布后,其他依赖这个系统的下游都拿到了新格式的数据,即便回退了,下游也不再接受老数据了。秘籍:这种错误常出现在配置管理、缓存这类系统里,最重要的应对是开发一种和版本无关的刷新机制,触发刷新的机制要独立于发布过程,要留一个能强制刷新数据的手段——让下游能随时被动或主动地对齐到”当前实际应该是什么状态”,而不是死死绑定在”上一次发布产生的格式”上。这三条秘籍号称覆盖了100%的回滚兼容性问题:核心思路都是把一次不可逆的变更,拆解或改造成一个可以安全地”往前滚也能往后滚”的过程——回滚兼容性从来不是运维单独能解决的问题,只有开发和运维都真正意识到这个问题的严重性,才能从整体上解决它,而解决不了回滚难题,就不可能真正达到高可用。

结构图

flowchart TD
    A["回滚不了的三类常见理由"] --> B["理由1:数据格式变更不兼容"]
    A --> C["理由2:变更删除了数据"]
    A --> D["理由3:下游已消费新格式数据"]
    B --> E["秘籍1:设计时预留兼容性\n加字段而非改字段/支持数据版本"]
    C --> F["秘籍2:拆两阶段\n第1阶段仅禁止访问\n第2阶段才真正删除"]
    D --> G["秘籍3:版本无关的强制刷新机制\n独立于发布过程"]

参考来源

- 位置:《高可用架构(第1卷)》第1章《高可用架构案例精选》"1.8 来自Google的高可用架构理念与实践"节,"1.8.2 高可用性方案"(源文件:_epub-src/OEBPS/Text/Chapter1_8_3.xhtml) - 结论依据:原文逐一列出三条"理由"和对应的"秘籍"("秘籍1:设计、开发时就要考虑好兼容性问题……秘籍2:段禁止访问这个数据。等到发布之后真没问题了,再来发布第2阶段,第2阶段真正删掉数据……秘籍3:开发一种跟版本无关的刷新机制"),并说明"以上3个秘籍覆盖了100%的回滚兼容性问题",直接支撑本卡片结论与结构图。 - 原始内容:秘籍1:设计、开发时就要考虑好兼容性问题!!!比如说数据库改字段的事就不要做,改成另加一个字段就好……秘籍3:这种错误经常出现在配置管理、缓存等系统中……最重要的就是,开发一种跟版本无关的刷新机制。