研究一款产品的时候,我们要从设计,架构的角度,来考虑其设计者为何要这样设计,这样设计的优点是什么,缺点是什么,其适用场景是什么,还有没有更好的解决方案.
在研究其实现时,也不能仅仅思考其功能上是如何实现的,还要考虑如何保证代码的优雅性,如何充分解耦,如何进行测试,代码中进行了哪些优化,我们还可以如何进一步优化.
这样我们才能也设计出一款具有更高的性能,更好的产品.
在这篇文章中,我们将会对ZooKeeper进行模块拆分.
ZooKeeper介绍
其实,ZooKeeper就是一个分布式键值系统.它提供了几种类型的几点,基于这,又衍生出来它的其他用途,比如,分布式锁.但是,从本质上说,它就是一个分布式键值系统.
我们如何设计一个键值系统?
我们考虑一下,如果让我们设计一个键值系统,不是分布式键值系统,只是一个简单的键值系统,在单机上运行的那种,我们要如何来设计呢?
首先,这个键值系统,很明显,是C/S架构.需要一个客户端,然后还需要一个服务器端.
那么,服务器端如何对外提供服务呢?以Restful接口的形式,还是以Socket的方式,或者RPC的方式?
另外,我们这个系统提供哪些操作?
它提供的操作是否是幂等性的?如果是非幂等性的,我们如何处理?
数据结构是怎样的?是HashMap么?或者其他的数据结构,链表,树?
如何做到容灾?用快照?
如何对服务器端进行监控?
对于一个分布式键值系统来说,又有其他的地方需要考虑.
各个节点如何进行通讯?
如何保证各个节点之间的数据的一致性?Paxos,Raft,Zab?
要实现哪一种一致性模型?强一致性还是最终一致性?
需要容忍Byzantine错误吗?
如何进行测试?
ZooKeeper拆分
从上面那一小节,我们基本上就能得出ZooKeeper的各个模块:
- 客户端
- 服务器端
- 一致性算法模块
- 本地容灾模块
- 监控模块
- 测试模块
当然,各个模块之间并不是独立的.比如,ZooKeeper中的监控使用的是JMX,所以,可以看到JMX穿插在各处.
其实服务器端
包括了本地容灾模块
以及监控模块
,以及其他的如各种数据结构.