【ZooKeeper Notes 11】ZooKeeper客户端地址列表的随机原理

查看PDF版本 java

转载请用注明:@ni掌柜nileader@gmail.comgit

 

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

  
  
           
  
  
  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的:session

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

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

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

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

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

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

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

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

  
  
           
  
  
  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号位开始一个一个使用xml

另外两个注意点

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点中的加大风险之处

相关文章
相关标签/搜索