ZOOKEEPER(关键点:Watcher和服务注册发现)

https://blog.csdn.net/varyall/article/details/79564418

ZooKeeper的基本运转流程:

1、选举Leader。

2、同步数据。

3、选举Leader过程中算法有很多,但要达到的选举标准是一致的。

4、Leader要具有最高的执行ID,类似root权限。

5、集群中大多数的机器得到响应并接受选出的Leader。[3]

 

那么Zookeeper能做什么事情呢,简单的例子:假设我们有20个搜索引擎服务器(每个负责总索引中的一部分的搜索任务)和一个总服务器(负责向这20个搜索引擎的服务器发出搜索请求并合并结果集),一个备用的总服务器(负责当总服务器宕机时替换总服务器),一个web的cgi(向总服务器发出搜索请求)。搜索引擎的服务器中的15个服务器提供搜索服务,5个服务器正在生成索引。这20个搜索引擎的服务器经常要让正在提供搜索服务的服务器停止提供服务开始生成索引,或生成索引的服务器已经把索引生成完成可以提供搜索服务了。使用Zookeeper可以保证总服务器自动感知有多少提供搜索引擎的服务器并向这些服务器发出搜索请求,当总服务器宕机时自动启用备用的总服务器。

 

zookeeper的常用方法:(首先需要创建ZOOKEEPER对象, 后续一切操作基于此对象)

1.create:创建znode         delete:删除znode

2.ls  path:查看path下子node列表 例:查看根节点下所有子节点:ls  /    此命令只能查看节点看不到节点下的数据(下面无节点时显示空数组符号)

5.get  path:查看path下的数据内容和属性信息

3.exists:判断子node是否存在

4.setData:更新node中关联的数据

 

什么是znode?

zookeeper中节点称为znode,对zk的操作主要是对znode的操作:

节点类型:

根据节点的存活时间将节点分为持久节点和临时节点,节点的类型在创建时被确定下来并且不能改变。

持久节点的存活时间不依赖于客户端会话,只有客户端显示删除节点该节点才消失。

临时节点的存活依赖于客户端会话,会话结束时临时节点被自动删除。(利用临时节点的这一特性可以使用临时节点进行集群管理,包括发现服务的上下线等。)

zookeeper规定,临时节点不能拥有子节点。(子节点应该就是node)

(其实还有一种顺序节点的节点类型)

节点的数据:

创建节点时可以指定节点中存储的数据,zookeeper保证读写都是原子的操作,且每次读写操作都是对数据的完整读或写操作,不提供对数据的部分读取或部分写的操作。

zookeeper虽然提供在节点存储数据的功能,但并不将自己定位为数据库,也就是说你不应该在节点存储过多的数据,zk规定数据大小不能超多1m,实际上我们应该让znode的数据量尽量小,否则会导致zk性能下降,需要大量数据时可用分布式数据库解决,如redis。

 

事务id:

对于zk,每次的事务变化都会产生一个唯一的事务id,通过id可以确定操作的先后顺序,如果id1<id2,则id1操作先于id2操作执行。此id可解决客户端重连的问题。

 

 

 

书籍:

zookeeper规定,每一个节点的机器只有三种角色中的一种,leader,follower和观察者observer。observer机器不参与选举,所有机器都提供读服务,只有leader提供写服务。

zookeeper中,一个会话session是指客户端和服务端间的一个TCP长链接,zookeeper默认端口是2181.session的sessionTimeout用来设置超时时间,只要在超时时间内可以重连上集群中任意一台服务器,之前创建的会话任然有效。

通常说的节点是集群中的某个节点,zookeeper中的节点有两类,一类是集群中的机器称为机器节点,另一类是数据模型中的数据单元称为数据节点znode。数据模型是一棵树,由/分割的路径就是一个znode。

事件监听器watcher是zk的一个重要特性,zk允许用户在指定节点上注册watcher,在特定事件触发的时候,zk服务器将将事件通知到感兴趣的客户端去,此机制是zk实现分布式协调服务的重要机制。

zk使用ZAB协议(zk原子消息广播协议)作为数据一致性的核心 算法:

使用一个单一的主进程来接收并处理所有客户端的事务请求,将服务器数据的状态变更以事务propasal的形式广播到所有的副本进程中。(保证同一时刻集群中只有一个进程在广播服务器的状态变更。)

所有事务请求必须由一个全局唯一的服务器来协调处理,即leader服务器,剩下的服务器即成为follower服务器,leader服务器负责将客户端的一个事务请求装换成一个事务提议proposal并将该事务提议分发给所有follower,一旦超过半数的follower有正确的反馈,leader便向所有follower分发提交该事务提议的消息。

ZAB包括两种模式:崩溃恢复和消息广播。

整个服务框架启动中,或leader服务器崩溃,异常,网络中断中等,ZAB协议则开始进入崩溃恢复模式选举产生新的leader。

leader产生并且leader和半数的机器完成数据同步则进入消息广播模式。

已经有leader是,新加入的服务器会找到leader进行数据同步,然后一起参与到消息广播流程中。非leader的机器接收到事务请求后会转发给leader。

当leader服务器出现崩溃,或不存在过半的服务器与其保持正常通信,ZAB会进入崩溃恢复模式,直到彼此保持一致的状态。

一个机器要称为leader,必须获得过半及进程的支持,每个机器可能随时崩溃,前后会出现多个leader,ZAB协议运行过程中可能会出现多个leader,三台机器组成的ZAB服务,通常由一个leader和两个follower组成,其中一个follower挂了,整个ZAB集群是不会中断服务的。这是因为leader仍然能获得过半机器的支持(包括自己)

消息广播:

leader将事务提议peopasal广播给所有机器并收集各机器的ack响应,超过半数则进行事务提交。所有的follower要么正常反馈leader提出的事务propasal,要么就抛弃leader服务器。整个消息广播协议使用具有FIFO特性的TCP协议来进行网络通信。

leader服务器会为每个事务请求生成对应的提议进行广播,广播前会为每个提议生成一个全局单调递增的唯一id,即事务id/ZXID。每个事务提议按照其事务id的先后顺序来进行排序与处理(放入FIFO队列进行发送)。每个follower接收到事务提议后在本地磁盘写入事务日志,成功写入后反馈给leader一个ack响应。leader接收到超过半数的ack响应后,广播一个commit消息给所有follower,follower接收到commit消息后会完成对事务的提交,leader自身也会完成对事务的提交。

崩溃恢复:

leader提出p后崩溃,恢复后需要丢弃p,提出c后崩溃,恢复后需要继续c:新leader拥有最高事务id的事务提议,新leadre便一定有所有已提交的提案。

数据同步:

leader选举后,正式工作前(接收客户端事务请求并提出新提案)。leader会先确认事务日志中所有propasal提议是否被过半的机器提交(是否完成数据同步),(数据同步完成后会有通知,不然事务日志没法查看。)

 

zookeeper使用:

一:建立zk服务

1.下载解压到某路径,下文用%ZK_HOME%代表该解压路径(每台机器都要有zookeeper服务因此每台机器都要安装解压zookeeper)。

2.给每台机器配置zoo.cfg和zoo.cfg里配置数据路径下的myid文件:

将%ZK_HOME下conf目录下zoo_sample.cfg按下面配置并重命名为zoo.cfg:

tickTime=2000

dataDir=/var/lib/zookeeper/

clientPort=2181(不同ip的机器可以不一样,一般都是2181。zookeeper服务器对外服务的端口,供客户端连接使用。)

initLimit=5

syncLimit=2

server.1=IP1:2888:3888(第一个端口供leader和follower同步数据使用,第二个端口供选择leader时通信使用)

server.2=IP2:2888:3888

server.3=IP3:2888:3888

集群中的每个机器需要感知整个集群由哪些机器组成,每台机器都需要有上面相同的配置文件。配置文件中可按此格式进行配置,每行代表一个机器配置:

server.id=host:port:port

同时每台机器的数据目录下(dataDir)要创建一个myid文件,该文件只有一行内容,并且是一个数字,即每台机器的serverID数字。注意要和zoo.cfg配置文件中的serverid对应,并且范围为1-255.

 

 

单机模式:

zoo.cfg中只配置一个机器

