背景
最近在看到Pachyderm的介绍时,看到作者拿YARN和Kubernetes做类比,拿Zookeeper和etcd做对比。YARN和Kubernetes的类比还相对比较好理解,毕竟他们都有资源管理和调度的职能,只不过YARN上运行的对象是JVM,而Kubernetes上运行的是容器。但是拿Zookeeper和etcd来类比我就有些不懂了,在我之前的概念里zookeeper并不是一个存储组件啊,因此有了本文的过程。
etcd的官网介绍是一个分布式的K/V存储,而Zookeeper的官网介绍是一个高度可用的分布式协调者。看起来他们做的事情完全不同啊,那我们来比较一下功能介绍。
从功能上看,他们干的事好像也都差不多,分布式的一致性、选举算法、分布式锁,那么,我们来看一下各自的典型应用吧。
分别参考了ZooKeeper应用场景汇总和ETCD的应用场景
在应用场景上,etcd和Zookeeper也很一致,难道Zookeeper本质上是分布式存储组件,为此,我查了下 Zookeeper是否可以作为分布式存储系统?
在知乎上的答案为:zookeeper只存元数据(https://www.zhihu.com/question/22116083)
总结几点原因如下:
所以,逻辑上来说,可以。因为Zookeeper本质上是一个内存式的文件系统,它的znode就相当于dictionary和file的结合体,但是由于性能和存储容量以及使用场景来看,Zookeeper适合存有强一致性要求的配置信息,也就是元数据。
到这一步,基本搞清楚了Zookeeper的应用场景了,如果etcd可以和Zookeeper作类比的话,难道etcd不是一个分布式存储组件?
回到etcd的官方文档,在Reference下看到一个FAQ目录,发现了etcd的名称由来,原来它是”/etc”和”d” (distributed) 的结合体, 它存的也是大型分布式系统的配置信息,也就是“distributed etc directory.”
到此可知,Zookeeper和etcd解决的问题是一样的,都解决分布式系统的协调和元数据的存储,所以它们都不是一个存储组件,或者说都不是一个分布式数据库。etcd灵感来源于Zookeeper,但在实现的时候有了很多的改进。
etcd是使用raft算法解决的脑裂问题,raft算法具体参考 raft的动画(http://thesecretlivesofdata.com/raft/)看这个就很好理解。
关于脑裂现象的一些推荐资料
Linuex-ha split-brain
Split-brain, Quorum, and Fencing - updated
ZooKeeper
除了上述的这些不足以外,在其官网文档中自己也提到,在watch被触发和重新设置之间发生的事件将被丢弃,无法被捕捉。接下来让我们看看Etcd的watch。
Etcd
Etcd支持单点watch,prefix watch以及ranged watch。
和ZooKeeper不同,Etcd不会根据事件的不同而要求调用不同的watch API,三类watch的区别仅在于
对key的处理不同:
之前在使用etcd的时候,只是在官网看到了分布式存储,就默认它为一个存储组件,导致了对etcd的误解,这也是第一次用到的时候没有深入了解导致的,在经过和Zookeeper的比较学习之后,发现两者在很多方面有着相同的特性。以前我对Zookeeper也有一定的误解,以为它是一个协调者,一定有管理的功能,可以控制很多东西,但经过这番学习之后,发现其实Zookeeper本质上也是一个存储单元,用于存放配置信息,解决分布式中的读写一致性问题。总的来说,etcd和Zookeeper有相似的功能,做的事情也大同小异,只是可能具体的应用场景不太一样,我目前的了解是Zookeeper主要用于Hadoop组件的协调上,etcd主要用于Kubernetes上对于容器的协调上,两者都是用于存放配置信息等元数据的,随着以后的深入学习,希望可以慢慢把他们的区别理清晰。
不得不承认,作为后起之秀,Etcd在watch方面完胜ZooKeeper。
从功能的角度来看,Etcd只需要调用一次watch操作就可以捕捉所有的事件,相比ZooKeeper大大简化了客户端开发者的工作量。
ZooKeeper的watch获得的channel只能使用一次,而Etcd的watch获得的channel可以被复用,新的事件通知会被不断推送进来,而无需客户端重复进行watch,这种行为也更符合我们对go channel的预期。
ZooKeeper对事件丢失的问题没有解决办法(如果新版本可以解决记得留言告诉我)。Etcd则提供了版本号帮助客户端尽量捕捉每一次变化。要注意的是每一次变化都会产生一个新的版本号,而这些版本不会被永久保留。Etcd会根据其版本留存策略定时将超出阈值的旧版本从版本历史中清除。
从开发者的角度来看,ZooKeeper是用Java写的,且使用了自己的TCP协议。对于程序员来说不太友好,如果离开了ZooKeeper提供的SDK自己写客户端会有一定的技术壁垒,而ZooKeeper官方只提供了Java和C语言的SDK,其它语言的开发者就只能去寻求第三方库的帮助,比如github.com/samuel/go-zookeeper/zk。
另一方面,Etcd是用Go写的,使用了Google的gRPC协议,官方除了提供Go语言的SDK之外,也提供了Java的SDK:https://github.com/etcd-io/jetcd。
另外Etcd官方还维护了一个zetcd项目:https://github.com/etcd-io/zetcd,它在Etcd外面套了一个ZooKeeper的壳。让那些ZooKeeper的客户端可以无缝移植到Etcd上。有兴趣的小伙伴可以尝试一下。
阅读了“ZooKeeper应用场景汇总(超详细)”一文的读者可能会发现,etcd实现的这些功能,Zookeeper都能实现。那么为什么要用etcd而非直接使用Zookeeper呢?
相较之下,Zookeeper有如下缺点:
而etcd作为一个后起之秀,其优点也很明显。
最后,etcd作为一个年轻的项目,正在高速迭代和开发中,这既是一个优点,也是一个缺点。优点在于它的未来具有无限的可能性,缺点是版本的迭代导致其使用的可靠性无法保证,无法得到大项目长时间使用的检验。然而,目前CoreOS、Kubernetes和Cloudfoundry等知名项目均在生产环境中使用了etcd,所以总的来说,etcd值得你去尝试。
转自https://blog.csdn.net/zzhongcy/article/details/89401204
说的再好,不如行动。不怕慢,就怕站。
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://www.cnblogs.com/ibigboy/p/15923344.html
内容来源于网络,如有侵权,请联系作者删除!