来源 | 说出你的愿望吧
来源 | juejin.im/post/5d0bd358e51d45105e0212dbjava
高并发分布式开发技术体系已然很是的庞大,从国内互联网企业使用状况,可发现RPC、Dubbo、ZK是最基础的技能要求。关于Zookeeper你是否是还停留在Dubbo注册中心的印象中呢?还有它的工做原理呢?经典应用场景呢?对前面三个问题,如若回答时没有本身的思路或者说并未了解,那么我以为我能够帮助到你去入门,并深化这些知识,让你在面试中更好地去回答。node
话很少说进入正题linux
回忆咱们学多线程的时候,网上有个图也是十分的有意思面试
其实咱们把线程换成进程,至关于每台服务上跑了一个程序,相同的应用程序运行于多个服务器集群上,是为了解决单台服务面对高并发处理不来的状况。而尝试去处理这些状况,咱们就会面临不少诸如此类的问题apache
好比说咱们如今是3台服务器的一个集群, 怎么保证全部机器共享的配置信息保持一致?tomcat
有一台机器挂掉了,其余机器如何感知到这一变化并接管任务?服务器
用户量忽然的爆增,须要增长机器来缓解压力,如何作到不重启集群而完成机器的添加?网络
分布式系统,怎么高效协同多台服务对同一网络文件进行写操做(网络并非即时的,它并不可靠,存在延时)?session
此时咱们就须要一个相似于线程协同机制的能让进程进行协同的工具数据结构
在apache上的许多开源项目都是以动物形象做为icon,好比tomcat就是一只猫,hive是只黄蜂等,zookeeper的工做就是把这些动物的行动进行协调
zookeeper就是一种用于分布式应用程序的高性能协调服务,它的特色就是数据是存于内存中的,持久化实如今日志中。它的内存相似于树形结构,且高吞吐低延迟,能够帮助咱们实现分布式统一配置中心,服务注册,分布式锁等 组成ZooKeeper服务的服务器必须彼此了解。它们维护内存中的状态图像,以及持久性存储中的事务日志和快照。只要大多数服务器可用,ZooKeeper服务就可用。客户端链接到单个ZooKeeper服务器。客户端维护TCP链接,经过该链接发送请求,获取响应,获取监视事件以及发送tick。若是与服务器的TCP链接中断,则客户端将链接到其余服务器。
1.JDK版本须要在1.6以上 2.下载:https://archive.apache.org/dist/zookeeper/zookeeper-3.5.2/zookeeper-3.5.2.tar.gz 3.解压后的conf目录,增长配置文件zoo.cfg 4.启动服务端 bin/zkServer.sh start 5.测试,客户端链接:bin/zkCli.sh -server 127.0.0.1:2181 zoo.cfg的关键配置有3个: tickTime=2000:一次心跳的基本时间, dataDir:数据与日志的存放处 clientPort:端口号
相似于Unix文件系统树形结构,每一个目录成为Znode节点,但它不一样于文件系统,它既能够视为文件夹,也能够视为文件来存放数据,可是咱们平时仍是得叫它节点,别叫文件夹这么掉价。
须要注意:同一个节点下的子节点名称不能相同,且命名是有规范的,它的路径是没有相对路径的概念的,都是绝对路径,任何开始都以"/"开始,最后就是,它存放数据的大小是有限制的
层次命名空间:就是上面已经提到的,相似于unix的文件系统,以"/"为根,节点能够包含关联数据和子节点,绝对路径 Znode:名称惟一,命名有规范,类型分4种:持久,顺序,临时,临时顺序,节点的数据构成以后再提
节点名称除下列限制外,可使用任何unicode字符:
1. null字符(\u0000)不能做为路径名的一部分; 2. 如下字符不能使用,由于它们不能很好地显示,或者以使人困惑的方式呈现:\u0001 - \u0019和\u007F - \u009F。 3. 不容许使用如下字符:\ud800 - uf8fff, \uFFF0 - uFFFF。 4. “.”字符能够用做另外一个名称的一部分,可是“.”和“..”不能单独用于指示路径上的节点,由于ZooKeeper不使用相对路径。下列内容无效:“/a/b/. / c”或“c / a / b / . . /”。 5. “zookeeper”是保留节点名。
由于个人电脑是window系统的,因此我找了一个window版本的zookeeper来进行演示
先大体解释一下各个目录的内容
bin ---> 包括了linux和window的运行程序的运行目录 conf ---> zookeeper的配置zoo.cfg contrib ---> 其余一些组件和发行版本dist- maven ---> maven发布下的一些jar包 docs ---> 文档 lib ---> 库 recipe ---> 一些应用实例 src ---> zookeeper的源码,由于zookeeper是java写出来的
启动bin目录下的zkServer.cmd,再启动zkClient.cmd便可,在我根本不知道该如何进行学习的时候,通常来讲输入help,-help,-h这些指令就能够获取到帮助,下图我就是在客户端输入了-help指令
由于命令都相对简单因此也不进行演示了,惟一须要注意的是要注意路径"/"的问题,好比 ls / 就是根目录,create /zk 123,还有各个命令的依托条件,好比create必需要提供父节点,delete节点时次节点不能有子节点等···
提供多种方式跟踪时间,ZooKeeper给每一个更新贴上一个数字,这个数字反映了全部ZooKeeper事务的顺序,严格的顺序意味着能够在客户机上实现复杂的同步原语 解释czxid、version、zoo.cfg中ticks配置
你可使用stat path或者ls2来查看这些信息
cZxid:建立该节点的 zxidctime:该节点的建立时间 mZxid:该节点的最后修改 zxidmtime:该节点的最后修改时间 pZxid:该节点的最后子节点修改 zxidcversion:该节点的子节点变动次数 dataVersion:该节点数据被修改的次数 aclVersion:该节点的ACL变动次数 aphemeraOwner:临时节点全部者会话id,非临时的为0 dataLength:该节点数据长度 numChildren:子节点数
这些数据都在从侧面告诉咱们,zookeeper是一个协调者
数据可复制,可备份。zookeeper能够快速地搭建一个集群,内部自带了这样的一些工具与机制,咱们只须要设置一些配置便可,保证服务可靠,不会成为单点故障
zookeeper的一些特色能够应用于大型分布式系统
Session会话
1.一个客户端链接一个会话,由zookeeper分配惟一会话id 2.客户端以特定的时间间隔发送心跳以保持会话有效, 3.超过会话超时时间未收到客户端的心跳,则判断客户端无效(默认2倍tickTime) 4.会话中额请求是FIFO(先进先出原则)的顺序执行
节点数据:存储的基本信息(状态,配置,位置等) 节点元数据:stat命令下的一些数据 数据大小:限制1M
1.持久节点:直接经过create path value所建立 2.临时节点:create -e path value 3.顺序节点:create -s path value 注意 1.session会话失效时,临时节点就会被删除 2.顺序节点的建立,后为10位十进制序号,每一个父节点拥有一个计数器,这个计数器也是有限制的,到2147483647以后将溢出 3.顺序节点在会话结束仍然存在
客户端能在znodes上设置watch,监听znode的变化,包括增删改查,经过stat path ,ls2 path get path皆可查看
触发watch事件的条件有4种,create,delete,change,child(子节点事件)
watch的重要特性
1.仅一次性:watch触发后会当即删除,要持续监听变化的话就要持续提供设置watch,这也是watch的注意事项 2.有序性:客户端先获得watch通知才可查看变化结果
watch的注意事项
1.刚刚说起到的它的仅一次性 2.获取事件和发送watch,获取watch,这些请求有可能存在延时,因此不能绝对可靠获得每一个节点发生的每一个更改 3.一个watch对象只会被通知一次,若是一个watch同时注册了多个接口(exists,getData),若是此时删除节点,虽然这个事件对exists和getData都有效,可是watch只会被调用一次
阻塞线程唤醒机制—客户端能够被动接受其余客户端进程状态通知
1.顺序一致性(Sequential Consistency),保证客户端操做是按顺序生效的; 2.原子性(Atomicity),更新成功或失败。没有部分结果。 3.单个系统映像,不管链接到哪一个服务器,客户端都将看到相同的内容 4.可靠性,数据的变动不会丢失,除非被客户端覆盖修改。 5.及时性,保证系统的客户端当时读取到的数据是最新的。
=======
经过上面的阐述应该咱们对于zookeeper有了一个初步的认识,以后会陆续说说分布式锁,集群还有一些场景的应用