当前位置: 首页 > news >正文

Zookeeper(八)序列化与协议

目录

  • 一 序列化与反序列化
    • 1.1 Jute序列化工具
      • 1.1 Recor接口
      • 1.2 OutputArchive和InputArchive
  • 二 通信协议
    • 2.1 请求部分
      • 2.1.1 请求头
      • 2.2.2 请求体
      • 2.1.3 案例分析
    • 2.2 响应部分
      • 2.2.1 响应头
      • 2.2.2 响应内容
      • 2.2.3 案例分析

  • 官网:Apache ZooKeeper

一 序列化与反序列化

对于一个网络通信,首先需要解决的就是对数据的序列化和反序列化处理,在ZooKeeper中,使用了Jute这一序列化组件来进行数据的序列化和反序列化操作。

1.1 Jute序列化工具

Zookeeper的客户端与服务端之间会进行一系列的网络通信来实现数据传输,Zookeeper使用Jute组件来完成数据的序列化和反序列化操作,其用于Zookeeper进行网络数据传输和本地磁盘数据存储的序列化和反序列化工作。
实体类要使用Jute进行序列化和反序列化步骤:

  • 1.需要实现Record接口的serialize和deserialize方法;
  • 2.构建一个序列化器BinaryOutputArchive;
  • 3.序列化:调用实体类的serialize方法,将对象序列化到指定的tag中去,比如这里将对象序列化到header中;
  • 4.反序列化:调用实体类的deserialize方法,从指定的tag中反序列化出数据内容。
package com.shu.jute;import org.apache.jute.InputArchive;
import org.apache.jute.OutputArchive;
import org.apache.jute.Record;/*** @author 31380* @description MockReHeader* @create 2024/3/21 14:10*/
public class MockReHeader implements Record {private long sessionId;private String type;public MockReHeader() {}public MockReHeader(long sessionId, String type) {this.sessionId = sessionId;this.type = type;}public void setSessionId(long sessionId) {this.sessionId = sessionId;}public void setType(String type) {this.type = type;}public long getSessionId() {return sessionId;}public String getType() {return type;}public void serialize(OutputArchive outputArchive, String tag) throws java.io.IOException {outputArchive.startRecord(this, tag);outputArchive.writeLong(sessionId, "sessionId");outputArchive.writeString(type, "type");outputArchive.endRecord(this, tag);}public void deserialize(InputArchive inputArchive, String tag) throws java.io.IOException {inputArchive.startRecord(tag);this.sessionId = inputArchive.readLong("sessionId");this.type = inputArchive.readString("type");inputArchive.endRecord(tag);}@Overridepublic String toString() {return "sessionId = " + sessionId + ", type = " + type;}
}
package com.shu.jute;import org.apache.jute.BinaryInputArchive;
import org.apache.jute.BinaryOutputArchive;
import org.apache.zookeeper.server.ByteBufferInputStream;import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;/*** @author 31380* @description* @create 2024/3/21 14:11*/
public class JuteTest {public static void main(String[] args) throws IOException {ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();BinaryOutputArchive binaryOutputArchive = BinaryOutputArchive.getArchive(byteArrayOutputStream);new MockReHeader(0x3421eccb92a34el, "ping").serialize(binaryOutputArchive, "header");ByteBuffer byteBuffer = ByteBuffer.wrap(byteArrayOutputStream.toByteArray());ByteBufferInputStream byteBufferInputStream = new ByteBufferInputStream(byteBuffer);BinaryInputArchive binaryInputArchive = BinaryInputArchive.getArchive(byteBufferInputStream);MockReHeader mockReHeader = new MockReHeader();System.out.println(mockReHeader);mockReHeader.deserialize(binaryInputArchive, "header");System.out.println(mockReHeader);byteBufferInputStream.close();byteArrayOutputStream.close();}}

image.png

1.1 Recor接口

Zookeeper中所需要进行网络传输或是本地磁盘存储的类型定义,都实现了该接口,是Jute序列化的核心。Record定义了两个基本的方法,分别是serialize和deserialize,分别用于序列化和反序列化。其中archive是底层真正的序列化器和反序列化器,并且每个archive中可以包含对多个对象的序列化和反序列化,因此两个接口中都标记了参数tag,用于序列化器和反序列化器标识对象自己的标记。

1.2 OutputArchive和InputArchive

  • OutputArchive和InputArchive分别是Jute底层的序列化器和反序列化器定义。有BinaryOutputArchive/BinaryInputArchive、CsvOutputArchive/CsvInputArchive和XmlOutputArchive/XmlInputArchive三种实现,无论哪种实现都是基于OutputStream和InputStream进行操作。
  • BinaryOutputArchive对数据对象的序列化和反序列化,主要用于进行网络传输和本地磁盘的存储,是Zookeeper底层最主要的序列化方式。CsvOutputArchive对数据的序列化,更多的是方便数据的可视化展示,因此被用在toString方法中。XmlOutputArchive则是为了将数据对象以xml格式保存和还原,但目前在Zookeeper中基本没使用到。

注意:在最新版本的ZooKeeper中,底层依然使用了Jute这个古老的,并且似乎没有更多其他系统在使用的序列化组件。

二 通信协议

基于TCP/IP协议,ZooKeeper实现了自己的通信协议来完成客户端与服务端、服务端与服务端之间的网络通信。ZooKeeper通信协议整体上的设计非常简单,对于请求,主要包含请求头和请求体,而对于响应,则主要包含响应头和响应体
image.png

2.1 请求部分

image.png
我们将从请求头和请求体两方面分别解析ZooKeeper请求的协议设计

2.1.1 请求头

class RequestHeader {int xid;int type;}

从zookeeper.jute中可知RequestHeader包含了xid和type,xid用于记录客户端请求发起的先后序号,用来确保单个客户端请求的响应顺序,type代表请求的操作类型,如创建节点(OpCode.create)、删除节点(OpCode.delete)、获取节点数据(OpCode.getData)。

2.2.2 请求体

协议的请求体部分是指请求的主体内容部分,包含了请求的所有操作内容。

ConnectRequest:会话创建

class ConnectRequest {int protocolVersion;long lastZxidSeen;int timeOut;long sessionId;buffer passwd;}

Zookeeper客户端和服务器在创建会话时,会发送ConnectRequest请求,该请求包含协议版本号protocolVersion、最近一次接收到服务器ZXID lastZxidSeen、会话超时时间timeOut、会话标识sessionId和会话密码passwd。

GetDataRequest:获取节点数据

 class GetDataRequest {ustring path;boolean watch;
}

ZooKeeper客户端在向服务器发送获取节点数据请求的时候,会发送GetDataRequest请求,该请求体中包含了数据节点的节点路径path和是否注册Watcher的标识watch

SetDataRequest:更新节点数据

 class SetDataRequest {ustring path;buffer data;int version;
}

ZooKeeper客户端在向服务器发送更新节点数据请求的时候,会发送SetDataRequest请求,该请求体中包含了数据节点的节点路径path、数据内容data和节点数据的期望版本号version

2.1.3 案例分析

  • 发出请求获取数据

我们获取到了ZooKeeper客户端请求发出后,在TCP层数据传输的十六进制表示,其中带下划线的部分就是对应的GetDataRequest请求,即[00,00,00,1d,00,00,00,01,00,00,00,04,00,00,00,10,2f,24,37,5f,32,5f,34,2f,67,65,74,5f,64,61,74,61,01],GetDataRequest请求的完整协议定义,我们来分析下这个十六进制字节数组的含义
image.png

2.2 响应部分

获取节点数据响应的完整协议定义
image.png

2.2.1 响应头

 class ReplyHeader {int xid;long zxid;int err;}

xid与请求头中的xid一致,zxid表示Zookeeper服务器上当前最新的事务ID,err则是一个错误码,表示当请求处理过程出现异常情况时,就会在错误码中标识出来,常见的包括处理成功(Code.OK)、节点不存在(Code.NONODE)、没有权限(Code.NOAUTH)。

2.2.2 响应内容

协议的响应主体内容部分,包含了响应的所有数据,不同的响应类型请求体不同。

ConnectResponse:会话创建

 class ConnectResponse {int protocolVersion;int timeOut;long sessionId;buffer passwd;}

针对客户端的会话创建请求,服务端会返回客户端一个ConnectResponse响应,该响应体中包含了协议的版本号protocolVersion、会话的超时时间timeOut、会话标识sessionId和会话密码passwd

GetDataResponse:获取节点数据

 class GetDataResponse {buffer data;org.apache.zookeeper.data.Stat stat;
}

针对客户端的获取节点数据请求,服务端会返回客户端一个GetDataResponse响应,该响应体中包含了数据节点的数据内容data和节点状态stat

SetDataResponse:更新节点数据

 class SetDataResponse {org.apache.zookeeper.data.Stat stat;}

针对客户端的更新节点数据请求,服务端会返回客户端一个SetDataResponse响应,该响应体中包含了最新的节点状态stat

2.2.3 案例分析

我们获取到了ZooKeeper服务端响应发出之后,在TCP层数据传输的十六进制表示,其中带下划线的部分就是对应的GetDataResponse响应,即[00,00,00,63,00,00,00,05,00,00,00,00,00,00,00,04,00,00,00,00,00,00,00,0b,69,27,6d,5f,63,6f,6e,74,65,6e,74,00,00,00,00,00,00,00,04,00,00,00,00,00,00,00,04,00,00,01,43,67,bd,0e,08,00,00,01,43,67,bd,0e,08,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,0b,00,00,00,00,00,00,00,00,00,00,00,04]。
image.png
image.png

相关文章:

Zookeeper(八)序列化与协议

目录 一 序列化与反序列化1.1 Jute序列化工具1.1 Recor接口1.2 OutputArchive和InputArchive 二 通信协议2.1 请求部分2.1.1 请求头2.2.2 请求体2.1.3 案例分析 2.2 响应部分2.2.1 响应头2.2.2 响应内容2.2.3 案例分析 官网:Apache ZooKeeper 一 序列化与反序列化 …...

人工智能之Tensorflow变量作用域

在TensoFlow中有两个作用域(Scope),一个时name_scope ,另一个是variable_scope。variable_scope主要给variable_name加前缀,也可以给op_name加前缀;name_scope给op_name加前缀。 variable_scope 通过所给的名字创建或…...

ElasticSearch插件安装及配置

Docker安装ElasticSearch docker compose 安装直接看步骤三:新建索引 1、安装elasticsearch (1)下载elasticsearch和kibana docker pull elasticsearch:7.9.1 docker pull kibana:7.9.1(2)配置 mkdir -p /mydata/…...

vue+Echarts实现多设备状态甘特图

目录 1.效果图 2.代码 3.注意事项 Apache ECharts ECharts官网,可在“快速上手”处查看详细安装方法 1.效果图 可鼠标滚轮图表和拉动下方蓝色的条条调节时间细节哦 (注:最后一个设备没有数据,所以不显示任何矩形)…...

STM32使用滴答定时器实现delayms

在STM32上使用SysTick实现jiffies(时间戳)并且实现delay_ms 代码实现: volatile uint32_t jiffies 0; // 用于记录系统运行的jiffies数 void SysTick_Handler(void) {/* 每次SysTick中断,jiffies增加 */jiffies; }uint32_t tick…...

k8s的volumn解析

背景 k8s中有一套自己的存储逻辑,它和docker中的volumn类似,本文就来看一下k8s的volunm的存储设计 k8s的volumn 1.EmptyDir类型的volumn 这种类型的volumn是Pod内的容器共享的,volumn的生命周期和Pod的生命周期是一致的,不过大…...

Golang获取音视频时长信息

文章目录 一、工具简介二、使用golang获取时间长 一、工具简介 这些工具都是与多媒体处理和流媒体相关的开源工具,它们都属于 FFmpeg 多媒体框架。 FFmpeg 是一个用于处理多媒体内容(音频、视频、图像等)的命令行工具。它可以执行各种各样…...

LeetCode 面试经典150题 14.最长公共前缀

题目: 编写一个函数来查找字符串数组中的最长公共前缀。 如果不存在公共前缀,返回空字符串 ""。 思路: 代码: class Solution {public String longestCommonPrefix(String[] strs) {if (strs.length 0) {return &…...

自注意力机制的理解

一、自注意力要解决什么问题 循环神经网络由于信息传递的容量以及梯度消失问题,只能建立短距离依赖关系。为了建立长距离的依赖关系,可以增加网络的层数或者使用全连接网络。但是全连接网络无法处理变长的输入序列,另外,不同的输…...

win10-误删winsock恢复方法

文件链接放在最前面 链接:https://pan.baidu.com/s/1i9X0HJJOfo63fbtOETc1Xw?pwdlfqx 提取码:lfqx 误删后应该还是可以正常连接网络的,但是重启过后直接以太网和wifi都是无法使用的。下图是我后面网络正常补充的图片 误删后是只有飞行模式…...

c#矩阵求逆

目录 一、矩阵求逆的数学方法 1、伴随矩阵法 2、初等变换法 3、分块矩阵法 4、定义法 二、矩阵求逆C#代码 1、伴随矩阵法求指定3*3阶数矩阵的逆矩阵 (1)伴随矩阵数学方法 (2)代码 (3)计算 2、对…...

array go 语言的数组 /切片

内存地址通过& package mainimport "fmt"func main() {var arr [2][3]int16fmt.Println(arr)fmt.Printf("arr的地址是: %p \n", &arr)fmt.Printf("arr[0]的地址是 %p \n", &arr[0])fmt.Printf("arr[0][0]的地址是 %p \n"…...

【Stable Diffusion】专栏介绍和文章索引(持续更新中)

目录 1 背景2 思考3 文章索引(持续更新中)3.1 入门3.2 初级3.3 中级3.3 高级 1 背景 最近开始学习AIGC,对Stable Diffusion比较感兴趣,所以新建了这个专栏,来记录自己在使用和学习Stable Diffusion的一些方法、资料以…...

RPC 快速入门

一、What 1)小故事 张三和李四都在同一个家公司负责商品交易的模块,两个人平时开发甚是紧密。 🙋🏻‍♂️ 张三:“李四,我这边一个商品下单了,但是付款数额不对,你帮我查下支付有没…...

使用Docker搭建Syslog-ng

Syslog-ng是一个可靠、多功能的日志管理系统,用于收集日志并将其转发到指定的日志分析工具。 使用Docker CLI方式搭建 步骤 1: 拉取Syslog-ng镜像 首先,需要从Docker Hub拉取Syslog-ng的官方镜像。 docker pull balabit/syslog-ng:latest步骤 2: 启动…...

使能 Linux 内核自带的 FlexCAN 驱动

一. 简介 前面一篇文章学习了 ALPHA开发板修改CAN的设备树节点信息,并加载测试过设备树文件,文件如下: ALPHA开发板修改CAN的设备树节点信息-CSDN博客 本文是学习使能 IMX6ULL的 CAN驱动,也就是通过内核配置来实现。 二. 使能…...

通过dbeaver链接dm8数据库

一、环境说明 windows 11 vmware 17 ubuntu 22 tt:~$ lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 22.04.3 LTS Release: 22.04 Codename: jammytt:~$ docker info Client:Version: 24.0.5Context: d…...

Stable diffusion(四)

训练自己的Lora 【DataSet】【Lora trainer】【SD Lora trainer】 前置的知识 batch size:模型一次性处理几张图片。一次性多处理图片,模型能够综合捕捉多张图片的特征,最终的成品效果可能会好。但是处理多个batch size也意味着更大的显存…...

oracle 19c RAC补丁升级

1.停止集群件备份家目录 ----两节点分别操作 cd /u01/app/19.3.0/grid/bin/ crsctl stop crstar -zcvf /u01/app.tar.gz /u01/app/u01/app/19.0.0/grid/bin/crsctl start crs2.两节点 GI、DB OPatch 替换(都得执行) ----# 表示 root 用户,$…...

计算机视觉研究方向

计算机视觉是一个广泛且快速发展的领域,涵盖了多种研究方向和技术。主要的研究方向包括图像处理、目标检测与识别、图像生成、三维视觉、行为识别、深度学习与计算机视觉、多媒体分析、视频理解、风格化、全向视觉传感器等。这些研究方向和技术不断进步,…...

四足机器人步态调参实战:如何用Walk These Ways控制器实现楼梯穿越与抗干扰行走

四足机器人步态调参实战:Walk These Ways控制器在复杂地形中的应用技巧 当Unitree Go1机器人第一次站在楼梯前时,开发者们面临着一个经典困境——如何让这台在平地上表现优异的机器跨越这道障碍。传统解决方案往往需要重新训练模型或调整底层算法&#…...

离线环境下的华为NPU卡Ubuntu驱动安装全攻略:从依赖包下载到错误排查

1. 离线安装华为NPU卡驱动的核心挑战 在封闭的企业内网环境中安装华为NPU卡驱动,就像在没有工具箱的情况下组装家具。我最近在客户数据中心遇到的实际案例是:一台用于AI推理的Ubuntu 18.04服务器被部署在金融行业的隔离网络区域,既不能连接外…...

OpenCore Legacy Patcher:让旧Mac重获新生的完整方案

OpenCore Legacy Patcher:让旧Mac重获新生的完整方案 【免费下载链接】OpenCore-Legacy-Patcher Experience macOS just like before 项目地址: https://gitcode.com/GitHub_Trending/op/OpenCore-Legacy-Patcher 当您的Mac被官方系统更新拒之门外时&#xf…...

translategemma-12b-it在C++高性能计算环境中的集成

translategemma-12b-it在C高性能计算环境中的集成 1. 引言 在当今全球化的技术环境中,多语言翻译能力已经成为许多应用程序的核心需求。translategemma-12b-it作为Google基于Gemma 3架构开发的专门翻译模型,支持55种语言的高质量互译,为开发…...

初学者如何自学SEO优化

初学者如何自学SEO优化 在当今互联网时代,搜索引擎优化(SEO)已经成为了网站推广的核心手段。对于初学者来说,如何自学SEO优化可能看起来有些复杂,但只要掌握几个关键点,就能迅速上手。本文将带你深入了解如…...

告别Transformer!用TimeKAN在ETTh1数据集上实现SOTA级长时序预测(附PyTorch复现指南)

TimeKAN:用频率分解与轻量架构重塑长时序预测的PyTorch实践指南 时序预测领域正在经历一场静悄悄的革命——当Transformer模型因计算复杂度陷入瓶颈时,一种融合频率分解思想与新型网络架构的解决方案正在ETTh1等基准数据集上刷新纪录。本文将带您深入Tim…...

编写程序实现智能乐器音准检测偏差时,提示“需要调音”,新手也能调好音。

1. 实际应用场景描述场景:一名吉他初学者刚刚买回一把新吉他,或者在干燥天气后琴弦音准发生了偏移。他不知道电子调音表如何使用,也不具备绝对音感。本系统功能:用户拨动琴弦(例如第 6 弦 E2),电…...

Qwen3-VL-8B-Instruct-GGUF实战:上传图片秒懂内容,智能问答体验分享

Qwen3-VL-8B-Instruct-GGUF实战:上传图片秒懂内容,智能问答体验分享 1. 模型概述与核心优势 Qwen3-VL-8B-Instruct-GGUF是阿里通义最新推出的中量级多模态模型,它最大的特点可以用一句话概括:用8B参数实现72B级别的视觉语言理解…...

SGLang-v0.5.6应用教程:快速构建API服务,支持约束解码生成指定格式

SGLang-v0.5.6应用教程:快速构建API服务,支持约束解码生成指定格式 1. SGLang简介与核心能力 SGLang(Structured Generation Language)是一个专注于大模型推理优化的高性能框架。它通过创新的架构设计,有效解决了传统…...

告别纯手工!用X-AnyLabeling的SAM2模型,5分钟搞定复杂目标分割标注

5分钟解锁X-AnyLabeling的SAM2黑科技:复杂目标分割标注效率提升指南 当面对医学影像中不规则肿瘤轮廓、遥感图像中的破碎地块边界,或是工业质检场景下的缺陷区域时,传统矩形框标注就像用粉笔画框测量云朵形状——既笨拙又低效。X-AnyLabelin…...