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

zookeeper如何管理客户端与服务端之间的链接?(zookeeper sessions)

zookeeper客户端与服务端之间的链接用zookeeper  session表示。

zookeeper session有三个状态:

CONNECTING, ASSOCIATING, CONNECTED, CONNECTEDREADONLY, CLOSED, AUTH_FAILED,

NOT_CONNECTED(start时的状态)

1、CONNECTING 

    表明客户端正在与服务端建立连接。当客户端的句柄正在建立时,在java中,也就是ZkClient对象在创建后,到与服务端建立起真正链接的过程中,zookeeper的session状态是connecting。

2、CONNECTED 

    表明客户端与服务端已经建立链接。

3、CLOSE

    表明客户端与服务端之间的链接已经关闭。

当以下四种事件发生时,session的状态就会发生改变。

1、当session处于CONNECTING状态,客户端请求被加入到连接请求队列CONNECTING requests queue,执行成功后,会触发CONNECTED EVENTsession状态为CONNECTED

2、当session处于CONNECTING状态,但是客户端与服务端尝试连接的过程中权限校验不通过,触发AUTH_FAILED event,客户端请求返回AUTH_FAILED,连接建立结束。

3、当连接已经建立,session处于CONNECTED状态时,服务端突然出现故障或其他因素导致链接失效,触发DISCONNECTED event,返回CONNECT_LOSS。客户端重新将请求加入到连接请求队列CONNECTING requests queue,session状态重新变为CONNECTING。此时客户端有两个选择:

       重新向zookeeper集群中的其他服务器发起连接,成功则触发CONNECTED event,session状态变为CONNECTED,不断尝试直到超时则会造成session timeout,触发SESSION_EXPIRED event,请求返回SESSION_EXPIRED ,同时session状态修改为CLOSE

      或者,客户端直接请求关闭连接,返回CONNECTION LOSS,session状态变为CLOSE

整个过程如下图所示:

State transitions

zookeeper 客户端与服务端建立链接时有三个参数,一个是地址串,一个是超时时间timeout,一个是监听器。

地址参数表明客户端向哪个zookeeper server发起连接请求。 

当你使用多个zookeeper server地址时,多个地址用逗号隔开,比如“127.0.0.1:3000,127.0.0.1:3001,127.0.0.1:3002”,zookeeper客户端会随机连接到某个server上,如果连接失败,客户端会不断连接到其他server地址上,直到成功。

 zkClient = new ZooKeeper("127.0.0.1:3000,127.0.0.1:3001,127.0.0.1:3002", 2000,null);

当链接建立时,客户端所处的路径便是zookeeper server的根节点"/“。我们知道zookeeper没有相对路径的说法,客户端访问的所有节点都需要是绝对路径。那假设我们的配置信息分开发环境env和生产环境prod。开发环境的配置信息放在/env节点下,生产环境的配置放在/prod下。我们在开发时访问zookeeper的任何节点都需要加上前缀/env或者/prod。这样太麻烦了也容易出错。

于是zookeeper提供了一种方法,让我们可以在链接建立之后,访问的所有节点都相对于某个路径。

我们在连接地址串后面加上地址,比如:

        zkClient = new ZooKeeper("127.0.0.1:3000,127.0.0.1:3001,127.0.0.1:3002/env", 2000,null);

 那么当链接建立后,我们访问getData("/a"),实际上访问的是"/env/a”节点。

zookeeper session建立后,服务端会返回一个64位的session id 与针对这个session id设立的密码给客户端。当客户端所连接的这个服务端出现故障导致DISCONNECT event发生后,客户端将会尝试和其他服务端建立链接。客户端会将之前保存的session id与密码发送给新连接的服务端,以保证会话数据和原来一样。

timeout超时时间

session 的超时时间由zookeeper集群自己管理。超时时间是指当session建立后,客户端多长时间没有与服务端进行交互(包括维持连接的心跳也没有)时,集群认为session失效。zookeeper集群会删除这个会话,并且删除这个会话建立的所有临时节点,同时通知所有监听这些临时节点的zookeeper客户端,当然,对于这个这个被删除会话的客户端而言,在它重新连接上zookeeper集群之前它是收不到这个通知的,毕竟如果这个客户端是正常的,那么它就会和zookeeper集群保持心跳以维持会话。会话超时说明这个客户端断开了链接,哪怕zookeeper集群的功能再强大,它也通知不到这个已经失去联系的客户端。

 timeout时间最小是ticktime的两倍时间,最长是20倍。当客户端设置timeout值小于两倍ticktime时,zookeeper server实际返回的是ticktime的两倍时间。

