走近分布式协调服务--zookeeper

分布式环境的特点

  • 并发性,程序运行过程中,并发性操作是很常见的。比如同一个分布式系统中的多个节点,同时访问一个共享资源、数据库等。
  • 分布性
  • 无序性

分布式环境下面临的问题

网络通信
网络本身的不可靠性,因此会涉及到一些网络通信问题。

分区容错
当网络发生异常导致分布式系统中部分节点之间的网络延时不断增大,最终导致组成分布式架构的所有节点,只有部分节点能够正常通信。

CAP理论

C一致性:所有节点上的数据时刻保持一致。

A可用性:每次请求都能收到响应,不管结果成功或失败。

P分区容错性。cap介绍

由于这三个指标不可能同时做到,在分区容错性是必须的情况下,只能选择取舍CP或AP其中一种。

1
2
(CAP理论仅适用于原子读写的Nosql场景,不适用于数据库系统?
因为如果出现更新失败导致数据丢失的情况,无法恢复)

zookeeper是CP理论的一种典型。

image

BASE 理论

ebay提出的BASE理论,放宽了对事务的ACID要求。保证基本可用。软状态。保证数据的最终一致性。 (兼顾可用性和一致性)

Basically available :基本可用。正常情况下,一个在线搜索引擎需要在0.5秒之内返回给用户相应的查询结果,但由于出现故障(比如系统部分机房发生断电或断网故障),查询结果的响应时间增加到了1~2秒。

soft-state: 软状态。即允许系统在不同节点的数据副本之间进行数据同步的过程存在延时。

Eventually Consistent:最终一致性。

zookeeper是什么

zookeeper是一个开源的分布式协调服务,是由雅虎创建的,基于google chubby。 是分布式数据一致性的一种解决方案。

zookeeper能做什么

数据的发布/订阅(配置中心:disconf) 、 负载均衡(dubbo利用了zookeeper机制实现负载均衡) 、命名服务、
master选举(kafkahadoophbase)、分布式队列、分布式锁。

  • 顺序一致性:从同一个客户端发起的事务请求,最终会严格按照顺序被应用到zookeeper
  • 原子性:所有的事务请求的处理结果在整个集群中的所有机器上的应用情况是一致的,也就是说,要么整个集群中的所有机器都成功应用了某一事务、要么全都不应用。
  • 可靠性:一旦服务器成功应用了某一个事务数据,并且对客户端做了响应,那么这个数据在整个集群中一定是同步并且保留下来的。
  • 实时性:一旦一个事务被成功应用,客户端就能够立即从服务器端读取到事务变更后的最新数据状态;(zookeeper仅仅保证在一定时间内,近实时)

一些概念

zookeeper的数据模型和文件系统类似,每一个节点称为:znode. 是zookeeper中的最小数据单元。每一个znode上都可以保存数据和挂载子节点。从而构成一个层次化的属性结构。

节点特性

  • 持久化节点 :节点创建后会一直存在zookeeper服务器上,直到主动删除。
  • 持久化有序节点:每个节点都会为它的一级子节点维护一个顺序。
  • 临时节点 :临时节点的生命周期和客户端的会话保持一致。当客户端会话失效,该节点自动清理。
  • 临时有序节点:在临时节点上多勒一个顺序性特性。

zookeeper集群

zookeeper集群, 包含三种角色: leader / follower /observer

1
2
3
4
5
6
7
#在datadir添加一个myid,配置server.myid=ip:port1:port2
#添加observer节点的时候需要在zoo.cfg中增加peerType=observer

server.0=192.168.11.128:2888:3888
server.1=192.168.11.129:2888:3888
server.2=192.168.11.130:2888:3888
server.3=192.168.11.131:2888:3888:observer

其中,3888用于leader选举。2888为节点间通信端口。

observer节点比较特殊,用于提升zookeeper集群的扩展性。因为随着连接的client增多,server的集群也必须扩大,而zk集群选举需要半数以上机器投票通过,代价较大。observer不参与投票只接收投票结果。可以做到在不影响写性能的情况下去扩展zk。

zookeeper配置文件

1
2
3
4
5
6
7
8
9
10
11
tickTime=2000  zookeeper中最小的时间单位长度 (ms)

initLimit=10 follower节点启动后与leader节点完成数据同步的时间

