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

客户端

客户端是开发人员使用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();
}

初始化过程的泳道图如下

请求处理(SetData请求)

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

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

流程逻辑大概如下所示:

预处理

  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技术内幕之客户端与SetData请求处理的更多相关文章

  1. 从Paxos到ZooKeeper-四、ZooKeeper技术内幕

    本文将从系统模型.序列化与协议.客户端工作原理.会话.服务端工作原理以及数据存储等方面来揭示ZooKeeper的技术内幕. 一.系统模型 1.1 数据模型 ZooKeeper的视图结构使用了其特有的& ...

  2. 2、初探 ZooKeeper 技术内幕

    分布式一致性 “分布式” 是大型系统实现高性能.高可用所常用的架构手段,本章节将概述 “分布式一致性”的基本内容,以作为 ZAB 算法阐述的基础. 分布式一致性的基本概念 数据库系统的基础理论中,“事 ...

  3. 洞悉Redis技术内幕:缓存,数据结构,并发,集群与算法

    "为什么这个功能用不了?" 程序员:"清一下缓存" 上篇洞悉系列文章给大家详细介绍了MySQL的存储内幕:洞悉MySQL底层架构:游走在缓冲与磁盘之间.既然聊过 ...

  4. developerWorks 图书频道: 深入分析 Java Web 技术内幕,第 10 章

    developerWorks 图书频道: 深入分析 Java Web 技术内幕,第 10 章 深入理解 Session 与 Cookie Session 与 Cookie 不管是对 Java Web ...

  5. 架构设计:远程调用服务架构设计及zookeeper技术详解(下篇)

    一.下篇开头的废话 终于开写下篇了,这也是我写远程调用框架的第三篇文章,前两篇都被博客园作为[编辑推荐]的文章,很兴奋哦,嘿嘿~~~~,本人是个很臭美的人,一定得要截图为证: 今天是2014年的第一天 ...

  6. 《MSSQL2008技术内幕:T-SQL语言基础》读书笔记(下)

    索引: 一.SQL Server的体系结构 二.查询 三.表表达式 四.集合运算 五.透视.逆透视及分组 六.数据修改 七.事务和并发 八.可编程对象 五.透视.逆透视及分组 5.1 透视 所谓透视( ...

  7. Mysql技术内幕(第四版)读书笔记(一)

    题记:写代码已经有2年了,学到了很多知识,但是没有一个好习惯去记录,去分享,好多知识点都会忘记,所以从今天开始学着像大牛一样去记录自己经历项目的点点滴滴,先从最近读<Mysql技术内幕>开 ...

  8. 【转】COM技术内幕(笔记)

    COM技术内幕(笔记) COM--到底是什么?--COM标准的要点介绍,它被设计用来解决什么问题?基本元素的定义--COM术语以及这些术语的含义.使用和处理COM对象--如何创建.使用和销毁COM对象 ...

  9. Java并发编程与技术内幕:线程池深入理解

    摘要: 本文主要讲了Java当中的线程池的使用方法.注意事项及其实现源码实现原理,并辅以实例加以说明,对加深Java线程池的理解有很大的帮助. 首先,讲讲什么是线程池?照笔者的简单理解,其实就是一组线 ...

  10. 深入理解JavaWeb技术内幕(一)

    最近在看许令波的<深入理解JavaWeb技术内幕>.整理了一些笔记.想做一个系列,这篇是系列的第一篇,讲Web请求. B/S架构 最常见的架构方式. 优点: 1.客户端使用统一(此处的统一 ...

随机推荐

  1. vue中通过$emit实现子向父通信

    本篇讨论vue中使用$emit实现子向父通信, 第一步:我们在父组件中注册子组件,然后再给子组件标签添加一个自定义事件监听,这样在子组件实例上就绑定了一个自定义的事件add. 后面如果触发add事件, ...

  2. Go语言网络编程:SSH连接

    旨在提升Go语言网络编程能力 SSH是什么? SSH 为 Secure Shell 的缩写,为建立在应用层基础上的安全协议.SSH 是较可靠,专为远程登录会话和其他网络服务提供安全性的协议.利用 SS ...

  3. 【Qt6】QWindow类可以做什么

    原来的水文标题是"用 VS Code 搞 Qt6",想想还是直接改为"Qt6",反正这个用不用 VS Code 也能搞.虽然我知道大伙伴们都很讨厌 CMake, ...

  4. Redis报错MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on

    1.错误信息 org.redisson.client.RedisException: MISCONF Redis is configured to save RDB snapshots, but is ...

  5. Appweb+ESP学习笔记

    Appweb+ESP学习笔记 1.Appweb简介        Appweb HTTP Web服务器是最快的小型Web服务器.这是一个高性能,紧凑的嵌入式网络服务器,具有模块化,安全的核心.它支持广 ...

  6. STM32 + RTThread + UGUI

    一.概述 开发板:STM32F103C8T6 显示器:ST7735S RT-Thread:5.0.0 玩过 GUI 的小伙伴都知道,界面的显示是一个个像素点组合起来的,那么直接构建出来炫酷的 GUI ...

  7. Driver8833电机驱动模块的使用(STM32为主控)

    一.硬件 STM32C8T6.STLINK下载器 Driver8833:TI公司的DRV8833是双桥马达驱动器解决方案,包括有两个H桥驱动器,可驱动两个DC电刷马达,或一个步进马达, 螺线管和其它电 ...

  8. LeetCode 654:最大二叉树

    先立个flag吧,坚持每日刷题的小目标,希望自己能坚持下来,如果有需要一起打卡的uu,可以一起监督哈,在菜鸡的路上慢慢变好 题目:最大二叉树 给定一个不重复的整数数组 nums . 最大二叉树 可以用 ...

  9. 2022-12-19:大的国家。如果一个国家满足下述两个条件之一,则认为该国是 大国 : 面积至少为 300 万平方公里(即,3000000 km2),或者 人口至少为 2500 万(即 250000

    2022-12-19:大的国家.如果一个国家满足下述两个条件之一,则认为该国是 大国 : 面积至少为 300 万平方公里(即,3000000 km2),或者 人口至少为 2500 万(即 250000 ...

  10. 玩转服务器之环境篇:PHP和Python环境部署指南

    前几篇文章中讲解了如何搭建docker和Java Web环境的方法,本篇文章来教大家搭建一个好的PHP和Python环境,可以帮助开发和运行PHP和Python应用程序,使其更加高效和稳定. 一. P ...