秒懂Zookeeper原理与工作机制
什么是Zookeeper
Zookeeper简称zk,先从字面意思上去理解,那就是动物园管理员。其实zk是大数据领域中的一员,为整个分布式环境提供了协调服务,主要可以用于存储一些配置信息,同时也可以基于zk实现集群。它是一个apache的开源分布式中间件。
zk和大数据领域结合比较密切,可以管理很多框架,比如:
- hadoop
- hive
- kafka
- hbase
- hdfs
- pig
- ……
zk把上述框架都可以管理起来,那么就相当于作为一个动物园管理员管着各个动物了,比如大象啊,蜜蜂啊,猪啊等等。很形象。
举一些zk简单的场景:
- 比如当你使用dubbo的时候,你需要使用zk作为注册中心,当然SpringCloud也可以使用zk来替代eureka作为注册中心。
- 另外kafka和solr都是基于zk的结合实现了集群,当然netty也可以。如果你对上述的一些技术名字没有听过没有接触过,那么没有关系,我们将来都会涉及到,都会带着大家去学习。
- 集群或者分布式系统以及大数据中的一些统一的配置管理信息可以都写入zk便于所有服务器节点监听读写,其实也就是协调作用嘛
- MQ消费者处理完毕也可以通过zk回写通知生产者处理完成,并且告知结果。
工作机制
zk可以说是一种监工模式。zk中把数据保存到节点(节点后面会说),然后可以监听这个节点,如果节点的数据发生变化,则可以发起通知。我们可以通过下面一张图来描述这个过程。
上面就是zk的工作原理,本质上其实也是生产者与消费者的关系,学生就是生产者,而班主任就是消费者,通过这种关系实现了zk的通知机制。
Zookeeper的特点
- zk集群由一个leader和多个follower组成。和公司一样,老板只有一个,其他都是打工的小弟。
- zk集群中,只要有半数以上的zk节点存活,那么整个集群可以正常对外提供服务。这是选举规则,和redis一样。
- 每个节点的数据全部都是一致的,不论客户端(脚本或java端)连接到任意的zk节点,那么所获得的数据,全部一致。
- 同一个客户端发起的写操作是顺序执行的。其实也就是自身事务的顺序一致性,zk会使用递增的事务id号(zxid)来标识事务。
- 数据原子性,数据写操作,要么成功,要么失败。
- 近实时性,成功写入一个数据后,可以立马在别的节点读取相应的数据。节点之间对数据的同步复制速度很快,而且本身zk的数据保存也不会很大的,同步会很快。
Zookeeper的数据结构
zk的数据结构是线性的树形结构的,类似linux系统目录结构那种。
通过例子先来聊一聊redis的数据结构。redis的数据都是放在内存的。通过set设置,get获取。那么其实就类似一个桶状型容器,里面放了很多key,通过get就能获得。
就拿洗澡盆来讲,洗澡盆里可以放小黄鸭,奥特曼,怪兽等。我们要拿的话就直接get("小黄鸭")就能获得数据。类似这样的:
那么zk是怎样的呢,看如下图:
也就是说,zk的数据模型和linux的文件系统目录结构类似,可以作为树形结构一层一层展开,每一层作为一个node节点(znode)都可以存储数据,而这个node可以比作是一片树叶,树叶很小能够承载的东西也不多,所以znode节点能够存储的数据大小在1m左右,不能设置很大,存储一些配置信息啊或者一些json信息就行。每一个节点都会有其指定的唯一标识路径,比如/admin/info
就是唯一路径。
Zookeeper 应用场景
- 统一命名策略:一般来说,在分布式系统里,有很多的服务器节点,他们都是各有ip组成的,那么我们并不会记住那么多的ip,往往都可以为它取一个别名,比如ip为192.168.1.201的ip我们几乎不会去记住它,而且用一个别名比如 service-mq 和ip做好映射,那么客户端去调用这个ip的时候,直接根据服务别名去获得就能拿到ip,然后根据ip发起通信即可。微服务也是如此,可以参考如下图,我们可以直接通过获得节点
/admin/service-admin
的值就能拿到对应的ip了。 -
发布/订阅模式:这个也是常见的生产者与消费者模式,或者说是监听机制,类似消息队列。可以向一个节点去做一些数据的操作变更,一旦消费者监听到,那么可以去做相关的业务处理。
-
分布式配置管理:在分布式系统中,配置文件的同步很常见的。这其实就是统一分布式环境中,集群的所有配置信息全部一致,而且就是基于上面的第2点来实现的,如下图所示:当我往某个节点去写入一段配置信息,那么可以让所有其他的节点监听到,随后同步配置信息到本地。假设有1万台服务器集群,你要运维改会很麻烦,而且容易出问题,现在通过zk就能很好的进行配置信息的同步管理,只需要写入一次,就能让1万台集群自动同步配置,这岂不是美哉!
-
服务器节点状态管理:当集群或者分布式环境下,某个服务节点出现问题,可以通知其他节点,以便做一些业务处理。
并在如果是集群环境,当一个节点宕机下线后,那么服务可以快速做出调成,切换成新的服务ip,以保障集群可用。
-
(软)负载均衡:既然可以通过zk去管理集群或分布式系统的状态,那么我们完全也可以通过zk去实现负载均衡呀,微服务不就如此吗?
前期接触zk会很陌生,很抽象,但是一旦你自己去实操演练,安装啊,写代码啊,那么就会对zk有一定的理解了。