etcd 有非常多的用户,全球有上万公司在用。但目前并没有文章在讲 etcd 的架构。一方面,业界中懂 etcd 的人都太忙了;另一方面,学术圈一般不会涉足这种应用。作者身处 CoreOS 虽地位卑微,但好在脸皮厚敢于胡说。这里写写自己对 etcd 架构疏浅的理解。尽己之力为这个领域贡献的同时望批评指教。
Chubby, Paxos Made Live
Google 公布出来的 Paxos 系统就有两套:Chubby [OSDI 06], Paxos Made Live [PODC 07]. 读这两篇 paper 的感觉就像我这村娃第一次进广州看到天上有辆直升机,那叫一个兴奋啊,从来没见过这样的高科技。
为什么要讲 Google 的系统呢?一方面,因为他们的设计直接影响了 etcd 的设计,paper 里的大家自读即可,不再累述;另一方面,通过对比,etcd 某些设计上的权衡会更显然。
storage layer
Chubby 的 storage layer 是典型的 database 架构:on-disk data + in-mem table + index files。因为大家想要做的是 replicated database。事实上这么做能利用起 database storage layer 的知识框架,这套理论历经千锤百炼,能够处理大规模的数据,还在不断发展。
Chubby 底层用的是 BDB,古董就不讨论了。后来出现的 Spanner 用了 LevelDB,现在开源的 Cockroach DB 和 TiKV 都用 RocksDB (LDB 一变种)。而 etcd 则用了 LMDB。这是因为前者的写数据量大,但是会牺牲读 throughput。而 etcd 需要更大的读 throughput,对写要求可以降低。其次,etcd 只需要维护一层的 file,可以假定 key space 不会超过 memory size.
然而即便如此,etcd 的写 performance 还是令人叹为观止:https://coreos.com/blog/performance-of-etcd.html
API
Chubby 的 90% use case 是存小数据 (<1KB) 和做 KeepAlive (lock service)。但是 Chubby API 太过于 file system oriented 了。这是因为 Chubby 是 Google 的 internal system, 一方面要满足应用层的需求,另一方面 fit in Google infra landscape。
etcd 的 API 则更为多样化:
- Raft (consensus) 层被其他开源项目 TiKV, Cockroach DB, Dgraph 给重用了。
- KeepAlive 是绑定在 client-agnostic 的 Lease 抽象层上而不是 client-specific 的 Session 上。
- Watch 可以得到连续性的事件。
- 类似于 Kafka, 能通过 index 重新得到原来的消息。
- 提供 Range query。
- 提供 Transaction API。
- 默认提供了 causal consistency guarantee。用户可选 serializability guarantee。
可以看出,etcd API 更偏底层。这是因为 etcd 作为开源项目,要满足更广泛的 use cases,所以需要在更底层找到共同的抽象。
其实 API 并没有好坏之分,这里一个重要的经验就是系统设计切忌照猫画虎。Chubby 最牛逼的地方在于他的 consensus 层和 database storage 层。假设不得其精髓,只顾肤浅实现其 API,这就是算法上的只顾每步最优无法全局最优。千万不要走捷径,走崎岖的路是一种沉淀!
值得一提的是 Transaction API。在 Paxos Made Live 里面提到了一个叫 MultiOp primitive。前人深邃的思想,在白纸黑字间,略显枯燥无味。以为就要淹没在历史的河流里,十多年后这个想法却在 etcd 里面用现代的方式重新展现出来,在这个世界被许许多多的用户使用着,受惠于大大小小的项目。我每次想到这个就情不自禁地兴奋起来。这TM才是艺术!我恨不得开间博物馆给保存起来。
写在最后
etcd 目前主要用作:
- replicated database: causal consistency, serializability
- message queue
- health checking
通过分享架构,希望能帮助人们更好的使用 etcd,和开发新的用法。