首页 > 其他分享 >聊聊Zookeeper技术内幕之客户端与SetData请求处理

聊聊Zookeeper技术内幕之客户端与SetData请求处理

时间:2023-07-10 21:34:48浏览次数:37  
标签:初始化 事务 Zookeeper 请求 创建 ZooKeeper SetData 客户端

从客户端会话创建到网络连接、请求处理,简单的叙述下流程与逻辑

客户端

客户端是开发人员使用ZooKeeper最主要的途径,ZooKeeper的客户端主要由以下几个核心组件组成。

  • ZooKeeper实例:客户端的入口。
  • ClientWatchManager:客户端Watcher管理器。
  • HostProvider:客户端地址列表管理器(管理服务器地址信息)。
  • ClientCnxn:客户端核心线程,其内部又包含两个线程,即SendThread和EventThread。前者是一个I/O线程,主要负责ZooKeeper客户端和服务端之间的网络I/O通信;后者是一个事件线程,主要负责对服务端事件进行处理。

对如上的组件,需要有一个初始化的过程,而这就是Zookeeper构造函数执行的结果。

在初始化阶段中,会做如下的事情:

  1. 初始化Zookeeper对象。
    通过调用ZooKeeper的构造方法来实例化一个ZooKeeper对象,在初始化过程中,会创建一个客户端的Watcher管理器:ClientWatchManager。

  2. 设置会话默认Watcher
    如果在构造方法中传入了一个Watcher对象,那么客户端会将这个对象作为默认Watcher保存在ClientWatchManager中。

  3. 构造Zookeeper服务器地址列表管理器:HostProvider。
    对于构造方法中传入的服务器地址,客户端会将其存放在服务器地址列表管理器HostProvider中。

  4. 创建并初始化客户端网络连接器:ClientCnxn。
    ZooKeeper客户端首先会创建一个网络连接器ClientCnxn,用来管理客户端与服务器的网络交互。另外,客户端在创建ClientCnxn的同时,还会初始化客户端两个核心队列outgoingQueue和pendingQueue,分别作为客户端的请求发送队列和服务端响应的等待队列。

  5. 初始化SendThread和EventThread。
    客户端会创建两个核心网络线程SendThread和EventThread,前者用于管理客户端和服务端之间的所有网络I/O,后者则用于进行客户端的事件处理。同时,客户端还会将ClientCnxnSocket分配给SendThread作为底层网络I/O处理器,并初始化EventThread的待处理事件队列waitingEvents,用于存放所有等待被客户端处理的事件。

Zookeeper的构造函数有蛮多,但最后都是调用此构造函数方法,其参数列表也正是对应着上述的功能模块的初始化。


public ZooKeeper(
        String connectString,
        int sessionTimeout,
        Watcher watcher,
        boolean canBeReadOnly,
        HostProvider hostProvider,
        ZKClientConfig clientConfig
    ) throws IOException {
        LOG.info(
            "Initiating client connection, connectString={} sessionTimeout={} watcher={}",
            connectString,
            sessionTimeout,
            watcher);

        this.clientConfig = clientConfig != null ? clientConfig : new ZKClientConfig();
        this.hostProvider = hostProvider;
        ConnectStringParser connectStringParser = new ConnectStringParser(connectString);

        cnxn = createConnection(
            connectStringParser.getChrootPath(),
            hostProvider,
            sessionTimeout,
            this.clientConfig,
            watcher,
            getClientCnxnSocket(),
            canBeReadOnly);
        cnxn.start();
    }

初始化过程的泳道图如下

image

请求处理(SetData请求)

在Zookeeper中,更新类的操作都属于事务操作,即这个操作需要事务保障的。

服务端对于SetData请求的处理,大体可以分为4大步骤,分别是请求的预处理、事务处理、事务应用和请求响应

流程逻辑大概如下所示:

image

预处理

  1. I/O层接收来自客户端的请求。

  2. 判断是否是客户端“会话创建”请求。ZooKeeper对于每一个客户端请求,都会检查是否是“会话创建”请求。对于SetData请求,因为此时已经完成了会话创建,因此按照正常的事务请求进行处理。

  3. 将请求交给ZooKeeper的PrepRequestProcessor处理器进行处理。

  4. 创建请求事务头。

  5. 会话检查。客户端会话检查是指检查该会话是否有效,即是否已经超时。如果该会话已经超时,那么服务端就会向客户端抛出SessionExpiredException异常。

  6. 反序列化请求,并创建ChangeRecord记录。面对客户端请求,ZooKeeper首先会将其进行反序列化并生成特定的SetDataRequest请求。SetDataRequest请求中通常包含了数据节点路径path、更新的数据内容data和期望的数据节点版本version。同时,根据请求中对应的path,ZooKeeper会生成一个ChangeRecord记录,并放入outstandingChanges队列中。outstandingChanges队列中存放了当前ZooKeeper服务器正在进行处理的事务请求,以便ZooKeeper在处理后续请求的过程中需要针对之前的客户端请求的相关处理,例如对于“会话关闭”请求来说,其需要根据当前正在处理的事务请求来收集需要清理的临时节点。

  7. ACL检查。由于当前请求是数据更新请求,因此ZooKeeper需要检查该客户端是否具有数据更新的权限。如果没有权限,那么会抛出NoAuthException异常。

  8. 数据版本检查。

  9. 创建请求事务体SetDataTxn。

  10. 保存事务操作到outstandingChanges队列中去。

