1.Zookeeper在Linux上的安装
首先将压缩包放到Linux系统中的某个文件路径下,
将压缩包解压在当前目录下,也可以自己指定解压目录
然后进入解压后的zookeeper文件夹中,再进入到conf目录下,将zoo_sample.cfg文件拷贝一份并改成zoo.cfg,然后打开该文件,把其中的dataDir中的路径改成zookeeper安装目录下的tmp(此时zookeeper安装目录还没有tmp目录,需要待会手动创建)
将路径切换到zookeeper安装目录,通过mkdir tmp 创建tmp目录
接下来再切换到zookeeper的bin目录,通过sh zkServer.sh start启动zookeeper
通过jps查看是否启动成功,如果出现QuorumPeerMain说明启动成功
然后通过sh zsCli.sh 进入zookeeper客户端操作zookeeper,如果要退出客户端可以使用quit也可以使用ctrl+C健
以上只是zookeeper的单机安装和启动,接下来介绍zookeeper集群的按照和启动
2.Zookeeper集群的安装
开始几步和zookeeper单机安装一样,例如上传,解压,重命名为zoo.cfg,修改dataDir等等,这些都一样。然后在zoo.cfg的末尾再加上几行信息:
(1)server.1=192.168.253.131:2888:3888
(2)server.2=192.168.253.132:2888:3888
(3)server.3=192.168.253.133:2888:3888
其中server是关键字,后面的数字1(或者2或者3)是不固定的,可以自己指定,但是他们之间要能够比较出大小,代表当前服务器的选举ID。192.168.253.131(或者132或者133)写的是你的三台zookeeper服务器的IP地址,然后2888和3888是端口号,2888端口号是原子广播端口,3888是zookeeper内部选举所使用的端口号,两个端口号可以自己指定,不过一般都是使用这两个的
接下来进入zookeeper安装目录,查看有没有tmp目录,没有的话要创建,如果有的话,将tmp目录下的文件删除。然后进入该文件夹,重新创建一个myid的文件,将当前服务器的选举ID写入保存并退出,此时,第一台zookeeper服务器已经搭建完毕,
剩下两台可以通过scp -r path root@ip:/path 该命令拷贝到其他服务器上,然户在修改一下myid文件即可。
接下来就可以启动zookeeper集群了(注意:要关闭三台服务器的防火墙)
进入bin目录:通过sh zkServer.sh start 启动
3.zookeeper选举,分两个阶段
(1).数据恢复阶段
每台服务器在启动前,都会从本地目录找自己所拥有的Zxid(最大事务id),每有一次操作,都是一个事务,每次事务都会递增,事务id越大,事务越新
(2).选举阶段
每台zk服务器都会提交一个选举协议,协议中的内容:
①自己的zxid(事务id)
②选举id(myid文件里的数字)
③逻辑时钟值(和选举轮数有关),作用是确保每台zk服务器处于同一轮选举中
④状态-(Looking)选举状态,Leader,Follower,Observer
4.选举PK原则
先比较Zxid,谁大谁当Leader,如果Zxid比较不出来,再比较选举ID,谁大谁当Leader(前提是要满足过半机制)
注意:zookeeper有一个过半存活机制,比如,三台服务器,挂掉一个可以,挂掉两个不能工作
5.Leader选举成功之后
首先要做的就是数据同步,目的是确保zk集群的数据一致性,一是可以保证当Leader挂掉之后,其他Follower可以顶替工作,此外要确保客户端无论从哪个zk服务器获取数据都是一致的,这种实现数据一致性的过程称为原子广播(Atomic Brodcast)
对于客户端的读请求,任何一个服务器都可以处理,但是对于写请求,会交给Leader来处理,Leader会通过原子广播端口,将写请求(事务)广播给其他的节点,还会收集每个zk服务器的ack信息,然后统计是否满足过半性,如果满足,则次事务成功提交,最后反馈给客户一个确认信息
注意:过半性(过半选举,过半事务提交,过半存活)。每一次选举都会生成一个epoch id(这个id是自增的,所有Follower只会接收epoch id大的数据信息)
6.Zookeeper特性总结:
(1).数据一致性
Client无论连接到哪个Zookeeper,展示给他的都是同一个视图,即查询的数据都是一样的。
(2).原子性
对于事务决议的更新,只能是成功或者失败两种可能,没有中间状态,要么都更新成功,要么都不更新,即,要么整个集群中所有机器都成功应用了某一事务,要么都没有应用,一定不会出现集群中部分机器应用某个事务,另一部分没有应用的情况
(3).可靠性
一旦服务端成功的应用了某一个事务,并完成对客户端的响应,那么该事务所引起的服务端状态变更将会一直保留下来,除非有另一个事务对其进行了改变
(4).Zookeeper保证客户端将在非常短的时间范围内获得服务器的更新信息,或者服务器失效的信息,或者指定监听事件的变化信息(前提是网络状态良好)
(5).顺序性
如果一台服务器上消息a在消息b前发布,则在所有的Server上消息a都将在消息b前被发布
(6).过半性
Zookeeper集群必须有半数以上的机器存活才能正常工作,因为只有满足过半数,才能满足选举机制选出Leader,因为只有过半,在做事务决议时,事务才能更新,所以一般来说,zookeeper集群的数量最好是奇数个。
7.zookeeper的应用场景
(1).统一命名服务(Name Service)
分布式应用中,通常需要有一套完整的命名规则,既能够产生唯一的名称又便于人识别和记住, 就像数据库中产生一个唯一的数字主键一样。我们利用Zookeeper 可以轻松实现这一功能——利用znode路径。因为znode路径是全局唯一的(可以用某个路径来代表服务名)。
(2).集群管理
通过zookeeper知道集群里机器的状态,实现思路:集群里每台机器都在zookeeper里注册自己的临时节点,并上传自己的运行状态,我们可以查看这些临时节点,来得知节点的数据信息,加入某个临时节点消失了,意味着这台节点挂掉了,从而也可以达到集群监控的目的。
(3).数据订阅发布
这个最典型的就是集群配置信息要发布到集群的客户机节点上,实现配置信息的集中式管理和动态更新。
(4).配置管理(Configuration Management)
配置的管理在分布式应用环境中很常见,例如同一个应用系统需要多台 PC Server 运行,但是它们运行的应用系统的某些配置项是相同的,如果要修改这些相同的配置项,那么就必须同时修改每台运行这个应用系统的 PC Server,这样非常麻烦而且容易出错。
像这样的配置信息完全可以交给 Zookeeper 来管理,将配置信息保存在 Zookeeper 的某个目录节点中,然后将所有需要修改的应用机器监控配置信息的状态,一旦配置信息发生变化,每台应用机器就会收到 Zookeeper 的通知,然后从 Zookeeper 获取新的配置信息应用到系统中。
还有分布式同步协调通知、任务分配、负载均衡、分布式锁等等
7.2PC算法
对于一个将数据副本分布在不同分布式节点上的系统来说,如果对第一个节点的数据进行了更新操作并且更新成功后,却没有使得第二个节点上的数据得到相应的更新,于是在对第二个节点的数据进行读取操作时,获取的依然是老数据(或称为脏数据),这就是典型的分布式数据不一致情况。
为了解决分布式一致性问题,在长期的探索研究过程中,涌现出了一大批经典的一致性协议和算法,其中最著名的就是二阶段提交协议、三阶段提交协议和Paxos算法。
2PC算法,是Two-Phase Commit的缩写,即二阶段提交,是计算机网络尤其是在数据库领域内,为了使基于分布式系统架构下的所有节点在进行事务处理过程中能够保持原子性和一致性而设计的一种算法。通常,二阶段提交协议也被认为是一种一致性协议,用来保证分布式系统数据的一致性。目前,绝大部分的关系型数据库都是采用二阶段提交协议来完成分布式事务处理的,利用该协议能够非常方便地完成所有分布式事务参与者的协调,统一决定事务的提交或回滚,从而能够有效地保证分布式数据一致性,因此二阶段提交协议被广泛地应用在许多分布式系统中。
1.提交过程
二阶段提交协议是将事务的提交过程分成了两个阶段来进行处理,其执行流程如下:
(1)阶段一:提交事务请求+执行事务
1. 事务询问。
协调者向所有的参与者发送事务内容,询问是否可以执行事务提交操作,并开始等待各参与者的响应。
2. 执行事务。
各参与者节点执行事务操作,并将Undo和Redo信息记入事务日志中。
3. 各参与者向协调者反馈事务询问的响应。
如果参与者成功执行了事务操作,那么就反馈给协调者Yes响应,表示事务可以执行;如果参与者没有成功执行事务,那么就反馈给协调者No响应,表示事务不可以执行。
由于上面讲述的内容在形式上近似是协调者组织各参与者对一次事务操作的投票表态过程,因此二阶段提交协议的阶段一也被称为“投票阶段”,即各参与者投票表明是否要继续执行接下去的事务提交操作。
(2)阶段二:事务提交
在阶段二中,协调者会根据各参与者的反馈情况来决定最终是否可以进行事务提交操作,正常情况下,包含以下两种可能。
执行事务提交
假如协调者从所有的参与者获得的反馈都是Yes响应,那么就会执行事务提交。
1. 发送提交请求。
协调者向所有参与者节点发出Commit请求。
2. 事务提交。
参与者接收到Commit请求后,会正式执行事务提交操作,并在完成提交之后释放在整个事务执行期间占用的事务资源。
3. 反馈事务提交结果。
参与者在完成事务提交之后,向协调者发送Ack消息。
4. 完成事务。
协调者接收到所有参与者反馈的Ack消息后,完成事务。
中断事务
假如任何一个参与者向协调者反馈了No响应,或者在等待超时之后,协调者尚无法接收到所有参与者的反馈响应,那么就会中断事务。
1. 发送回滚请求。
协调者向所有参与者节点发出Rollback请求。
2. 事务回滚。
参与者接收到Rollback请求后,会利用其在阶段一中记录的Undo信息来执行事务回滚操作,并在完成回滚之后释放在整个事务执行期间占用的资源。
3. 反馈事务回滚结果。
参与者在完成事务回滚之后,向协调者发送Ack消息。
4. 中断事务。
协调者接收到所有参与者反馈的Ack消息后,完成事务中断。
以上就是二阶段提交过程中,前后两个阶段分别进行的处理逻辑。简单地讲,二阶段提交将一个事务的处理过程分为了投票和执行两个阶段,其核心是对每个事务都采用先尝试后提交的处理方式,因此也可以将二阶段提交看作一个强一致性的算法,
下图分别展示了二阶段提交过程中“事务提交”和“事务中断”两种场景下的交互流程。
8.2PC算法的优缺点
二阶段提交协议的优点:原理简单,实现方便。
二阶段提交协议的缺点:同步阻塞、单点问题、脑裂(一个集群中,同时出现了两个Leader,会造成数据同步的紊乱)、太过保守(只要有一个失败,则整个事务失败)。
同步阻塞
二阶段提交协议存在的最明显也是最大的一个问题就是同步阻塞,这会极大地限制分布式系统的性能。在二阶段提交的执行过程中,所有参与该事务操作的逻辑都处于阻塞状态,也就是说,各个参与者在等待其他参与者响应的过程中,将无法进行其他任何操作。
单点问题
在上面的讲解过程中,相信读者可以看出,协调者的角色在整个二阶段提交协议中起到了非常重要的作用。一旦协调者出现问题,那么整个二阶段提交流程将无法运转,更为严重的是,如果协调者是在阶段二中出现问题的话,那么其他参与者
太过保守
如果在协调者指示参与者进行事务提交询问的过程中,参与者出现故障而导致协调者始终无法获取到所有参与者的响应信息的话,这时协调者只能依靠其自身的超时机制来判断是否需要中断事务,这样的策略显得比较保守。换句话说,二阶段提交协议没有设计较为完善的容错机制,任意一个节点的失败都会导致整个事务的失败。
针对以上问题又诞生了另一个算法:Paxos算法。
9.Paxos算法
Paxos算法实际上也是一个类2pc算法,而重点是引入了“过半性”的投票理念,通俗地讲就是少数服从多数的原则。此外,Paxos算法支持分布式节点角色之间的轮换,即当协调者出现问题后,参与者可以变成协调者工作。这极大地避免了分布式单点的出现,因此Paxos算法既解决了无限期等待问题,也提高了性能,是目前来说最优秀的分布式一致性协议之一。
Zookeeper用的是fast paxos 算法,如果采用paxos算法,可能会出现活锁问题。解决了活锁问题。此外,Google的Chubby lock service 也基于paxos算法来实现的