前言在分布式系统中,注册中心起着举足轻重的作用,是服务发现和客户端负载均衡不可或缺的一员。除了注册中心的基本功能外,其稳定性、可用性和健壮性对整个分布式系统的平稳运行有很大的影响。dubbo作为国内主流的分布式系统,在注册中心支持zookeeper、nacos、redis等第三方中间件。高并发分布式开发技术体系已经非常庞大。前段时间一直在准备找工作,参加了面试。通过面试可以发现RPC、Dubbo、zookeeper、nacos、分布式、微服务等都成为了求职利器。最基本的技能要求。之前有一篇文章介绍了如何使用nacos作为注册中心:SpringCloud:搭建Nacos服务与服务发现。其实不仅nacos可以作为注册中心,zookeeper也可以作为注册中心。但是Zookeeper不仅仅可以作为注册中心。对于Zookeeper,其官方文档中的解释是:它是一个分布式服务框架,是ApacheHadoop的一个子项目,主要用于解决分布式应用中经常遇到的一些数据管理问题,例如:统一命名服务,状态同步服务、集群管理、分布式应用配置项的管理等。可以理解为zookeeper是一个文件系统+监控通知机制。在今天的文章中,让我们一起来学习和学习Zookeeper。我也在学习中!什么是zookeeper随着系统应用的扩展和数据量的保证,我们的系统经常会遇到这些情况:如何保证一个服务器集群中的所有服务器保持共享配置信息的一致性?如果服务器集群中的一台机器挂掉了,其他机器如何感知这个变化并接管任务呢?对于分布式系统,如何高效协调多个服务写入同一个网络文件并保持一致性?如何在不重启集群的情况下添加机器?......为了解决以上问题,需要一个类似于线程协调机制的工具,让各种服务协同工作。Zookeeper就是这样一个工具。上面提到Zookeeper在其官方文档中是这样解释的:它是一个分布式服务框架,是ApacheHadoop的一个子项目。主要用于解决分布式应用中经常遇到的一些数据管理问题,如:统一命名服务、状态同步服务、集群管理、分布式应用配置项管理等。所以可以理解为zookeeper是一个高性能的协调服务,可以用在分布式应用中。它的数据存储在内存中,它的持久化是在日志中实现的。并且其内存结构类似于树形结构,具有高吞吐量和低延迟的特点。Zookeeper不仅可以帮助我们实现分布式的统一配置中心、服务注册、分布式锁等,他们在内存中维护状态图像,在持久化存储中维护事务日志和快照。只要大多数服务器可用,ZooKeeper服务就可用。客户端连接到单个ZooKeeper服务器。客户端维护一个TCP连接,它通过该连接发送请求、获取响应、获取监视事件并发送报价单。如果与服务器的TCP连接丢失,客户端将连接到不同的服务器。所以可以简单的认为zookeeper=文件系统+监控通知机制。我们也可以这样理解:zookeeper的中文意思就是动物园管理员(zoom+keeper)。动物园管理员的作用是管理动物园里的动物,使它们保持秩序。Zookeeper是apache下的一个开源项目。apache下的很多开源项目其实都是用动物作为图标的,比如Hadoop(大象)、Hive(蜜蜂)、Pig(猪)、tomcat(猫)。所以可以记住apache下的项目就是zoo,zookeeper就是负责管理这些动物的zookeeper(开源项目)。Zookeeper的数据结构Zookeeper会维护一个层次化的数据结构,这与标准的文件系统非常相似:上图中树形结构中的每个节点(目录项),比如NameService,称为一个znode(目录节点)。Zondes由路径引用,路径必须是绝对的,因此它们必须以斜杠字符开头。此外,它们必须是唯一的,这意味着每条路径只有一种表示,因此这些路径不能更改。在zookeeper中,路径由具有一些限制的Unicode字符串组成。字符串“/ZooKeeper”用于保存管理信息,如密钥配额信息。znode同时具有文件和目录的特性。它不仅可以像文件一样维护数据、元信息、访问控制列表)、时间戳等数据结构,还可以像目录一样作为路径标识的一部分,可以自由增删znode。每个znode由三部分组成:stat:这是状态信息,描述znode的版本,权限等信息data:与znode关联的数据children:znode下的子节点需要注意相同node子节点名称不能重名,命名规范。它的路径没有相对路径的概念,是绝对路径。一切都以“/”开头。最后,其存储数据的大小是有限的。的。Zookeeper节点类型Zookeeper中有两种节点类型,即临时节点(EphemeralNode)和永久节点(PersistentNode)。节点的类型是在创建时确定的,不能更改。两个节点的区别在于是否依赖会话(Session)生存。客户端和ZooKeeper服务器之间的连接称为会话。客户端通过与服务器建立长TCP连接来维护会话。客户端启动时,会先与服务器端建立TCP连接。通过这个连接,客户端可以通过心跳检测与服务器保持有效的会话,也可以向ZooKeeper服务器发送请求并得到响应。(1)临时节点:节点的生命周期取决于创建它们的会话。一旦会话结束,临时节点将自动删除,但也可以手动删除。虽然每个临时Znode都绑定到一个客户端会话,但它们仍然对所有客户端可见。另外zookeeper的临时节点是不允许有子节点的。临时节点又可以细分为:临时目录节点和临时序号目录节点。临时目录节点(EPHEMERAL):客户端与zookeeper断开连接后,该节点被删除。临时序号目录节点(EPHEMERAL_SEQUENTIAL):客户端与zookeeper断开连接后,该节点被删除,但zookeeper对节点名进行顺序编号。(2)永久节点:节点的生命周期不依赖于会话,只有在客户端执行删除操作时才能被删除。临时节点又可以细分为:持久目录节点和持久序号目录节点。持久目录节点(PERSISTENT):客户端与zookeeper断开连接后,该节点仍然存在。持久序号目录节点(PERSISTENT_SEQUENTIAL):客户端与zookeeper断开连接后,该节点仍然存在,但zookeeper对节点名进行顺序编号。上面的分类有一个概念叫做顺序节点:用户在创建节点时,可以请求在zooKeeper路径的末尾增加一个增量计数。这个计数对于这个节点的父节点是唯一的。当客户端请求创建这个节点时,zookeeper会根据父节点的zxid状态为这个节点写入一个唯一的编号,这个编号只会一直增加。这样的节点称为顺序节点。上面提到了一个叫做zxid的概念:对于每一个改变zookeeper节点状态的操作,这个节点都会收到一个Zxid格式的时间戳,这个时间戳是全局有序的。可以这样理解,每一次改变节点的操作都会产生一个唯一的交易id,叫做Zxid。如果Zxid1的值小于Zxid2的值,则可以认为Zxid1对应的事件先于Zxid2对应的事件发生。实际上zookeeper的每个节点都维护了两个Zxid值,即:cZxid和mZxid。cZxid:指节点创建时间对应的Zxid格式时间戳。mZxid:指节点修改时间对应的Zxid格式时间戳。在实现中,Zxid是一个64位的数字,其高32位是epoch(投票),用来标识Leader关系是否发生了变化。每选举出一个Leader,都会有一个新的epoch。第32位是增量计数。zookeeper的特点1.有序性Zookeeper提供了多种时间跟踪方式。Zookeeper为每个更新附加一个数字(上面提到的zxid)。这个数字反映了所有zookeeper事务的顺序。严格的顺序意味着它可以在复杂的客户端上实现同步。除了上面提到的zxid,version和zoo.cfg中还有ticks配置。版本号(versionnumber):版本号用于记录节点数据或节点子节点列表或权限信息的修改次数。如果节点的版本为1,则表示该节点自创建以来已经修改过一次。每个节点维护三个版本号,分别是:version:节点数据版本号。cversion:子节点版本号。aversion:节点拥有的ACL版本号。对一个节点的写请求会导致该节点的三个版本号增加,原理和乐观锁类似。ticks:zoo.cfg文件中的配置。使用多服务器zookeeper时,服务器使用一个“tick”来定义事件发生的时间,比如状态上传,session超时等,通过最小sessiontimeout(默认为ticktimex2)间接暴露,如果客户端请求超过这个时间,则客户端无法再连接到服务器。实时:zookeeper不使用实时。所以可以理解为zookeeper是一个协调者,有序的进行一些交互连接!高速。前面说了,zookeeper的数据加载在内存中,所以有高吞吐低延迟的效果。而且读取的速度特别快,而且操作的znode大小限制在1m以内。正是这些特点,使得zookeeper适用于大型分布式系统。2、可复制的zookeeper数据可以复制备份。Zookeeper可以快速搭建一个集群,它内部自带了一些工具和机制。我们只需要设置一些配置就可以保证服务可靠,不会成为单点故障。如下:watcher机制Zookeeper允许用户在指定的节点上注册一些Watcher。当数据节点发生变化时,zookeeper服务器将向感兴趣的客户端发送此更改的通知。这是zookeeper的核心特性,zookeeper的很多功能都是基于这个特性实现的。如果两个客户端都在zookeeper集群中注册了watcher(事件监听器),那么当zookeeper中的节点数据发生变化时,zookeeper会向客户端发送这个变化的通知,当客户端收到这个变化的通知时,一定预先定义的动作将被触发。一般来说,zookeeper只会向客户端发送一个通知。如果一个watch同时注册了多个接口(exists、getData),如果此时节点被删除,虽然这个事件对exists和getData都有效,但是watch只会被调用一次。并且这些请求可能存在延迟,因此无法绝对可靠地获取每个节点上发生的每个更改。手表被触发后,会立即被删除。如果你想继续监测变化,你需要继续为手表提供设置。并且客户端只有在收到手表通知后才能查看更改结果。触发watch事件的条件有4个,create、delete、change、child(子节点事件)。所以zookeeper的特点可以总结为:1.原子性,更新成功还是失败。没有部分结果。2、可靠性:数据变化不会丢失,除非被客户端覆盖修改。3、实时性:系统客户端当时读取的数据是最新的。4、有序性:客户端操作有序生效。5、一致性:又称单一系统镜像,无论连接哪台服务器,客户端看到的内容都是一样的。综上所述,以上就是对zookeeper的简单介绍。这也是一个学习的过程。总结了一些关于zookeeper的概念和相关知识点。