当客户端所连接的server下线时,只要在timeout时间内,客户端能自动重连上zookeeper集群中的其他server,那么会话就能够保持。

zookeeper推荐由zookeeper客户端去负责重连的事情,直到请求返回session expired,此时我们再在自己的程序里去建立一个新的会话。而不是监听到所连接的server下线就立马去建立新的session,那样容易会发生“羊群效应”,也就是当server下线后,所有之前与这个服务端连接的客户端同时申请建立新的会话,会对zookeeper集群造成很大的压力。

SessionMovedException

这是一个内部异常,一般而言来说,客户端不会见到这个异常。当客户端向server A发起请求时,由于网络原因,在请求到达server时客户端就因为长时间没有收到响应而认为A已经下线,进而向server B建立会话。此时请求到达server A,A检测到会话已经转移,就会关闭与这个客户端的tcp链接。这一切都是由zookeeper在内部完成的,正常情况下客户端不会看到这个错误。

当有两个客户端在重建同一个链接时,其中一个客户端建立起的链接会因为另一个客户端建立起同样的链接而失效,从而重新建立链接。不断反复建立,失效,建立,失效,陷入一个死循环中。

在zookeeper3.5.0后加入一个local session概念。

zookeeper的session的建立与关闭是十分消耗性能的。因为在zookeeper中,所有的写操作都要在法定人数的server端操作成功才会同步到所有server。这是zookeeper的写瓶颈所在。另外,假设zookeeper集群的连接客户端非常多,而客户端仅仅只是连接Observer ZooKeeperServer 去读取数据并不涉及写操作时,只建立本地会话能够大大提升性能。

因此在3.5.0后引入一个local session(本地会话)的概念。local session只存在于与客户端连接的server中。

local session有以下特点:

localSessionsUpgradingEnabled 被禁用时,即local session不允许被升级为全局会话,那么:

1、local session不能建立临时节点

2、当会话丢失时,客户端并不能向集群的其他server重建同样的会话。因此local session只存在于之前所连接的server中。但是,这并不意味着当tcp链接断开后,客户端就只能新建一个session了。只要在timeout时间内,客户端重新连接上同一个server,那么session也能够得到保持。

3、local session的信息只由被连接的server维护,并不会通知到集群leader,同样的,session的状态信息也不会被持久化到磁盘。

4、心跳维持、过期和其他session状态由当前的server维护。

为什么要禁用?

  • 在想要处理大量客户端的大型部署中,我们知道客户端通过观察者进行连接,而观察者应该仅是本地会话。因此,这更像是防止有人意外创建大量临时节点和全局会话的防护措施。

localSessionsUpgradingEnabled 启用时,即local session允许被升级为全局会话,那么local session发生以下情况时会被自动升级为global session(全局会话):

1、当local session创建一个临时节点时,local session会先升级为global session再行创建。为什么创建临时节点就要升级为全局会话呢?原因是临时节点的创建在很大程度上取决于全局会话。从数据一致性的角度出发,那么当local session创建临时节点时,不同节点的数据就会不一致。从管理的角度出发,临时节点的删除依赖于集群中的leader。leader需要知道session的生命周期以便当session结束时能够删除临时节点,但是local session并不被leader知晓。

如果请求升级,则将会话从本地集合中删除,同时保留相同的会话ID。

当客户端请求与服务端A建立session时,服务端A会发送session id和password给客户端,同时提交一个createSession给leader。如果在客户端收到返回数据而leader未接收到createSession时,客户端断开连接重连上服务端B,此时服务端B会拿着客户端给的session id发送一个验证包给leader。如果在验证数据包到达之前leader提交了由A发出的CreateSession,则客户端将可以连接。否则,客户端将使会话过期,因为法定人数尚未得知该会话。此时,如果客户端也尝试再次连接回A,则该会话已从本地会话跟踪器中删除。因此,A将需要将验证数据包发送给领导者。处理过程与B相同。

因果一致性

Zookeeper是否满足因果一致性,需要看客户端的编程方式。

  • 不满足因果一致性的做法

1. A进程向Zookeeper的/z写入一个数据,成功返回

2. A进程通知B进程,A已经修改了/z的数据

3. B读取Zookeeper的/z的数据

4. 由于B连接的Zookeeper的服务器有可能还没有得到A写入数据的更新,那么B将读不到A写入的数据

相关文章:

zookeeper如何管理客户端与服务端之间的链接?(zookeeper sessions)

zookeeper客户端与服务端之间的链接用zookeeper session表示。 zookeeper session有三个状态: CONNECTING, ASSOCIATING, CONNECTED, CONNECTEDREADONLY, CLOSED, AUTH_FAILED, NOT_CONNECTED(start时的状态) 1、CONNECTING 。 表明客户…...

【Java多线程】7——阻塞队列线程池

7 线程池 ⭐⭐⭐⭐⭐⭐ Github主页👉https://github.com/A-BigTree 笔记仓库👉https://github.com/A-BigTree/tree-learning-notes 个人主页👉https://www.abigtree.top ⭐⭐⭐⭐⭐⭐ 如果可以,麻烦各位看官顺手点个star~&#x…...

同步复位和异步复位的优缺点

同步复位 优点:能确保电路是100%的; 同步复位可以综合处更小的触发器; 可以保证复位只发生在有效时钟边沿,过滤掉复位信号毛刺; 内部逻辑产生的复位信号,采用同步复位可以有效过滤掉毛刺。 缺点&#xff1a…...

Code Review(代码审查)

代码审查是软件开发生命周期的重要组成部分。它能显著提高开发人员的代码质量。 这个过程就像写一本书。作者写好了内容,出版社编辑对其进行了校审,所以没有出现任何错误,例如将“你”与“你的”混淆。这个案例中,代码审查是阅读…...

《拆解一切问题》如何成为解决难题的高手 - 三余书屋 3ysw.net

拆解一切问题:如何成为解决难题的高手 今天给大家分享的这本书叫做《拆解一切问题》,标题看起来确实有点虚,在没有读这本书之前,会让人感觉似乎只要读完学会书中的内容,就可以解决一切问题了。但事实上这种认识是误解…...

matlab——基于三维激光扫描点云的树冠体积计算方法

目录 一、算法原理1、原理概述2、参考文献二、代码实现三、结果展示本文由CSDN点云侠原创,原文链接。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫与GPT。 一、算法原理 1、原理概述 针对树冠形状不规则,树冠体积难以测量和计算的问题,提出一种基于三…...

如何在jupyter使用新建的虚拟环境以及改变jupyter启动文件路径。

对于刚刚使用jupyter的新手来说,经常不知道如何在其中使用新建的虚拟环境内核,同时,对于默认安装的jupyter,使用jupyter notebook命令启动 jupyter 以后往往默认是C盘的启动路径,如下图所示,这篇教程将告诉…...

Exception in thread “main“ com.fasterxml.jackson.databind.JsonMappingException:

问题:jaskson反序列化超出最大长度 Caused by: com.fasterxml.jackson.core.exc.StreamConstraintsException: String length (5043456) exceeds the maximum length (5000000) 场景:前端传递过大base64 原因: jaskon默认已经限制了最大长…...

第三十九章 保护与 IRIS 的 Web 网关连接

文章目录 第三十九章 保护与 IRIS 的 Web 网关连接配置 Web 网关的连接安全最低连接安全性(不推荐)简单的用户名/密码验证 第三十九章 保护与 IRIS 的 Web 网关连接 本页介绍用于保护从 Web Gateway 到 IRIS 的连接的选项。与 IRIS 的 Web 网关连接可以…...

java数据结构与算法刷题-----LeetCode127. 单词接龙

java数据结构与算法刷题目录(剑指Offer、LeetCode、ACM)-----主目录-----持续更新(进不去说明我没写完):https://blog.csdn.net/grd_java/article/details/123063846 文章目录 广度优先双分裂蛇 广度优先双分裂蛇 解题思路:时间复…...

pytorch中的torch.nn.Linear

torch.nn.Linear是pytorch中的线性层,应该是最常见的网络层了,官方文档:torch.nn.Linear。 torch.nn.Linear(in_features, out_features, biasTrue, deviceNone, dtypeNone)其中,in_features表示输入的维度;out_featu…...

03-MySQl数据库的-用户管理

一、创建新用户 mysql> create user xjzw10.0.0.% identified by 1; Query OK, 0 rows affected (0.01 sec) 二、查看当前数据库正在登录的用户 mysql> select user(); ---------------- | user() | ---------------- | rootlocalhost | ---------------- 1 row …...

知乎:多云架构下大模型训练,如何保障存储稳定性?

知乎,中文互联网领域领先的问答社区和原创内容平台,2011 年 1 月正式上线,月活跃用户超过 1 亿。平台的搜索和推荐服务得益于先进的 AI 算法,数百名算法工程师基于数据平台和机器学习平台进行海量数据处理和算法训练任务。 为了提…...

JWFD流程图转换为矩阵数据库的过程说明

在最开始设计流程图的时候,请务必先把开始节点和结束节点画到流程图上面,就是设计器面板的最开始两个按钮,先画开始点和结束点,再画中间的流程,然后保存,这样提交到矩阵数据库就不会出任何问题,…...

GT收发器第一篇_总体结构介绍

文章目录 前言GT收发器介绍 前言 之前写过一篇简单介绍GT的文章https://blog.csdn.net/m0_56222647/article/details/136730026,可以先通过这篇文章对整体进行简单了解一下。 GT收发器介绍 参考xilinx手册ug476 对于7系列的FPGA,共有3个系列&#xf…...

[图像处理] MFC载入图片并进行二值化处理和灰度处理及其效果显示

文章目录 工程效果重要代码完整代码参考 工程效果 载入图片,并在左侧显示原始图片、二值化图片和灰度图片。 双击左侧的图片控件,可以在右侧的大控件中,显示双击的图片。 初始画面: 载入图片: 双击左侧的第二个控件…...

centos7.5 安装gitlab-ce (Omnibus)

一、安装前置依赖 # 安装基础依赖 $ sudo yum -y install policycoreutils openssh-server openssh-clients postfix# 启动 ssh 服务 & 设置为开机启动 $ sudo systemctl enable sshd & sudo systemctl start sshd二、安装gitlab rpm包 # 下载并执行社区版脚本 curl …...

深入理解MapReduce:从Map到Reduce的工作原理解析

当谈到分布式计算和大数据处理时,MapReduce是一个经典的范例。它是一种编程模型和处理框架,用于在大规模数据集上并行运行计算任务。MapReduce包含三个主要阶段:Map、Shuffle 和 Reduce。 ** Map 阶段 ** Map 阶段是 MapReduce 的第一步&am…...

初始Java篇(JavaSE基础语法)(5)(类和对象(上))

个人主页(找往期文章包括但不限于本期文章中不懂的知识点):我要学编程(ಥ_ಥ)-CSDN博客 目录 面向对象的初步认知 面向对象与面向过程的区别 类的定义和使用 类的定义格式 类的实例化 this引用 什么是this引用? this引用…...

机器人---人形机器人之技术方向

1 背景介绍 在前面的文章《行业杂谈---人形机器人的未来》中,笔者初步介绍了人形机器人的未来发展趋势。同智能汽车一样,它也会是未来机器人领域的一个重要分支。目前地球上最高智慧的结晶体就是人类,那么人形机器人的未来会有非常大的发展空…...

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…...

Python爬虫实战:研究MechanicalSoup库相关技术

一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...

日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻

在如今就业市场竞争日益激烈的背景下,越来越多的求职者将目光投向了日本及中日双语岗位。但是,一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧?面对生疏的日语交流环境,即便提前恶补了…...

docker详细操作--未完待续

docker介绍 docker官网: Docker:加速容器应用程序开发 harbor官网:Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台,用于将应用程序及其依赖项(如库、运行时环…...

MFC内存泄露

1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...

cf2117E

原题链接&#xff1a;https://codeforces.com/contest/2117/problem/E 题目背景&#xff1a; 给定两个数组a,b&#xff0c;可以执行多次以下操作&#xff1a;选择 i (1 < i < n - 1)&#xff0c;并设置 或&#xff0c;也可以在执行上述操作前执行一次删除任意 和 。求…...

【LeetCode】算法详解#6 ---除自身以外数组的乘积

1.题目介绍 给定一个整数数组 nums&#xff0c;返回 数组 answer &#xff0c;其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法&#xff0c;且在 O…...

高抗扰度汽车光耦合器的特性

晶台光电推出的125℃光耦合器系列产品&#xff08;包括KL357NU、KL3H7U和KL817U&#xff09;&#xff0c;专为高温环境下的汽车应用设计&#xff0c;具备以下核心优势和技术特点&#xff1a; 一、技术特性分析 高温稳定性 采用先进的LED技术和优化的IC设计&#xff0c;确保在…...

鸿蒙Navigation路由导航-基本使用介绍

1. Navigation介绍 Navigation组件是路由导航的根视图容器&#xff0c;一般作为Page页面的根容器使用&#xff0c;其内部默认包含了标题栏、内容区和工具栏&#xff0c;其中内容区默认首页显示导航内容&#xff08;Navigation的子组件&#xff09;或非首页显示&#xff08;Nav…...

C++中vector类型的介绍和使用

文章目录 一、vector 类型的简介1.1 基本介绍1.2 常见用法示例1.3 常见成员函数简表 二、vector 数据的插入2.1 push_back() —— 在尾部插入一个元素2.2 emplace_back() —— 在尾部“就地”构造对象2.3 insert() —— 在任意位置插入一个或多个元素2.4 emplace() —— 在任意…...