1.Zookeeper是分布式应用程序的协调服务框架,是Hadoop的重要组件。
ZK要解决的问题:
a.分布式环境下的数据一致性。
b.分布式环境下的统一命名服务
c.分布式环境下的配置管理
d.分布式环境下的分布式锁
单台机器使用的锁:同步代码块、重入锁。但是在分布式环境这个锁就发挥不出来作用。共享锁(常用于数据库中的读操作)和排他锁(写操作)
e.集群管理问题
分布式的思想:就是人多干活快,即用多台机器同时处理一个任务。
2.分布式编程容易出现的问题
a.活锁定义:在程序里,由于某些条件的发生碰撞,导致重新执行,再碰撞=》再执 行,如此循环往复,就形成了活锁。活锁的危害:多个线程争用一个资源,但是没有任何一个线程能拿到这个资源。(通俗理解为两人过楼道,互相谦让)
b.死锁定义:死锁是有一个线程拿到资源,但相互等待互不释放造成死锁。
活锁 是死锁的变种。补充:活锁更深层次的危害,很耗尽Cpu资源(在做无意义的调度)
c.需要考虑集群的管理问题,需要有一套机制来检测到集群里节点的状态变化。(可以用心跳 机制来做,但zk不是用心跳机制来做的)
d.如果用一台机器做集群管理,存在单点故障问题,所以针对集群管理,也需要形成一个集群
3.ZK指令
a.create创建节点指令,注意,在创建节点时,要分配初始数据。 如:create /zk01 '' create /zk02 'hello zookeeper'
b.get查看节点数据指令。 如: get /zk01
get查看节点数据指令
hello 数据
cZxid = 0x2
ctime = Mon May 15 05:58:32 PDT 2017创建节点的时间戳
mZxid = 0x2
mtime = Mon May 15 05:58:32 PDT 2017修改此节点数据的最新时间戳
pZxid = 0x2
cversion = 0
dataVersion = 0数据版本号,每当数据发生编号,版本号递增1
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 5数据大小
numChildren = 0子节点个数
c.set更新节点数据指令(执行后mtime、dataVersion可定会放生变化,dataLength可能会变化) 如:set /zk01 hellozk
d.delete删除节点:注意:如果存在子节点,不让删除。只有删除子节点后才能删除。 如:delete /zk01
e.create指令补充:
普通持久节点: 如:create /zk03 ''
普通临时节点:创建此临时节点的客户端失去和zk连接后,此节点消失.zk是通过临时节点监控哪个服务器挂掉的。 create -e /zk04 ''
顺序持久节点:会根据用户指定的节点路径,自动分配一个递增的顺序号。(顺序节点实现分布式锁的效果,服务器1抢到zk05分配zk050001,服务器2抢到zk05分配zk050002) 如:create -s /zk05 ''
顺序临时节点: create -s -e /zk06 'hello'
quit退出zk客户端
4.zoo.cfg
配置zoo.cfg
配置说明:
tickTime=2000 心跳间隔周期 毫秒。
initLimit=10初始连接超时阈值=10*tickTime。指的是follower初始连接leader的超时时间。 如果网络环境不好,适当调大。
syncLimit=5连接超时阈值=syncLimit*tickTime。指的是follower和leader做数据交互的超时时间。如果网络环境不好,适当调大。
dataDir=/usr/soft/zookeeper-3.4.7/tmp dataDir数据目录指的是zookeeper znode树的持久化目录,
server.1=10.8.41.187:2888:3888
server.2=10.8.41.188:2888:3888
server.3=10.8.41.189:2888:3888
server后的数字是选举id,在选举过程中会用到。注意:数字一定要能比较出大小。
2888 端口原子广播端口,可以自定义
3888 端口选举端口,可以自定义
5.Zookeeper事务概念
a.每一个写操作都是一个事务,每一个事务都用一个事务id来代表,叫:zxid
b.zxid 是全局唯一,并且全局递增的。作用就是可以根据最大事务id,找到最新的事务
6.Zookeeper选举机制
a.首先比较最大事务id,Zxid,谁大谁当领导
b.如果Zxid比较不出来,比较myid(选举id),谁大谁当领导
c.选举的前提满足过半同意
选举分两个阶段
a.数据恢复阶段:
当zk服务器启动时,会先从本地磁盘找到本机的最大事务id。
b.选举阶段:
zk服务器会提交选举协议
1.Zxid(最大事务id) 2.本机的选举id(myid文件里的数字) 3.逻辑时钟值 记录当前的选举轮数,确保每个zk在同一轮选举中 4.当前zk服务器状态,分4种:
Looking=>选举阶段 Following=>当小弟阶段 Leading=>当领导阶段 Observering=>观察者阶段(观察者不参与选举)
Leader:负责进行投票的发起和决议,更新系统状态
follower:用于接收客户端请求,并向客户端返回结果,在选举过程中参与投票
observer:可以接收客户端连接,将写请求转发给Leader,但observer不参加投票过程,只同步Leader状态,observer目的是为了扩展系统,提高读取速度。
Leader选举之后:
Leader身上肯定是有最新数据的(有最大事务id的),所以首先做的就是原子广播(通过原子 广播端口)。 原子广播的目的就是为了确保数据一致性(即客户端无论通过哪个zk服务器查看数据,数据都是一样的)
目的二就是为了防止leader挂掉之后,数据的丢失问题
对于事务更新,Leader会通过原子广播征询其他follower,只要满足过半同意机制,事务才能被更新。
注意:a.若ZooKeeper集群共有5台机器,有三台(半数以上的死机了),整个集群就停止工作了。
b.若在一个Following上提交了更新事务,首先该Following会先将任务发送Leader,由Leader会通过原子广播征询其他follower,只要满足过半同意机制,事务才能被更新操作。若是执行更新事务操作时,Leader挂掉,其它集群服务器执行完毕
后会将执行的结果交给Leader进行提交确认,但是Leader挂掉,此时事务会回滚。
7.Zxid 最大事务id 是全局的, cZxid、mZxid、pZxid是针对某个节点路径而言的。
扩展 Zookeeper的选举机制根据Paxos 算法来实现。
Paxos算法解决的问题:在分布式环境下就某一个决议达成一致性问题。
Paxos算法存在活锁问题,Zk用的是Fast Paxos算法,解决了活锁问题。
8.zk的脑裂
脑裂的定义:在管理集群里,出现两个Leader的状况,造成数据混乱,造成整个集群出现问题。脑裂问题是不可控和不可模拟的。出现脑裂问题的根源是选举机制自集群的选举。
Zk脑裂的预防
为选举的Leader分配递增id,根据id的大小去判断是否老Leader或新Leader,如果是老Leader, 就不接受其指令。
9、监控机制:
getData():监控数据是否被修改
getChildren():监控父节点下的子节点是否发生变化
exists() : 监控某个节点是否存在
一旦监控被触发,若不重新置位,当再次发生同样事件时,不会获得触发。
10.权限控制:
ACL:访问控制链【将所有权限组织成为一个链条,对某一个节点提供不同权限的定位,权限取并集】
定义权限通过类似三元组来设计:(scheme:expression, prems) 模式:用户, 权限
模式:world[默认所有的成员访问都是anyone],auth,digest[通过用户名,密码访问 也叫访客模式], host [通过域名],ip
权限:create, read, write, delete, admin
11.ZooKeeper应用场景
11.1 实现消息订阅和发布实现思路:
a.创建一个znode节点 /data
b.其他订阅节点监听/data 节点的数据变化事件
c.如果有事件发生,就获取/data节点的数据
11.2 实现集群整体的配置信息管理
比如某一个机器的配置信息发生变化,其他机器的配置信息也实现同步更改。 实现思路同上
11.3 集群管理
能够快速检测出集群里节点的状态
实现思路:
临时节点+监听机制
11.4 实现分布式消息的协调通知(屏障)
11.5 实现集群的负载均衡
a.利用zk检测到每台的机器的负载情况,指标是:cpu和内存。
b.每台客户端定期将自己的负载情况指标发给zk
c.zk根据收集到指标后,根据负载情况做相关业务控制
11.6 实现分布式锁
实现思路: 利用顺序临时节点的特性来实现,比如4个客户端争相抢注 /source 顺序临时节点。最先抢注的顺序号最小, 就分配给这个节点资源,
该节点对应的服务器执行完后,session会话断开,对应的/source001的临时节点就销毁。接下来,/source002节点对应的服务器执行操作。
11.7 实现命名服务
利用znode路径的唯一性,来做命名服务。
11.8 zk不适用于做的事情
不能用zk存储大量数据。znode树是维系在内存里的,如果数据大,会吃掉大量内存。
12.ZooKeeper 特性
a.数据一致性(单一视图)
client不论连接到哪个Zookeeper,展示给它都是同一个视图,即查询的数据都是一样的。这是zookeeper最重要的性能。
b.原子性
对于事务决议的更新,只能是成功或者失败两种可能,没有中间状态。要么都更新成功,要么都不更新。
c.可靠性
一旦服务端成功的应用了一个事务,并完成对客户端的响应,那么该事务所引起的服务端状态 变更将会一直保留下来,除非有另一个事务又对其进行了改变。
d.实时性
Zookeeper保证客户端将在非常短的时间间隔范围内获得服务器的更新信息,或者服务器失效 的信息,或者指定监听事件的变化信息。(前提条件是:网络状况良好)
e.过半性
集群必须有半数以上的机器存活才能正常工作。因为只有满足过半数,才能满足选举机制选出Leader。因为只有过半,在做事务决议时,事务才能更新。
所以一般来说,zookeeper集群的数量最好是奇数个。