伪集群模式(同集群模式一样,要安装解压三个zookeeper并在不同的端口提供服务(同一台机器上的三个zookeeper服务肯定不能用同一个端口来提供服务)):

zoo.cfg中配置的多个server的ip相同,毕竟是集群,所以每个服务节点对外服务端口只能不同(因为在一台机器上),同步数据端口和选举leader通信端口当然也不能相同(因为在一台机器上)

server.1=IP1:2888:3888

server.2=IP1:2889:3889

server.3=IP1:2890:3890

伪集群模式注意dataDir和dataLogDir不要配置的一样了,不然不同节点的数据等难以区分。

 

3.启动/停止zk服务:

执行%ZK_HOME%下的bin下的zkServer.sh脚本。

sh  zkServer.sh  start

sh  zkServer.sh  stop

windows系统为zkServer.cmd

 

zk的启动类:QuorumPeerMain

1.读取并封装zoo.conf配置文件为Properties类

2.启动定时清除服务任务来清除过期的日期和数据快照:purgeMgr.start();

3.

公司系统的zk服务是怎么启动的(注意问题是启动,不是连接!)?????

二:使用脚本客户端连接zk服务并操作zk节点

1.客户端脚本(连接zk服务):

zk.Cli,执行此脚本输出一下信息变表示连接zk服务器成功:

WATCHER::
WatchedEvent state:SyncConnected type:None path:null
[zk: localhost:2181(CONNECTED) 0]

默认是连接本地的zk服务器,连接指定服务器可如下:

sh  zkCli.sh  -server  ip:port

或zkCli.cmd  -server  ip:port

 

2.操作zk节点(path均指内存中的zk节点的逻辑路径,不是具体的硬盘的路径):

create   path   data

默认为持久节点,可使用-s  -e控制创建临时或顺序节点,创建时并可使用acl进行节点的权限控制。

查看指定节点下的一级节点:

ls  path

查看指定节点的数据及属性

get  path

更新节点(每更新一次dataVersion都会加1)

set  path  data  dataVersion(用于指定更新哪个版本,可不指定)

删除节点(只能删除掉没有子节点的节点)

delete path  dataVersion(用于指定删除哪个版本,感觉没用呀,只要删除一次节点就不存在了无所谓版本了。。)

三:使用java客户端API连接zk服务

1.创建ZooKeeper实例来连接zk服务器:

Zookeeper构造方法参数说明:

connectString:逗号分开的ip:端口字符串,组成zk集群,同时可设置连上zk后的根目录如"ip1:port,ip2:port,ip3:port/zk-book",之后所有对zk的操作都会基于这个根目录。

三个机器上的三个目录还是只有leader的一个目录?

sessionTimeout:会话的超时时间,zk的客户端和服务器会通过心跳检测机制来维持会话的有效性,一旦在sessionTimeout内没有进行有效的心跳检测,会话就会失效。

watcher:构造方法允许传入一个Watcher的实现类对象来设置默认的watcher事件通知处理器,该参数为null时表示不需要设置默认的watcher事件处理器。

canBeReadOnly:zookeeper服务器发生故障后是否可以提供读服务(写服务是肯定提供不了的)

sessionId和sessionPassword:会话id和会话秘钥能唯一确定一个会话,客户端可使用这两个参数来实现会话复用。第一次链接zk服务器时调用Zookeeper对象实例的以下两个接口可获得当前会话的id和秘钥。

只有zk服务端向客户单发送通知,客户端收到此通知才算建立真正的会话,否则处于CONNECTING状态。

2.使用Zookeeper类的create()方法来创建节点:

参数详解:

path--节点路径

byte data[]--字节数组,节点创建后的初始内容(zk节点内容只支持字节数组,不负责对节点内容序列化,需要开发人员自己使用序列化工具操作序列化及反序列化)

createMode--节点类型

cb--回调函数,开发人员需要实现StringCallback接口,主要是对void processResult(...)方法的重写。zk服务端创建节点完毕后,zk客户端会自动调用此方法,以便处理相关的业务逻辑。

ctx--用于传递一个对象,可在回调方法执行时使用,通常是上下文信息。

 

zk服务注册:

所谓的注册zk服务,其实就是在zk的数据节点下创建子节点,写入服务提供者的url地址等信息。

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值