事务处理

对于事务请求,ZooKeeper服务端都会发起事务处理流程。无论对于会话创建请求还是SetData请求,或是其他事务请求,事务处理流程都是一致的,都是由ProposalRequestProcessor处理器发起,通过Sync、Proposal和Commit三个子流程相互协作完成的。

事务应用

  1. 交付给FinalRequestProcessor处理器。

  2. 事务应用。ZooKeeper会将请求事务头和事务体直接交给内存数据库ZKDatabase进行事务应用,同时返回ProcessTxnResult对象,包含了数据节点内容更新后的stat。

  3. 将事务请求放入队列:commitProposal。

请求响应

  1. 统计处理。

  2. 创建响应体SetDataResponse。SetDataResponse是一个数据更新成功后的响应,主要包含了当前数据节点的最新状态stat。

  3. 创建响应头。

  4. 序列化响应。

  5. I/O层发送响应给客户端。

参考

《从Paxos到Zookeeper:分布式一致性原理与实践 》

标签:初始化,事务,Zookeeper,请求,创建,ZooKeeper,SetData,客户端
From: https://www.cnblogs.com/zhiyong-ITNote/p/17542380.html

相关文章

  • java客户端连接zookeeper
    一、使用官方的maven依赖:<dependency><groupId>org.apache.zookeeper</groupId><artifactId>zookeeper</artifactId><version>3.4.10</version></dependency>代码:Z......
  • 二、EAS客户端编辑界面常用代码
    2、EAS客户端编辑界面常用代码2.1 获取菜单getUIContext().get("UIClassParam")2.2客户端环境工具类//静态存储用户当前登录信息,登录的当前组织信息(ContextUtil在服务端使用)com.kingdee.eas.common.client.SysContext://获得当前用户的环境变量Contextctx=SysCont......
  • Vue + Volo.Abp 实现Auth2.0客户端授权模式认证
    @目录注册ClientAuth2.0授权创建vue-oidc-client创建Auth2.0认证跳转获取令牌创建回调页面创建退出登录最终效果Volo.Abp的身份服务器模块默认使用IdentityServer4实现身份认证。IdentityServer4是一个开源的OpenIDConnect和OAuth2.0框架,它实现了这些规范中的所有必需功能。......
  • 如何实现Java mqtt 客户端,收到自己发出消息的具体操作步骤
    实现JavaMQTT客户端收到自己发出的消息介绍在本文中,我将教会你如何使用Java实现一个MQTT(MessageQueuingTelemetryTransport)客户端,以接收自己发出的消息。MQTT是一个轻量级的消息协议,广泛应用于物联网和实时通信领域。我们将使用EclipsePaho库来实现这个功能。整体流程下面......
  • 高可用 ZooKeeper 集群部署(进阶中级)
    高可用ZooKeeper集群部署(进阶中级)免密登录[root@master~]#ssh-keygen[root@master~]#ssh-copy-idroot@slave1[root@master~]#ssh-copy-idroot@slave2[root@master~]#sshslave1Lastlogin:TueMay2322:10:272023from192.168.100.1[root@slave1~]#exit......
  • springcloud - zookeeper的基本配置和使用
     第一步:导入依赖     <dependency>       <groupId>org.springframework.cloud</groupId>       <artifactId>spring-cloud-starter-zookeeper-discovery</artifactId>       <!--排除启动器中配置好的版本-->    ......
  • 记一次zookeeper占满磁盘的故障
    今天有测试找到我说zookeeper161主机满了,走到主机查看发现确实满了,但是我们的log也已经清了,但是data文件里边全是快照文件。这里就要讲一讲zookeeper文件的删除了,首先我们不能贸然用rm命令删除快照文件,如果直接删完会导致丢失好多数据,所以我们需要设置相关参数,并使用一些优雅的......
  • 关于安卓客户端 软键盘弹出后,导致底部按钮看不见的处理方法
    问题产生原因:安卓:软键盘弹出后会改变页面的高度将页面顶上来。使用fixed或者absolute,会使得元素跟随body的底部移动,而安卓端软键盘将导致body高度变小而导致变形。IOS端:苹果的软键盘是覆盖的(分层),因此没有什么问题。 解决思路:记录页面高度,在键盘收起后,恢复原来高度 ......
  • Unity 在AssetPostprocessor内使用AssetDataBase是不安全的行为(尤其在Build前进行Lib
    https://docs.unity3d.com/Manual/AssetDatabaseCustomizingWorkflow.html在Build前进行Library的删除,读取Asset是不安全的行为,需要使用C#的IOSystem进行操作AssetImportOrderIfyouarescriptingusingtheAssetDatabaseclass,it’simportanttounderstandhowtheor......
  • 利用ansible批量部署node客户端,并注册consul,实现主机自动发现
      1.在管理机器上搭建consul并上传 node_exoporter软件包,system服务配置文件,注册脚本 2.利用ansible对指定机器去分发软件包并启动服务,并curl注册到consul  编写为node-exporter.yml 3.prometheus配置consul地址,获取主机信息,自动发现并配合grafana展示  system......