什么是Zookeeper,为什么它在分布式系统中具有不可替代的地位
很多中间件,比如Kafka、Hadoop、HBase都使用Zookeeper,所以很多人都会明白Zookeeper是什么以及为什么。它在分布式系统中有如此不可替代的地位。
遇到很多坑之后,我决定回答这个问题。
其实,要学习任何技术,首先要明白为什么需要这个技术。
为什么我们需要Zookeeper
更认真地回答这个问题,我们需要一些像独立机器一样工作但比独立机器更可靠的东西。
下面是不认真回答的开始。
一个团队需要一个领导者。领导者是用来做什么的?我们先不谈管理。这么说吧,如果有人想问关于这个团队的事情,他们会先去找领导,因为他知道的最多,他的答案也最可靠。
例如,经理饼干这个产品就来到了要人那里。作为领导者,老吕发现小耀最近没有项目安排,于是将小耀分配到了cookie项目;
过了一会儿,小西的另一个产品也来找要人,老吕发现小耀刚刚安排离开,而没人已经被撤掉了,于是他告诉小西,人们从你的产品中撤掉了,你的产品应该协调。 ![]()
如果老吕忘记了小耀此时被安排离开,而将小耀分配给了小西,那么两个产品就会打起来。
这是团队中领导者的协调角色。
同样,在分布式系统中,也需要这样一个协调器来回答系统下所有节点的问题。
比如我们搭建了一个一主多从的数据库集群。 master负责写,slave只负责读。我们需要一个系统来告诉客户谁是主人。
有人说这很容易。我们只是把这些信息写入Java服务器的内存中,有一个map,key:master,value:IP对应master机器![]()
但是别忘了,这是一台单机。 ,一旦这台机器挂了,就结束了,客户端就无法知道谁是master了。
因此我们开始将其扩展到由三台服务器组成的集群。 ![]()
现在问题来了。当我更改其中一台机器的主IP时,数据未同步到其他两台机器。这时,顾客应要求到达。当请求到另外两台机器时,还没有同步。该机器接收旧数据并将数据写入不再是主机的机器。
所以我们需要这个服务器集群来存储master信息,这样如果信息不同步的话,就不会对外提供服务,阻塞request请求,等到信息同步完成,然后进入'有关请求请求的信息已返回。
导致请求变慢,延迟时间取决于集群如何认为数据同步完成。
假设数据同步时间无限短,比如1微秒,可以忽略不计,那么其实这个分布式系统就和我们之前的单机系统一样,可以保证数据的一致性,同时让外部查询后不可见。阻塞,同时不存在SPOF(单点故障)的风险,即不会因为一台机器宕机而导致整个系统不可用。
这样的系统称为分布式协调系统。谁能把这个数据同步时间压缩得更短,谁能更快地响应请求,就会更好,而Zookeeper就是其中之一。
它的工作方式就像单台机器一样,可以提供强数据一致性,但其背后是不同机器的集群,因此不存在单点故障。
其实就是CAP理论中满足CP但不满足A的分布式系统类型。
如果把每个节点比作不同的小动物,那么协调者就是zookeeper。这就是Zookeeper名字的由来。从名字就可以看出他的野心。
讲完了上面,现在我们看一下官网上的这句话,就会很容易理解了:
ZooKeeper: A Distributed Coordination Service for Distributed Applications当然还有这句话:![]()
以前很多ZK教程都说过,《Zookeeper是一个开源的分布式系统,《应用协调系统》blabla,很多像我这样的年轻人看到都会一头雾水。什么是分布式协调,为什么需要分布式协调......
上面只是回答我自己的问题,为什么需要Zookeeper?,或者说,为什么需要一个分布式协调系统。如果你想深入了解ZK,还需要了解Zookeeper的内部实现原理。
例如,从ZK的宏观结构:![]()
到ZK的微观结构:![]()
,再到ZK如何实现高性能和强一致性,这就是ZAB协议的原理。很多教程开始介绍ZAB协议,很简单却让人困惑,不知道为什么需要这样一个分布式一致性协议。有了上面介绍的背景,就容易理解多了。
当然你也可以比较一下近年来非常流行的etcd和ZK的区别。
最后推荐两个ZK学习资源:
- ZK官网
- 《从 Paxos 到 Zookeeper》
==更新于2019/06/14==
读完这篇文章,读者可能还有疑问,为什么一定有如果你想使用Zookeeper,我可以使用另一个。
这是我的错。在写这篇文章时,我把Zookeeper等同于分布式协调服务,并将为什么需要Zookeeper的问题等同于“为什么需要分布式协调服务”。事实上,这是有问题的,因为如果你想提供分布式协调服务,你不一定需要像ZK这样的CP中间件。也可以使用AP。
使用AP还是CP由业务决定。
例如,如果你是文件上传服务器,用户可以上传几GB的文件。如果您使用的是 AP 系统,则无法获取不可用的节点。如果返回给客户端再尝试,客户端肯定会发疯,这个时候就必须使用CP。
和rpc调用一样,如果调用失败,就重试一次,成本也不高。这时候可能用AP比较合适。
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
code前端网