首页 > ZooKeeper客户端地址列表的随机原理

ZooKeeper客户端地址列表的随机原理

原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://nileader.blog.51cto.com/1381108/932948

查看PDF版本

转载请用注明:@ni掌柜[email protected]

 

在之前一个文章《ZooKeeper Java API 使用样例》中提到,客户端使用ZooKeeper的时候,首先会建立与ZooKeeper的连接,方法是通过调用下面这个构造方法来实现的。

  1. public ZooKeeper(String connectString, // 
  2. int sessionTimeout, // 
  3. Watcher watcher,// 
  4. boolean canBeReadOnly ) 
  5. throws IOException 

 在这个构造方法中,首先要配置的是ZK服务器的地址列表,即connectString 这个参数,这个参数通常是这样一个格式的字符串:

  1. 192.168.1.1:2181,192.168.1.2:2181,192.168.1.3:2181 

 很明显,我们可以看到,ZK客户端允许我们将ZK服务器的所有地址都配置在这里,于是一个问题就来了,ZK在连接服务器过程中,是如何选择服务器的呢?下面首先来看看ZK客户端是如何处理这个connectString的:

  1. new ZooKeeper(“192.168.1.1:2181,192.168.1.2:2181,192.168.1.3:2181”,...) 

 实例一个ZooKeeper对象的时候,会要求传入一个地址列表的字符串,这个字符串就是ZK服务器的地址列表,用英文状态“,“隔开

  1. ConnectStringParser connectStringParser =  
