把zookeeper说清楚
什么是zookeeper?
zookeeper是一个高效的分布式协调服务,目的是为了用户的分布式应用程序提供协调服务。
1、zk是为其他别的分布式程序服务的。
2、zk本身就是一个分布式程序(只要半数以上的节点存活,zk就可以正常服务)
3、zk所提供的服务涵盖:主从协调、服务器节点动态上下线、统一配置管理、分布式共享锁、统一名称服务等。
4、虽说可以提供各种服务,但是zk在底层其实只提供了2个功能:
(1):管理(存储、读取)用户提交的数据。
(2):并为用户程序提供数据节点的监听服务。
zookeeper如何保证高可用?
zookeeper本身内部就是一个集群,所以zookeeper才高可用。
只要zookeeper内部半数以上节点存活,他就可以对外提供服务。
zookeeper内部怎么实现?
zookeeper是一个高可用的分布式管理与协调的框架,基于ZAB(原子消息广播协议)的实现。
zookeeper框架可以保证分布式环境中数据的一致性,也正是基于这种特性,使得zk成为解决分布式数据一致性问题的方案。
ZAB(原子消息广播协议):面试比较重要
CAS:也是zookeeper实现用到的。
1、顺序一致性:
从一个客户端发起的事务请求,最终会严格按照发起的顺序被应用到zk中去。
2、原子性:
所有事物请求的处理结果在整个集群中所有的机器上的应用情况都是一致的。
也就是说,不论你改zk集群中那个节点的数据,最终所有节点的数据都是一致的。不可能会出现数据不同步的情况,zookeeper做的事情就是数据同步。
举例说明:
zk有leader和follower两种角色,第一个请求(consumer1)打算将zk中的一个值value设置为1,第二个请求(consumer2)打算把zk中的这个value设置为2。只有第一个请求consumer1把leader及所有的follower中的value都设置成1以后,第二个请求consumer2才可以操作这个value。
具体是这样:第一个请求先把leader中的value设置为1,然后leader会同步其它follower告诉他们value=1;然后其它的comsumer才可以操作这个value,这期间相当于给value加了一把锁,其它的consumer是无法操作这个value的;
3、单一视图:
无论客户端连接的是哪一个zookeeper服务器,不论是leader还是哪个follower,看到的数据都是一致的。
zookeeper设计目标
目标1:简单数据结构
zookeeper是以简单数据结构来进行相互协调的。
目标2:可以构建集群
一般zookeeper是由3台或5台机器组成一个一个zookeeper集群。集群节点尽量是奇数节点,因为要通过选举策略来选举leader,类似于redis的投票策略。只要集群半数节点存活就可以对外提供服务。
目标3:顺序访问
对于每个客户端的每个请求,zookeeper都会分配以一个全局唯一的递增编号,这个编号反映了所有事物操作的先后顺序,应用程序可以使用zk的这个特性来实现更高层次的同步。
目标4:高性能
由于zookeeper将全量的数据存储在内存中,并直接服务于所有的非事务请求。因此尤其在读操作为主的场景下性能非常突出。
zookeeper的结构
zookeeper会维护一个具有层次关系的数据结构(像一棵树一样的,树状结构)。
zookeeper的组成
ZK server根据身份分为3种:leader、follower、observer,其中follower和observer统称为learner。
leader:负责客户端的writer类型的请求。
follower:负责客户端reader类型的请求,参与leader的选举。
observer:特殊的“follower”,可以接受客户端reader的请求,但不参与leader的选举。不接受任何同步的写入请求,只负责于leader同步数据。类似于一个watcher。例如:我们写一段Java代码来操作zk集群,那么这段代码就可以理解成是一个observer。相当于操作zk集群的客户端。
zookeeper的应用场景
zookeeper从设计模式角度来看,是一个基于观察者模式设计的分布式服务管理框架,它负责存储和管理大家都关心的数据,然后接受观察者的注册。
一旦数据发生变化,zookeeper就负责通知已经在zookeeper上注册的那些观察者做出相应的反应。从而实现集群中类似Master/Slave管理模式。
zookeeper的应用场景说明
1:配置管理
全局配置信息,例如:机器的配置列表、运行的开关设置、数据库配置信息等。
2:集群管理
zookeeper不仅帮我们维护当前集群中机器的服务状态,而且能帮我们选出一个“总管”leader,让这个leader来管理集群,并实现集群容错功能。
例如:1、希望知道当前集群中究竟有多少机器在工作。
2、对集群中机器的运行状态进行数据收集
3、对集群中每台机器的上下线操作
3:发布订阅
zookeeper是一个典型的发布/订阅模式的分布式管理与协调框架,开发人员可以使用zk进行分布式数据的发布与订阅。
4:数据库的切换
比如数据库挂了,zk可以通知服务有新的数据源。
5:分布式日志收集
日志收集统一管理。
6:zookeeper的特性就是分布式场景下的高可用,但原生API不好用。可以采用第三方客户端,如Curator框架,里面有对zk的api进行封装。
如果工作中用了zookeeper,而没用Curator。跟没用zookeeper一样,因为zookeeper原生的API太难用了。
zookeeper的缺点:
1:zookeeper不适合构建大集群
比如集群的数量很大,不是3-5个节点的zookeeper集群,而是几十个zookeeper集群,这时候如果所有的zookeeper节点做数据同步的话,时间延迟会很大,可能要10秒以上。
2:zookeeper不适合用在很严格的环境中
zk不适合用于数据更新很频繁的场合,因为zk节点间要做数据同步,更新频繁同步会有延迟。
zkServer.sh 服务端的相关命令
- 启动ZK服务: sh bin/zkServer.sh start
- 查看ZK服务状态: sh bin/zkServer.sh status
- 停止ZK服务: sh bin/zkServer.sh stop
- 重启ZK服务: sh bin/zkServer.sh restart
zkCli.sh 客户端命令
- 显示根目录下、文件: ls / 使用 ls 命令来查看当前 ZooKeeper 中所包含的内容
- 显示根目录下、文件: ls2 / 查看当前节点数据并能看到更新次数等数据
- 创建文件,并设置初始内容: create /zk “test” 创建一个新的 znode节点“ zk ”以及与它关联的字符串
- 获取文件内容: get /zk 确认 znode 是否包含我们所创建的字符串
- 修改文件内容: set /zk “zkbak” 对 zk 所关联的字符串进行设置
- 删除文件: delete /zk 将刚才创建的 znode 删除
- 退出客户端: quit
- 帮助命令: help