在介绍ZooKeeper前先了解下分布式应用。
分布式应用是指在网络中的多个或多种操作系统上运行,通过外部协调控制他们有效的完成特定业务作业,尤其是复杂、耗时的业务作业,应用分布式技术可以很快能完成。 一般大型分布式应用都以集群的方式部署应用。
ZooKeeper就是其中一种解决分布式应用协调服务的开源框架,用来解决分布式集群中的应用服务的集中管理,例如:名字服务、一致性、可靠性、配置管理等内容。ZooKeeper 本质上是一个分布式的小文件存储系统。提供基于类似于文件系统的目录树方式的数据存储,并且可以对树中的节点进行有效管理,从而来维护和监控你存储的数据的状态变化,将通过监控这些数据状态的变化,从而可以达到基于数据的集群管理。
ZooKeeper本身也是一个分布式应用程序,至少需要3个节点才能用于生产环境并提供预期的安全保障。下面罗列一下其涉及的知识点:
1、Leader:ZooKeeper 集群工作的核心 事务请求(写操作)的唯一调度和处理者,保证集群事务处理的顺序性;集群内部各个服务的调度者。 对于 create,setData,delete 等有写操作的请求,则需要统一转发给 leader 处理,leader 需要决定编号、执行操作,这个过程称为一个事务。
2、Follower: 处理客户端非事务(读操作)请求 转发事务请求给 Leader 参与集群 leader 选举投票2n-1台可以做集群投票 此外,针对访问量比较大的 zookeeper 集群,还可以新增观察者角色
3、Observer: 观察者角色,观察ZooKeeper集群的最新状态变化并将这些状态同步过来,其对于非事务请求可以进行独立处理,对于事务请求,则会转发给Leader服务器处理 不会参与任何形式的投票只提供服务,通常用于在不影响集群事务处理能力的前提下提升集群的非事务处理能力
4、Hierarchical namespace(层次命名空间): 用于在内存中表示ZooKeeper的数据模型(本质是文件系统的树结构)。ZooKeeper的树结构是由一系列节点Znode组成,每个Znode由一个名称标识且用路径符号(/)序列分隔,根路径的节点为“/”,在其下面有两个逻辑命名空间/config和/workers。config用于集中式配置管理数据;workers用于命名
5、节点信息、类型、状态:
Znode兼具文件和目录两种特点,既像文件一样维护着数据长度、元信息、ACL、时间戳等数据结构,又像目录一样可以作为路径标识的一部分。
1)、Znode由三个部分组成:
stat:此为状态信息,描述该Znode版本、权限等信息。
data:与该Znode关联的数据,最多可以存储1MB的数据。
children:该Znode下的节点
2)、Znode的状态信息包括下面几个主要信息:
a、版本号 - 每个znode都有版本号,这意味着每当与znode相关联的数据发生变化时,其对应的版本号也会增加。当多个zookeeper客户端尝试在同一znode上执行操作时,版本号的使用就很重要。
b、操作控制列表(ACL) - ACL基本上是访问znode的认证机制。它管理所有znode读取和写入操作。
c、时间戳 - 时间戳表示创建和修改znode所经过的时间。它通常以毫秒为单位。ZooKeeper从“事务ID"(zxid)标识znode的每个更改。Zxid 是唯一的,并且为每个事务保留时间,以便你可以轻松地确定从一个请求到另一个请求所经过的时间。
d、数据长度 - 存储在znode中的数据总量是数据长度。
6、Znode的节点类型:
持久(persistent)节点,顺序(sequential)节点和临时(ephemeral)节点
1)、持久节点 - 即使在创建该特定znode的客户端断开连接后,持久节点仍然存在。默认情况下,除非另有说明,否则所有znode都是持久的。
2)、临时节点 - 客户端活跃时,临时节点就是有效的。当客户端与ZooKeeper集合断开连接时,临时节点会自动删除。因此,只有临时节点不允许有子节点。如果临时节点被删除,则下一个合适的节点将填充其位置。临时节点在leader选举中起着重要作用。
3)、顺序节点 - 顺序节点可以是持久的或临时的。当一个新的znode被创建为一个顺序节点时,ZooKeeper通过将10位的序列号附加到原始名称来设置znode的路径。例如,如果将具有路径 /myapp 的znode创建为顺序节点,则ZooKeeper会将路径更改为 /myapp0000000001 ,并将下一个序列号设置为0000000002。如果两个顺序节点是同时创建的,那么ZooKeeper不会对每个znode使用相同的数字。顺序节点在锁定和同步中起重要作用。
7、节点状态:
LOOKING:寻找 Leader 状态,处于该状态需要进入选举流程
LEADING:领导者状态,处于该状态的节点说明是角色已经是 Leader
FOLLOWING:跟随者状态,表示 Leader 已经选举出来,当前节点角色是 follower
OBSERVER:观察者状态,表明当前节点角色是 observer
8、Session(会话):
会话对于ZooKeeper的操作非常重要。会话中的请求按FIFO顺序执行。一旦客户端连接到服务器,将建立会话并向客户端分配会话ID 。
客户端以特定的时间间隔发送心跳以保持会话有效。如果ZooKeeper集合在超过服务器开启时指定的期间(会话超时)都没有从客户端接收到心跳,则它会判定客户端死机。
会话超时通常以毫秒为单位。当会话由于任何原因结束时,在该会话期间创建的临时节点也会被删除。
9、Watches(监视):
监视是一种简单的机制,使客户端收到关于ZooKeeper集合中的更改的通知。客户端可以在读取特定znode时设置Watches。Watches会向注册的客户端发送任何znode(客户端注册表)更改的通知。
Znode更改是与znode相关的数据的修改或znode的子项中的更改。只触发一次watches。如果客户端想要再次通知,则必须通过另一个读取操作来完成。当连接会话过期时,客户端将与服务器断开连接,相关的watches也将被删除。
10、事务ID:
ZooKeeper状态的每次变化都接收一个 ZXID(ZooKeeper 事务 id)形式的标记。ZXID 是一个 64 位的数字,由 Leader 统一分配,全局唯一,不断递增。ZXID 展示了所有的ZooKeeper 的变更顺序。每次变更会有一个唯一的 zxid,如果 zxid1 小于 zxid2 说明 zxid1 在 zxid2 之前发生。
11、选举:
ZooKeeper正常工作必须要有Leader,所以在下面两种情况下会进行选举产生Leader,
1)、集群启动时
2)、 在运行过程中由于网络或其他原因导致Leader出故障,会重新启动选举产生新的Leader
12、脑裂:在正常运行时,ZooKeeper集群只有一个Leader,若集群中部署的机器超过7台以上,由于网络或其他原因会在两个局部网络中分别产生各自的Leader,发生这样的现象,俗称"脑裂"。
官方推荐最小的集群部署需要3个节点,这里节点指的是运行ZooKeeper程序的计算机(物理机或虚拟机最好分别建立在不同的物理机上的虚拟机)。
具体有下面三种部署方式:
1)、单机模式
仅在一台机器上部署ZooKeeper程序,主要用于研发测试,不能用于生产环境,没办法保证高可用。
2)、伪集群模式
也部署在一台机器上,但是区分不同的端口(至少需要部署三个端口),每个端口部署一个ZooKeeper程序,需要调整相关配置参数,主要用于测试部署,一般不推荐用于生产环境,因为只有一台机器,同样没办法保证高可用,在机器没问题的情况下可以保证高可用。
3)、集群模式
最少部署3个机器节点,为了优化适应选举一般推荐部署奇数个机器节点,主要用于生产环境,保证高可用。
缺点:
1、跨机房应用风险较大: 因为其只能有一个Leader,由于网络原因容易发生脑裂
2、选举速度较慢:通常耗时30到120秒,期间由于没有leader,不可提供服务
3、没有提供应用权限控制:需要应用方自己控制使用权限
4、性能受限:由于只有一个Leader所以容量、tps等都会受限
5、不能保证跨session的强一致性
6、无http访问接口,只能通过api访问
优点:
1、全局数据强一致性
2、可靠性
3、原子性
4、分布式协调
5、保证顺序消息
6、自动选举
7、同步
8、分布式锁
9、数据实时
10、自动处理心跳
1、集群管理
2、命名服务
3、配置管理
4、分布式协调
5、分布式锁
各个平台一般都有相应的操作组件,下面介绍下java和DoNet平台下的访问组件。
java平台:
1、zookeeper
官方提供的原生的api
2、Apache Curator
推荐用这个,使用比较方便,Apache的开源工具
3、zkclient
也是一个开源的jar包,maven仓库都可以下载的
DoNet平台:
1、ZooKeeperNetEx
推荐使用这个
Nuget: 下载ZooKeeperNetEx
2、Zookeeper.Net
这个目前好像不在维护了
Nuget: Zookeeper.Net