new ConnectStringParser(“192.168.1.1:2181,192.168.1.2:2181,192.168.1.3:2181”); 

 之后,这个地址列表会被封装到一个ConnectStringParser 对象中去,这个类主要就是解析传入地址列表字符串,将其它保存在一个ArrayList中。这个对象基本结构如下,这里我们主要关注serverAddresses这个成员

  1. public final class ConnectStringParser { 
  2.     private final String chrootPath; 
  3.     private final ArrayList<InetSocketAddress> serverAddresses = new ArrayList<InetSocketAddress>(); 

接下去,这个地址列表会被进一步封装成StaticHostProvider对象,并且在运行过程中,一直是这个对象来维护整个地址列表。关于这个对象,我们主要关注两点:地址列表的随机和地址获取这两个过程。首先来看地址列表的随机

  1. public StaticHostProvider(Collection<InetSocketAddress> serverAddresses) 
  2.             throws UnknownHostException { 
  3.         …… 
  4. …… 
  5.         Collections.shuffle(this.serverAddresses); 
  6.     } 

这里可以看到,对于传入地址列表,ZK使用java.util.Collections.shuffle(List list) 来对地址列表随机打乱顺序,注意,这个随机过程是一次性的,也就是说,之后使用过程中一直是按照这样的顺序。再来看看地址列表被随机打乱后,又是怎么使用地址的

  1.  public InetSocketAddress next(long spinDelay) { 
  2.         ++currentIndex; 
  3.         if (currentIndex == serverAddresses.size()) { 
  4.             currentIndex = 0
  5.         } 
  6. …… 
  7. …… 
  8.         return serverAddresses.get(currentIndex); 
  9.     } 

看一下StaticHostProvider.next(long spinDelay) 方法就明白了。next方法的实现, 没错,就是“Round Robin”。简单的说,ZK客户端将所有Server保存在一个List中,然后随机打乱,并且形成一个环,具体使用的时候,从0号位开始一个一个使用

另外两个注意点

1.通过代码,可以发现ZK本质上是通过一个List来维护地址列表的,因此,Server地址能够重复配置,这样能够弥补客户端无法设置Server权重的缺陷,但是也会加大风险。 比如: 192.168.1.1:2181,192.168.1.1:2181,192.168.1.2:2181

2.如果客户端在进行Server切换过程中耗时过长,那么将会收到SESSION_EXPIRED. 这也是上面第1点中的加大风险之处

本文出自 “ni掌柜的笔记” 博客,请务必保留此出处http://nileader.blog.51cto.com/1381108/932948



转载于:https://www.cnblogs.com/java20130722/p/3206755.html

更多相关:

  • 51 三菱PLC可读不可写Q:MT8102IQ和三菱Q系列PLC通讯,屏无法写入PLC,但是可以读取PLC的状态和数值?A:PLC程序中"允许RUN中写入"打钩,程序下载重启后解决。52 控制不了输入点Q:触摸屏做了三菱PLC的X点的元件,但是控制不了X输出?A:是的,PLC端X点无法通过触摸屏控制输出,屏上只能做X点的显示。53 M...

  • 传统方法(仅适用于普通项目):   1、在vscode中安装 Live Server 插件: 2、安装成功后,vscode右下角会有 Go Live 标识点击: 3、cmd ipconfig 查询自己电脑的ip地址: 4、复制地址替换端口前的地址(http://127.0.0.1:8080修改为http://192.168....

  • ngx_http_geo_module模块,默认情况下,nginx会加载,除非人为的 --without-http_geo_module。 这个模块提供了一个非常好用的geo指令,可以用它来创建变量,诞生其值依赖于客户端IP地址。 ngx_http_geo_module 模块官网地址 http://nginx.org/en...

  • uboot启动Linux内核过程分为4大步骤: 问题2: uboot阶段DDR的分区的问题 上述步骤2和步骤4中,有将uboot/kernel拷贝纸DDR的步骤,具体要拷贝到DDR的什么位置呢? 分清楚这两个概念: 链接地址:链接时指定的地址(指定方式为:Makefile中用-Ttext,或者链接脚本) 运行地址:程序实际运行...

  • 在Linux系统中,以32bit x86系统来说,进程的4GB内存空间(虚拟地址空间)被划分成为两个部分 ------用户空间和内核空间,大小分别为0-3G,3-4G。        用户进程通常情况下,只能访问用户空间的虚拟地址,不能访问到内核空间。          每个进程的用户空间存放用户的程序和代码(堆栈,数据区,代码区等)...

  • 一、代码结构概览1.核心部分configs:储存各种网络的yaml配置文件datasets:存放数据集的地方detectron2:运行代码的核心组件tools:提供了运行代码的入口以及一切可视化的代码文件。2.Tutorial部分demo:显而易见就是demodocs: 同样显而易见。。tests:提供了一些测试代码projects:...

  •     我刚刚接手这个项目的时候就被一系列不知所措的文件命名给深深的震惊了,那种振聋发聩不亚于听到赌王离世的消息。 首先请看,文件本来是用于处理“请假审批”,但是文件名居然叫做“teaApprove”,不要欺负我的初中英语不好,这个teaApprove我第一个感觉就是和“喝茶、茶叶”有关的业务,可是和我们这个项目八竿子打不着...

  • 这个问题简单,不做过多描述,如题所述,如果因为这个导致错误,请安装 npm install stylus-loader css-loader style-loader -D...

  • 使用这个宏TS_VERSION_MAOR来判断,这个宏定义在编译时生成在apidefs.h,它包含在ts/ts.h中,所以请在插件这包含...

  • linux valgrind Memcheck–内存检查工具 使用方法: 注意,这里要用debug版本,如果是release的运行文件,则用debug编译出来的可执行文件替换 输出到终端: valgrind --tool=memcheck --leak-check=full ./test.out 输出到文件: valgri...

  • 来源:http://suo.im/5HPGNT在Python中有4种内建的数据结构:列表、元组、字典、集合。今天我们将会学习如何使用它们,以及它们如何使编程变得简单。一、列表list是处理一组有序项目的数据结构,即你可以在一个列表中存储一个 序列 的项目。假想你有一个购物列表,上面记载着你要买的东西,你就容易理解列表了。只不过在你...

  • python列表(数组)  列表(list)  就是 数组   - 列表是Python中的一个对象   - 对象(object)就是内存中专门用来存储数据的一块区域   - 之前我们学习的对象,像数值,它只能保存一个单一的数据   - 列表中可以保存多个有序的数据   - 列表是用来存储对象的对象   - 列表的使用:   ...

  • 【列表|字典】 Tcl使用列表来处理各种集合,比方一个目录中的全部文件,以及一个组件的全部选项。最简单的列表就是包括由随意个空格、制表符、换行符、分隔的随意多个元素的字符串。比方: JerryAlice Mandy David l  lindex命令: --> 获取元素 至少须要两个參数,一个列表和一个索引值。返回取得的元素...

  • 节点列表由 getElementsByTagName() 方法和 childNodes 属性返回。 实例 下面的例子使用 XML 文件 books.xml。 函数 loadXMLDoc(),位于外部 JavaScript 中,用于加载 XML 文件。 从第一个 元素获取文本 本例使用 getElementsByT... </p> </div> </div> </li> </ul> </div> </div> </div> <!-- <div class="simle_box300"></div> --> </div> </section> <div class="footer-wrapper"> <div class="footer"> <p class="text-center"> ©2024 11GX.COM </p> </div> </div></body> </html><script data-cfasync="false" src="/cdn-cgi/scripts/5c5dd728/cloudflare-static/email-decode.min.js"></script>