zookeeper名字的由来
大数据生态系统里的很多组件的标志都是某种动物或者昆虫,比如hadoop就是🐘,hive就是🐝。zookeeper即动物园管理员,顾名思义就是管理大数据生态系统各组件的管理员,如下图所示:
zookeeper能用来做什么?
- 维护配置信息
- 命名服务naming service
- 分布式锁服务
- 集群管理
1. 维护配置信息
java编程经常会遇到配置文件(其中包含了需要的配置项),比如数据库的url、schema、user和password等。通常这些配置项我们会放置在配置文件中,再将配置文件放置在服务器上;当需要更改配置项时,需要去服务器上修改对应的配置文件。但是随着分布式系统的兴起,由于许多服务都需要使用到该配置文件,因此有必要保证该配置服务的高可用性(high availability)和各台服务器上配置数据的一致性。通常会将配置文件部署在一个集群上,然而一个集群动辄上千台服务器,此时如果再一台台服务器逐个修改配置文件那将是非常繁琐且危险的的操作,因此就需要一种服务,能够高效快速且可靠地完成配置项的更改等操作,并能够保证各配置项在每台服务器上的数据一致性。
zookeeper就可以提供这样一种服务,其使用Zab这种一致性协议来保证一致性。现在有很多开源项目使用Zookeeper来维护配置,比如在HBase中,客户端就是连接一个Zookeeper,获得必要的HBase集群的配置信息,然后才可以进一步操作。还有在开源的消息队列Kafka中,也使用Zookeeper来维护broker的信息。在Alibaba开源的SOA框架Dubbo中也广泛的使用Zookeeper管理一些配置来实现服务治理。
2. 命名服务naming service
比如为了通过网络访问一个系统,我们得知道对方的IP地址,但是IP地址对人非常不友好,这个时候我们就需要使用域名来访问。但是计算机是不能是别域名的。怎么办呢?如果我们每台机器里都备有一份域名到IP地址的映射,这个倒是能解决一部分问题,但是如果域名对应的IP发生变化了又该怎么办呢?于是我们有了DNS这个东西。我们只需要访问一个大家熟知的(known)的点,它就会告诉你这个域名对应的IP是什么。在我们的应用中也会存在很多这类问题,特别是在我们的服务特别多的时候,如果我们在本地保存服务的地址的时候将非常不方便,但是如果我们只需要访问一个大家都熟知的访问点,这里提供统一的入口,那么维护起来将方便得多了。
3. 分布式锁服务
一个集群是一个分布式系统,由多台服务器组成。为了提高并发度和可靠性,多台服务器上运行着同一种服务。当多个服务在运行时就需要协调各服务的进度,有时候需要保证当某个服务在进行某个操作时,其他的服务都不能进行该操作,即对该操作进行加锁,如果当前机器挂掉后,释放锁并fail over 到其他的机器继续执行该服务。
4. 集群管理
一个集群有时会因为各种软硬件故障或者网络故障,出现某些服务器挂掉而被移除集群而某些服务器加入到集群中的情况,zookeeper会将这些服务器加入/移出的情况通知给集群中的其他正常工作的服务器,以及时调整存储和计算等任务的分配和执行等。此外zookeeper还会对故障的服务器做出诊断并尝试修复。
zookeeper的数据模型
zookeeper可以视为树状结构(或者目录),树中的各节点被称为znode(即zookeeper node),一个znode可以有多个子节点。zookeeper节点在结构上表现为树状;使用路径path来定位某个znode,比如/ns-1/tenant/mysql/schema1/table1,此处ns-1、tenant、mysql、schema1、table1分别是根节点、2级节点、3级节点以及4级节点;其中ns-1是tenant的父节点,tenant是ns-1的子节点,tenant是mysql的父节点,mysql是tenant的子节点,以此类推。
那么如何描述一个znode呢?一个znode大体上分为3各部分:
- 节点的数据:即znode data;(节点path, 节点data)的关系就像是java map中(key, value)的关系;
- 节点的子节点children;
- 节点的状态stat:用来描述当前节点的创建、修改记录,包括cZxid、ctime等。
节点状态stat的属性
在zookeeper shell中使用get命令查看指定路径节点的data、stat信息:
[zk: localhost:2181(CONNECTED) 7] get /ns-1/tenant
cZxid = 0x6a0000000a
ctime = Wed Mar 27 09:56:44 CST 2019
mZxid = 0x6a0000000a
mtime = Wed Mar 27 09:56:44 CST 2019
pZxid = 0x6a0000000e
cversion = 2
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 0
numChildren = 2
属性说明:
- cZxid:创建该节点znode的transaction id
- ctime:该节点创建时间create time
- mZxid:最近一次修改该节点znode的transaction id
- mtime:最近一次修改该节点的时间modify time
- pZxid:最近一次修改该节点的子节点(非孙节点)的transaction id
- cversion:子节点被修改的次数children version,初始为零,每修改一次加1
- dataVersion:该节点data修改次数,初始为零,每修改一次加1
- aclVersion:该节点的访问控制列表修改次数(access control list),初始为零,每修改一次加1
- ephemeralOwner:临时节点owner,非临时节点为0
- dataLength:该节点data长度
- numChildren:该节点的子节点个数
参考: