知识卡片
用明确的数据源优先级,解决"多份数据副本谁说了算"的问题
内容
QConf客户端为了兼顾访问效率和容灾能力,实际上维护了不止一份配置数据:内存中的共享内存(访问最快)、通过网络从ZooKeeper获取的实时数据、以及落盘持久化的数据(用GDBM实现,只在机器重启且网络中断这种极端场景下才会被使用到)。多份数据副本天然带来一个问题:如果这几份数据在某一时刻恰好不一致,业务进程读取配置时到底该信哪一份?QConf给出的答案不是设计复杂的一致性协议去强行同步这几份数据,而是简单直接地定义清楚一条优先级顺序——共享内存优先于网络,网络优先于持久化配置,业务进程读取配置时严格按这个优先级来源查找,只有更高优先级的数据源不可用时才会退而求其次访问下一级。这个设计的合理性建立在对每种数据源”新鲜度”和”可用性”的清晰判断上:共享内存是本地内存访问,速度最快,且是Agent持续维护更新的最新状态,理应是第一选择;网络(直接从ZooKeeper取)是绝对权威的最新数据源,但访问代价比内存高,适合作为共享内存缺失时的补充;持久化配置只在机器重启、网络又恰好中断这种共享内存和网络都不可用的极端场景下才派上用场,属于最后的保底方案,不追求它的数据有多新,只求它”总归有一份能用的数据”。这个案例提示了一条应对多副本数据不一致问题的通用思路:并不是所有场景都需要靠复杂的一致性协议去强行让多份数据保持完全同步,当各份数据副本本身就存在明确的”访问速度”和”新鲜度可信度”差异时,简单地约定一条清晰的优先级顺序、让读取方总是优先访问最可信、最新鲜的那一份,往往就能用很低的复杂度换来足够好的正确性和可用性,只有在优先级最高的数据源确实不可用时,才需要接受用一份相对没那么新鲜的数据去兜底。
参考来源
- 位置:《高可用架构(第1卷)》第5章《运维保障》"5.1 360如何用QConf搞定两万台以上服务器的配置管理"节,"5.1.8 疑问与解惑"(源文件:_epub-src/OEBPS/Text/Chapter5_1_9.xhtml)
- 结论依据:原文说明"如果我们同时维护一份内存数据的话,同样有两个版本不同步的问题,有一个是优先使用的,就像我们现在的状况,共享内存>网络>持久化配置",直接支撑本卡片结论。
- 原始内容:直接使用配置文件会有访问效率的问题。现在使用这种方式,业务需要每次都从QConf读数据,当读取次数比较多时对业务进程的影响很大。如果我们同时维护一份内存数据的话,同样有两个版本不同步的问题,有一个是优先使用的,就像我们现在的状况,共享内存>网络>持久化配置。