syncLimit=5 leader节点和follower节点进行心跳检测的最大延时时间

dataDir=/tmp/zookeeper 表示zookeeper服务器存储快照文件的目录

dataLogDir 表示配置 zookeeper事务日志的存储路径,默认指定在dataDir目录下

clientPort 表示客户端和服务端建立连接的端口号: 2181

zookeeper的客户端使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#使用help查看命令

1. create [-s] [-e] path data acl
-s 表示节点是否有序
-e 表示是否为临时节点
默认情况下,是持久化节点,且无序

2. get path [watch]
获得指定 path的信息

3.set path data [version]
修改节点 path对应的data

4.delete path [version]
删除节点

5.deleteall path
delete不能删除有子节点的节点。deleteall可以(rmr命令已过时)。

Watcher

zookeeper提供了分布式数据发布/订阅,zookeeper允许客户端向服务器注册一个watcher监听。当服务器端的节点触发指定事件的时候会触发watcher。服务端会向客户端发送一个事件通知

watcher的通知是一次性,一旦触发一次通知后,该watcher就失效.

ACL

zookeeper提供控制节点访问权限的功能,用于有效的保证zookeeper中数据的安全性。避免误操作而导致系统出现重大事故。
CREATE/READ/WRITE/DELETE/ADMIN

ZooKeeper 的权限管理通过ServerClient 两端协调完成:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
(1) Server端

一个ZooKeeper 的节点存储两部分内容:数据和状态,状态中包含ACL 信息。创建一个znode 会产生一个ACL 列表,列表中每个ACL 包括:
① 权限perms
② 验证模式schema
③ 具体内容expression:Ids
例如,当scheme="digest" 时, Ids 为用户名密码, 即"root :J0sTy9BCUKubtK1y8pkbL7qoxSw"。ZooKeeper 提供了如下几种验证模式:

① Digest: Client 端由用户名和密码验证,譬如user:pwd

② Host: Client 端由主机名验证,譬如localhost

③ Ip:Client 端由IP 地址验证,譬如172.2.0.0/24

④ World :固定用户为anyone,为所有Client 端开放权限

当会话建立的时候,客户端将会进行自我验证。

权限许可集合如下:

① Create 允许对子节点Create 操作

② Read 允许对本节点GetChildren 和GetData 操作

③ Write 允许对本节点SetData 操作

④ Delete 允许对子节点Delete 操作

⑤ Admin 允许对本节点setAcl 操作

javaapi

  • 原生api
  • zkclient
  • curator

api的使用细节之后详细记录

实现数据发布订阅/ 配置中心

实现配置信息的集中式管理和数据的动态更新

实现配置中心有两种模式:pushpull。(文件的推和拉)

zookeeper采用的是推拉相结合的方式。 客户端向服务器端注册自己需要关注的节点。一旦节点数据发生变化,那么服务器端就会向客户端发送watcher事件通知。客户端收到通知后,主动到服务器端获取更新后的数据。
image

适用情况特征:

  1. 数据量比较小
  2. 数据内容在运行时会发生动态变更
  3. 集群中的各个机器共享配置

实现集群管理

实现集群管理,首先所有服务器在启动时向zookeeper中指定节点下,注册自己(创建临时节点)。基于临时节点和watcher机制的特性,当有节点创建成功时,会发送一个通知节点上线。节点意外宕机时,也会发出通知。
image

实现分布式锁

分布式锁的原理也是同样,当服务想要获取锁时,在zookeeper中有指定的持久节点,需要获取锁的线程需要到改节点下去创建临时有序节点,这样在zk中,节点创建成功,并且在所有子节点中排序为最小的那个线程成功获得锁。没有拿到锁的线程改为监控比自己节点小1的节点,当任务执行完毕,临时节点会被删除,此时触发watcher机制。通知下一个线程获取锁。

实现独占锁的机制也类似,所有节点都去创建子节点,创建成功者获得锁,其余等待。
image

实现分布式队列

分布式队列可以在zk中维护一个持久节点,节点下存一个data值为队列的容纳数量。当程序入队时,在该节点下创建子节点,当子节点个数达到父节点下的data设置个数时,表示队列满。无节点时表示队列空。每当出队时删除对应的节点。

image

0%