知识卡片

用轻量级库代替独立服务:Bada为何用Mnesia而非ZooKeeper

普通读书笔记卡

内容

ZooKeeper是分布式系统里存储元信息、做选主协调最常见的选择,但Bada选择了Erlang生态里的Mnesia而不是ZooKeeper,理由指向一个经常被忽略的选型维度:依赖的形态本身也是成本。ZooKeeper是一个独立的”服务”,一旦引入就意味着要额外部署、监控、运维一整套ZooKeeper集群,这套集群自身的可用性又成了整体系统可用性的一部分;而Mnesia是一个可以直接集成进代码里的”库”,不需要单独部署和维护额外的服务进程,使用起来更轻量、运维负担更小。此外Mnesia本身就是用Erlang开发、和Erlang生态高度集成,如果系统的其余部分也基于Erlang构建,选择同语言生态内的库自然能减少跨语言/跨进程通信的复杂度。Bada用Mnesia承担了两个职责:一是在选主过程中提供全局锁,二是保存元信息,且元信息不是集中存在单独的机器上,而是每个节点都各自部署一份Mnesia,这一点又呼应了[[对等结构与Meta/Data分离结构的取舍:Bada为何选择对等设计]]里”不设专门Meta角色”的整体设计思路。这个选型案例提示了一条通用的依赖评估原则:面对”要不要引入某个成熟中间件”的决策时,除了比较功能是否满足需求,还要认真权衡它是以”服务”形态存在(意味着额外的部署和运维成本)还是以”库”形态存在(意味着可以直接嵌入、成本更低)——当自身技术栈里已经有同等能力的轻量级库可用时,未必需要为了”业界标配”而引入额外的独立服务。

参考来源

- 位置:《高可用架构(第1卷)》第2章《高可用架构原理与分布式实践》"2.5 360分布式存储系统Bada的架构设计和应用"节,"2.5.7 FAQ"及"2.5.8 疑问与解惑"(源文件:_epub-src/OEBPS/Text/Chapter2_5_8.xhtml、Chapter2_5_9.xhtml) - 结论依据:原文说明"ZooKeeper是一个服务,而Mnesia是一个库,因此如果使用ZooKeeper,需要额外地维护一套服务。而Mnesia可以直接集成在代码里面,使用起来更方便……Mnesia和Erlang集成得更好",以及"mnesia对于我们的定位就类似于ZooKeeper。有2个用途,一是在选主过程中提供一个全局的锁,二是保存元信息",共同支撑本卡片结论。 - 原始内容:和Mnesia对比,ZooKeeper是一个服务,而Mnesia是一个库,因此如果使用ZooKeeper,需要额外地维护一套服务。而Mnesia可以直接集成在代码里面,使用起来更方便……mnesia对于我们的定位就类似于ZooKeeper。有2个用途,一是在选主过程中提供一个全局的锁,二是保存元信息。