# zookeeper-practice **Repository Path**: xiaochen2050/zookeeper-practice ## Basic Information - **Project Name**: zookeeper-practice - **Description**: zookeeper原理、架构、使用场景和可视化 - **Primary Language**: Java - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 18 - **Created**: 2018-12-26 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # zookeeper-practice zookeeper是Apache开源的顶级项目,用于提供一个高性能、高可用,且具有严格的顺序访问控制能力(主要是写操作的严格顺序性)的分布式协调服务。可用于在分布式环境中保证数据的一致性,拥有非常广泛地使用场景。 ### 架构特点 zookeeper会在内存中维护一个树状的目录结构,由奇数个服务器构成集群,且每台服务器上的数据是相同的。只要一半以上的服务器正常,就能正常对外提供服务。由于zookeeper的数组都在内存中,也使得它具有很高的读取性能。zookeeper只允许存在一个leader服务器用于接受客户端提交的数据,还包含follower和observer两种节点。 ![输入图片说明](https://images.gitee.com/uploads/images/2018/0919/081346_db74f379_1110335.jpeg "08171345_l5K3.jpg") ![输入图片说明](https://images.gitee.com/uploads/images/2018/0919/081455_3bd9c7b4_1110335.jpeg "08171344_cqXs.jpg") 1. 每个Server在内存中存储了一份数据; 2. Zookeeper启动时,将从实例中选举一个leader(Paxos协议); 3. Leader负责处理数据更新等操作(Zab协议); 4. 一个更新操作成功,当且仅当大多数Server在内存中成功修改数据。 ### 核心概念 - **会话session** 指客户端与zookeeper服务器建立的TCP长连接,通过这个连接与服务器交互,比如心跳检测、请求数据、接收服务器监听的消息等。如果客户端断开并超时,则会话失效。 - **数据节点Znode** 指的是zookeeper中保存的数据信息,是一个路径,例如/foo/path。每个节点上可以保存一些内容和属性信息。它的节点可分为持久节点和临时节点两种。持久节点创建以后需要手动删除,临时节点随着会话失效自动删除。所有的非叶子节点必须为持久节点。另外,节点可以添加一个SEQUENTIAL属性,使得节点创建时会追加一个父节点维护的自增数字。巧妙利用这些特点可以用于实现分布式锁。 - **版本号** 每个Znode有一个Stat的数据结构,记录了该节点的三个数据版本号,数据更新时版本号会发生变化。 - **事件监听器Watcher** 允许客户端在节点上注册事件监听器,当特定的事件发生时(如节点创建、删除等),客户端会收到服务器的通知,监听器触发后会被自动删除,该特性可用于实现分布式协调。 - **ACL权限控制策略** zookeeper包含五种权限,Create--创建子节点,Read--获取节点数据和子节点列表,Write--更新子节点数据,DELETE--删除子节点,ADMIN--设置节点ACL的权限。 ### 一致性算法 zookeeper并非完全是按照paxos来实现的算法保证数据一致性,而是使用了一种基于ZAB协议的算法。ZAB协议包括两种模式:崩溃恢复、消息广播。当leader服务器宕机重启,或者过半服务器无法与leader服务器正常通信时,进入崩溃恢复模式重新选举leader;当leader服务器正常且过半服务器与leader完成了数据同步时,进入消息广播模式。ZAB协议消息广播的流程是: 1. 客户端发起事务请求 2. Leader服务器为客户端生成事务的提案proposal,将其发送给followers 3. followers提交自己的ACK反馈 4. 只要leader接到过半follower的反馈,就通知followers提交事务 ![输入图片说明](https://images.gitee.com/uploads/images/2018/0918/161631_e30e860d_1110335.png "QQ截图20180918161607.png") ZAB协议会确保在leader服务器上成功提交的事务会同步到所有的follower服务器。如果leader只将提案下发到了部分的follower就崩溃了的话,那么这样的提案就要被丢弃。ZAB协议并不是一个Paxos算法的典型实现,但是存在一定的共性。 ### 集群搭建 1. 进入zookeeper目录,到conf文件夹下,把zoo_sample.cfg文件复制一份,命名为zoo.cfg; 2. 在zoo.cfg添加日志和数据路径,以及集群对应的端口,例如: ``` dataDir=/home/wang/zookeeper-3.4.6-01/data dataLogDir=/home/wang/zookeeper-3.4.6-01/logs server.1=10.172.88.13:2881:3881 server.2=10.172.88.17:2882:3882 server.3=10.172.88.15:2883:3883 ``` 3. 进入data目录下创建文件myid,填入服务器编号; 4. 进入bin目录,启动 ``` ./zkServer.sh start ``` 5. jps命令用来查看zookeeper是否启动,tail -500f zookeeper.out用来查看控制台输出。 ### 写入数据的流程 1. 客户端首先和一个Server或者Observe(可以认为是一个Server的代理)通信,发起写请求 2. Server将写请求转发给Leader,Leader再将写请求转发给其他Server 3. Server在接收到写请求后写入数据并响应Leader,Leader在接收到大多数写成功回应后,认为数据写成功,响应Client。 ### 客户端编程 使用zookeeper官方原生的API也能对zookeeper进行增删改查,但是用起来不太方便。比较流行的客户端有zkClient和Curator。本项目演示Curator的使用。包括: - 对zookeeper节点增删改查 - 对指定节点或子节点的变化进行监听 - master选举 - 分布式锁 - 分布式计数器 ### 使用场景 1. **实现数据的发布和订阅** :可以把一些可能变化的配置数据放入zookeeper服务器,客户端可以订阅并监听这个配置,一旦配置更新,就可以重新获取配置。 2. **命名服务** :有时分布式系统需要一些命名,比如提供RPC服务地址的名称、全局唯一不能重复的主键等,利用zookeeper节点不重名的特点可以进行命名服务。 3. **master选举**:有时分布式系统中存在多台服务器,必须选出一台master来执行特定的计算任务,master挂掉后,自动重新选出一台服务器担任master执行任务。这种情况可以使用zookeeper来实现,多个客户端创建同一个临时节点,只有一个可以成功,成功的节点就是master,其他客户端监听该节点,一旦被删除,说明master宕机,重新开始新的选举。 4. **负载均衡**:在消息队列的集群中,消息生产者需要比较均衡地将消息投递到不同的消息代理上,这里就涉及到负载均衡的使用。 5. **分布式锁**: 后台接口分布式部署了以后,为了避免出现不同服务器的线程同时修改同一个数据引起并发问题,需要进行跨主机跨进程的线程同步,这是就用到分布式锁,主要基于zookeeper的临时有序节点来实现。 6. **分布式队列** :客户端提交的任务信息可以保存到zookeeper中,利用zookeeper有序节点的特性,实现一个先进先出的队列,zookeeper可以记录任务提交的拓扑信息并保持任务的有序调度。 7. **分布式协调和通知** :可以实现不同机器之间心跳监测(临时有序节点是否存在)、数据通信(向节点写入数据并监听变化)等场景。 8. **集群管理** :每个集群的机器可以向zookeeper添加一个临时有序节点,只要节点存在表示机器存活。利用这个特点可以完成集群服务器的监控。还可以将主机的状态信息写入zookeeper的节点,监控中心订阅这些节点的数据来获得主机的实时信息。 ### 应用举例 - dubbo框架的服务注册中心使用zookeeper,服务提供者和消费者的地址是一种 **命名服务** ,服务提供者把地址列表 **发布** 到zookeeper,消费者 **订阅** 了对应的节点数据来获取地址,当服务上线或下线时,消费者的监听器会收到通知。 - storm中使用zookeeper实现 **分布式队列** ,以可靠地保存任务的拓扑信息和调度信息。 - YARN的资源管理器是使用zookeeper的 **master选举** 来保持资源管理器的主备架构,创建临时节点成功的机器成为master,其他备用资源管理器监听这个节点,一旦这个节点被删掉就重新选举,实现主备切换。同时,YARN还可以将一些资源管理器的状态信息保存在zookeeper的节点之中,实现对 **集群的管理** 。 - Hbase中的zookeeper实现对Hmaster的 **master选举** ,主备切换,以及各种元数据的存储记录,实现对 **集群服务器的监控和管理** 。 - kafka中zookeeper通过临时节点记录了消息服务器的信息,还记录了消息分区的信息,实现集群的管理。zookeeper还起到了 **负载均衡** 的作用,将消息均匀地发送到各个服务器上。 - canal在做数据同步的过程中,canal server集群的 **master选举** 和主备切换依赖于zookeeper。canal client也会监听server的节点,根据节点的最新变化从服务器端获取数据库操作。数据日志最后一次消费成功的位点信息也会被记录到zookeeper的节点中,避免数据的重复消费。 ### 可视化 这里可以使用zkui进行zookeeper的可视化管理https://github.com/DeemOpen/zkui #### 配置方法 1. 下载后,mvn clean install 2. 将config.cfg复制到上一步生成的jar文件所在目录,然后修改配置文件中的zookeeper地址,延长超时时间避免连接失败。 ``` zkServer=192.168.197.128:2181 zkSessionTimeout=25 ``` 3. 运行生成的jar文件 ``` java -jar zkui-2.0-SNAPSHOT-jar-with-dependencies.jar ``` 4. 测试,http://localhost:9090,如能看到登录页面则代表zookeeper安装运行正常。 5. 默认用户名密码为username:admin , password:manager。 ### 效果图 ![输入图片说明](https://images.gitee.com/uploads/images/2018/1010/085930_e864d10a_1110335.png "QQ截图20181010085901.png") ### 附录:个人作品索引目录(持续更新) #### 基础篇:职业化,从做好OA系统开始 1. [SpringMVC,Mybatis,Spring三大框架的整合实现增删改查](https://gitee.com/shenzhanwang/SSM) 2. [Struts2,Hibernate,Spring三大框架的整合实现增删改查](https://gitee.com/shenzhanwang/S2SH) 3. [Spring,SpringMVC和Hibernate的整合实现增删改查](https://gitee.com/shenzhanwang/SSH) 4. [Spring平台整合activiti工作流引擎实现OA开发](https://gitee.com/shenzhanwang/Spring-activiti) 5. [Spring发布与调用REST风格的WebService](https://gitee.com/shenzhanwang/Spring-REST) 6. [Spring整合Apache Shiro框架,实现用户管理和权限控制](https://gitee.com/shenzhanwang/Spring-shiro) 7. [使用Spring security做权限控制](https://gitee.com/shenzhanwang/spring-security-demo) 8. [Spring整合Jasig CAS框架实现单点登录](https://gitee.com/shenzhanwang/Spring-cas-sso) #### 中级篇:中间件的各种姿势 9. [Spring连接mongoDB数据库实现增删改查](https://gitee.com/shenzhanwang/Spring-mongoDB) 10. [Spring连接Redis实现缓存](https://gitee.com/shenzhanwang/Spring-redis) 11. [Spring连接图存数据库Neo4j实现增删改查](https://gitee.com/shenzhanwang/Spring-neo4j) 12. [Spring平台整合消息队列ActiveMQ实现发布订阅、生产者消费者模型(JMS)](https://gitee.com/shenzhanwang/Spring-activeMQ) 13. [Spring整合消息队列RabbitMQ实现四种消息模式(AMQP)](https://gitee.com/shenzhanwang/Spring-rabbitMQ) 14. Spring框架的session模块实现集中式session管理(未开源) 15. [Spring整合websocket实现即时通讯](https://gitee.com/shenzhanwang/Spring-websocket) 16. 使用Spring boot整合mybatis,rabbitmq,redis,mongodb实现增删改查(未开源) 17. [Spring MVC整合FastDFS客户端实现文件上传](https://gitee.com/shenzhanwang/Spring-fastdfs) 18. 23种设计模式,源码、注释、使用场景(未开源) 19. 使用ETL工具Kettle的实例(未开源) 20. Git指南和分支管理策略(未开源) #### 高级篇:架构之美 21. [zookeeper原理、架构、使用场景和可视化](https://gitee.com/shenzhanwang/zookeeper-practice) 22. Spring框架整合dubbo框架实现分布式服务治理(SOA架构)(未开源) 23. Spring框架整合dubbox实现微服务架构(MSA架构)(未开源) 24. 使用Spring Cloud实现微服务架构(MSA架构)(未开源) 25. 使用jenkins+centos+git+maven搭建持续集成环境自动化部署分布式服务(未开源) 26. 使用docker+compose+jenkins+gitlab+spring cloud实现微服务的编排、持续集成和动态扩容(未开源) 27. 使用FastDFS搭建分布式文件系统(高可用、负载均衡)(未开源) 28. 搭建高可用nginx集群和Tomcat负载均衡(未开源) 29. 搭建可扩展的ActiveMQ高可用集群(未开源) 30. 实现Mysql数据库的主从复制、读写分离、分表分库、负载均衡和高可用(未开源) 31. 搭建高可用redis集群实现分布式缓存(未开源) 32. [Spring整合SolrJ实现全文检索](https://gitee.com/shenzhanwang/Spring-solr) #### 特别篇:分布式事务和并发控制 33. 基于可靠消息最终一致性实现分布式事务(activeMQ)(未开源) 34. 使用TCC框架实现分布式事务(dubbo版)(未开源) 35. 使用TCC框架实现分布式事务(Spring Cloud版)(未开源) 36. 决战高并发:数据库锁机制和事务隔离级别的使用(未开源) 37. 决战高并发:使用redis实现分布式锁(未开源) 38. 决战高并发:使用zookeeper实现分布式锁(未开源) 39. 决战高并发:Java多线程编程实例(未开源) 40. 决战高并发:使用netty实现高性能NIO通信(未开源) ### 捐赠区 ![输入图片说明](https://images.gitee.com/uploads/images/2018/0719/154323_12a5c89c_1110335.jpeg "mm_facetoface_collect_qrcode_1531986023521.jpg")