知识卡片
异步双写:用"下次操作自动覆盖补全"把偶发丢数据概率降到接近于零
内容
购物车这类高频写入的场景,如果每次写操作都强同步等待所有副本写成功才返回,性能代价太高;改成异步双写又要面对”某次异步写失败、数据永久丢失”的顾虑。京东购物车给出的解法是承认单次异步写确实可能失败,但依靠购物车数据本身的一个特性——它是一个不断被同一用户反复操作、整体覆盖式更新的数据(每次操作购物车,写入的都是当前购物车的完整状态,而不是增量修改)——把”偶发写失败”的影响自然抵消掉:假设第一次操作时异步写失败了,只要用户后续还会继续操作购物车(这在电商场景下几乎必然发生),下一次操作写入的数据本身就是包含了上一次和这一次全部变更的完整状态,会把之前那次失败、没写进去的状态一并覆盖补齐,不需要任何额外的重试或补偿机制介入,异步丢数据的概率因此被自然摊薄到”基本不会产生”的程度。这个案例给出了一条应对异步操作可靠性问题的巧妙思路:不是所有场景都必须靠精细的重试、确认、补偿机制去堵住每一次异步失败的窗口,如果数据本身具备”后续操作会整体覆盖前面状态”这种天然的自我修复特性,那么单次异步失败造成的影响会被后续的正常业务行为自动吸收——识别并利用这种数据本身的幂等/覆盖特性,往往比额外叠加一套复杂的补偿体系更简单、更低成本。
参考来源
- 位置:《高可用架构(第1卷)》第3章《电商架构热点专题》"3.2 大促系统全流量压测及稳定性保证——京东交易架构"节,"3.2.5 应对大促的第2步:根据压力表现进行调优"(源文件:_epub-src/OEBPS/Text/Chapter3_2_6.xhtml)
- 结论依据:原文说明"这里有一个异步双写,在实际情况下,我们可能会写丢这个数据,不过没关系,购物车的存储是一个整体,如果在操作第一下时,异步写失败了,下次再操作的时候会把上两次都写过来,全部覆盖。这样异步丢数据的概率就会大大降低,甚至基本不会产生",直接支撑本卡片结论。
- 原始内容:这里有一个异步双写,在实际情况下,我们可能会写丢这个数据,不过没关系,购物车的存储是一个整体,如果在操作第一下时,异步写失败了,下次再操作的时候会把上两次都写过来,全部覆盖。这样异步丢数据的概率就会大大降低,甚至基本不会产生。