使用小记:Zookeeper中动态改变节点的功能
Zookeeper 3.5+提供了reconfig功能实现动态配置节点,官方的说明是,“你再也不需要进行全部节点重启”就可以应用所有的修改:
http://zookeeper.apache.org/doc/r3.5.4-beta/zookeeperReconfig.html
我们不妨按照官方的说明尝试一下。
根据文档,我们先配置一个3节点集群好了,配置文件内容如下:
zoo1.cfg
- reconfigEnabled=true
- standaloneEnabled=false
- tickTime=2000
- dataDir=/tmp/zkcluster/zk1
- initLimit=5
- syncLimit=2
- clientPort=2791
- server.1=127.0.0.1:2780:2783:participant;2791
- server.2=127.0.0.1:2781:2784:participant;2792
- server.3=127.0.0.1:2782:2785:participant;2793
zoo2.cfg
- reconfigEnabled=true
- standaloneEnabled=false
- tickTime=2000
- dataDir=/tmp/zkcluster/zk2
- initLimit=5
- syncLimit=2
- clientPort=2792
- server.1=127.0.0.1:2780:2783:participant;2791
- server.2=127.0.0.1:2781:2784:participant;2792
- server.3=127.0.0.1:2782:2785:participant;2793
zoo3.cfg
- reconfigEnabled=true
- standaloneEnabled=false
- tickTime=2000
- dataDir=/tmp/zkcluster/zk3
- initLimit=5
- syncLimit=2
- clientPort=2793
- server.1=127.0.0.1:2780:2783:participant;2791
- server.2=127.0.0.1:2781:2784:participant;2792
- server.3=127.0.0.1:2782:2785:participant;2793
其实这三个配置文件基本相同,差别就是dataDir和clientPort不同。
请注意如下几点:
1. reconfigEnabled=true,这个配置是用来实现动态配置的,一定要设置,否则集群启动后会无法修改现有配置
2. standaloneEnabled=false,根据官方文档:
http://zookeeper.apache.org/doc/r3.5.4-beta/zookeeperReconfig.html#sc_reconfig_standaloneEnabled
的"The standaloneEnabled flag"章节,文中提到的:
- Prior to 3.5.0, one could run ZooKeeper in Standalone mode or in a Distributed mode. These are separate implementation stacks, and switching between them during run time is not possible. By default (for backward compatibility) standaloneEnabled is set to true. The consequence of using this default is that if started with a single server the ensemble will not be allowed to grow, and if started with more than one server it will not be allowed to shrink to contain fewer than two participants.
- Setting the flag to false instructs the system to run the Distributed software stack even if there is only a single participant in the ensemble. To achieve this the (static) configuration file should contain:
- standaloneEnabled=false
因为Standalone和Ensemble模式使用的是不同的实现栈,为了让我们的集群能够动态增加和减少节点,并且集群节点能够少于2,最好使用Ensemble模式。
3. clientPort=2793, 官方文档不建议使用这个参数,但是我实在不知道如何配置连接用的端口,所以保留了这个参数
4. dataDir, 请为每个节点单独配置一个数据目录,且里面建立一个名为“myid”的文件,内容为本节点的id(例如dataDir=/tmp/zkcluster/zk1的节点,在此目录创建myid文件,内容为1)。这个目录会存放集群数据的快照。
当我们设置好上述参数后,即可启动节点:
上图中,我写了个脚本能够只要输入节点的编号即可启动,实际上执行时,请使用:
zkServer.sh start /dir/to/zookeeper/conf/zooN.cfg
启动
此时我们连上任何一个节点,可以看到集群已经启动了:
zkCli.sh -server 127.0.0.1:2791
连上集群后使用config命令检查节点:
至此为止都是基本操作,接下来到达最重要的部分:动态配置集群以实现增加或者减少节点
首先我们以下述配置文件再启动一个节点:
- reconfigEnabled=true
- standaloneEnabled=false
- tickTime=2000
- dataDir=/tmp/zkcluster/zk4
- initLimit=5
- syncLimit=2
- clientPort=2794
- server.1=127.0.0.1:2780:2783:participant;2791
- server.4=127.0.0.1:2801:2802:participant;2794
配置在前面的章节已经解释过了,但是配置节点时只设置了两个,这一点可能会令人迷惑,在这里说明一下:大家如果参考文档,会发现3.5+版本会自动把配置文件变为动态配置文件,静态的部分还是放在原来的zooN.cfg当中,动态的部分放到了zooN.cfg.dynamic.xxx当中了,而且集群的配置文件在绝大多数时间中都是一致的,只有在重新配置的时候会经历短暂的不一致,利用这一特性,让新加入节点连接到集群上,然后从集群同步配置过来即可。
启动这个节点后,连接上这个节点观察集群:
大家可以看到,这个节点实际上是连接到集群的,但是从集群上同步的配置却不包含本节点。
注意:前面提到过自动同步配置的机制,此时本节点(节点4)会将集群配置同步到本地,如果此时重启节点,节点将没有办法再次被启动,因为集群中不包含本节点。
现在连接到任何一个集群内节点(1,2,或者3),使用下述命令添加节点:
- reconfig -add server.4=127.0.0.1:2801:2802:participant;2794
然后就。。。。。失败了:
搜索一下Authentication is not valid,可以知道是因为服务器默认没有/zookeeper/config的写入权限导致的,此时需要添加写入权限:
1. 先进入zookeeper的安装目录,然后执行下述命令产生认证使用的摘要信息:
java -cp ./lib/*:./* org.apache.zookeeper.server.auth.DigestAuthenticationProvider su:passwd
说明下,这条命令实际上在执行zookeeper的org.apache.zookeeper.server.auth.DigestAuthenticationProvider功能,
使用用户名:su
和密码:passwd
产生认证参数,执行完毕后程序返回:
su:passwd->su:gACzJ4L2A0F2ygTno5HQnfabuik=
2. 修改zkServer.sh,添加下述命令行:
- SERVER_JVMFLAGS="-Dzookeeper.DigestAuthenticationProvider.superDigest=su:gACzJ4L2A0F2ygTno5HQnfabuik="
其中红色部分是上一步(1)产生的摘要信息。
然后重启集群中的一个节点
3. 连接步骤2中重启的节点,执行下述命令:
- addauth digest su:passwd
reconfig -add server.4=127.0.0.1:2801:2802:participant;2794
结果如图:
此时我们连接到第四个节点,然后通过config检查:
发现第四个节点确实已经在集群中了,图中我还在第四个节点get了一下/k的值,这个值是在第一个节点设置的,可以看到,数据也同步过来了。
终于用上了zookeeper的动态配置功能,再也不用一个一个重启实例来添加集群节点了
最后,关于zookeeper集群的几点思考:
1. 在整个集群中,保留几个节点作为核心集群,当要添加、删除节点时,从这些节点进行,这样就不需要为所有的节点都提供/zookeeper/config的写入权限,在生产环境中要是每个节点都获取了写入权限,很有可能导致非专职运维的成员能够修改集群信息。当然,最重要的还是密码的保护,要是密码被非运维人员知道了,同时他也知道核心节点的地址,一样可以修改集群配置。
2. 关于集群节点数量的问题,上面的例子中,我们向3节点的集群增加了一个节点,这只是一个说明动态配置zookeeper的例子,实际使用时集群节点数量最好为奇数,因为zookeeper是基于大多数节点可用时集群可用的,也就是说,当有5个节点时,可以容忍2个节点的失效,而当拥有4个节点时,只能容忍一个节点失效,和拥有3个节点效果一样。
zookeeper的官方文档中,有两处描述了这个问题,第一处是:
http://zookeeper.apache.org/doc/r3.5.4-beta/zookeeperStarted.html#sc_RunningReplicatedZooKeeper
“Running Replicated ZooKeeper”章节的Note部分,明确说明了集群要使用奇数个节点,但是只是说了两个节点系统没有一个节点系统稳定
第二个就是(个人觉得这一段最明确):
http://zookeeper.apache.org/doc/r3.1.2/zookeeperAdmin.html#sc_designing
“Designing a ZooKeeper Deployment”章节的“Cross Machine Requirements”中,有集群中节点数量的计算公式:
- 2xF+1
其中F是集群容忍失效机器的数目,通过这个公式计算,3个节点的集群和4个节点的集群都只能容忍1个节点的失效
3. 关于动态向集群添加节点
其实有三种方式向集群添加节点(再次搬出官方文档):
http://zookeeper.apache.org/doc/r3.5.4-beta/zookeeperReconfig.html#sc_reconfig_modifying
请看到“Adding servers”部分:
1. 通过配置文件将要添加的节点当作Observer加入集群(可以添加多个节点),然后再在系统中重新配置为Participant
2. 通过配置文件将要添加的节点当作Participant加入集群,每个节点的配置文件只能添加集群节点和自己,否则新加入的节点可能形成一个集群,导致发生脑裂,请参考下面的“Warning”部分
3. 仅将Leader节点和自己加入配置文件,然后通过reconfig将自身加入集群(本实例中使用的方法),这种方法有两个前提条件:
a. 配置文件中只能出现自身节点和Leader节点
b. 如果添加节点的过程中Leader挂掉,此时自身的配置已经有问题了,需要下线本节点重新配置再加入
实际生产时,使用1是最可靠的。
使用小记:Zookeeper中动态改变节点的功能的更多相关文章
- 代码中动态改变布局属性RelativeLayout.LayoutParams.addRule()
我们知道,在 RelativeLayout 布局中有很多特殊的属性,通常在载入布局之前,在相关的xml文件中进行静态设置即可. 但是,在有些情况下,我们需要动态设置布局的属性,在不同的条件下设置不同的 ...
- Android中动态改变控件的大小的一种方法
在Android中有时候我们需要动态改变控件的大小.有几种办法可以实现 一是在onMeasure中修改尺寸,二是在onLayout中修改位置和尺寸.这个是可以进行位置修改的,onMeasure不行. ...
- WPF 中动态改变控件模板
在某些项目中,可能需要动态的改变控件的模板,例如软件中可以选择不同的主题,在不同的主题下软件界面.控件的样式都会有所不同,这时即可通过改变控件模板的方式实现期望的功能. 基本方法是当用户点击切换主题按 ...
- CKEDITOR 3.4.2中 按钮事件中 动态改变图标和title 获取按钮
this.uiItems[0].className="cke_button_hui_position_type";this.uiItems[0].title="zhang ...
- ThinkPhp 中Action控制器中动态改变自动完成规则(使用setProperty)
Common.php中定义的方法 在更新数据时动态规则中 "完成时间" 必须设定为2
- 给div中动态添加节点并设置样式
前端IOS今天需要动态的在图片前面添加一个按钮 主要是在使用 bt.setAttribute("class","aaa"); 可以对创建的节点使用setAttr ...
- 【转载】在程序中动态改变static text控件的caption值
方法1,给STATIC控件取个名字叫IDC_STATICTITLE 然后在ClassWizard中设定一个控件变量给它叫m_statictitle 然后用m_statictitle.SetWindow ...
- hadoop集群中动态添加节点
集群的性能问题需要增加服务器节点以提高整体性能 https://www.cnblogs.com/fefjay/p/6048269.html hadoop集群之间hdfs文件复制 https://www ...
- Android中动态改变Listview中字体的颜色
效果如下: 账目显示用的是Listview,要实现的功能为使其根据所在Item是“收入”还是“支出”来把数字设置成绿色或红色 方法是自定义适配器,并重写其中getView()函数,实现如下: //自定 ...
随机推荐
- Python3基础之构建setup.py
技术背景 在上一篇博客中,我们介绍了如何使用pyinstaller将python项目打包成一个可执行文件,并且放在系统目录下,让系统用户可以直接识别到我们构造的项目.而python项目中常见的setu ...
- Android学习之启动活动的最佳写法
•开始热身 通过之前的学习,我们现在可以很容易的启动一个活动: 首先通过 Intent 构造出当前的 "意图",然后调用 startActivity() 方法将活动启动起来: ...
- kubernetes中有状态应用的优雅缩容
将有状态的应用程序部署到Kubernetes是棘手的. StatefulSet使它变得容易得多,但是它们仍然不能解决所有问题.最大的挑战之一是如何缩小StatefulSet而不将数据留在断开连接的Pe ...
- JMeter元件作用域实践指南
从一个问题说起 对于以下测试脚本: 为了能调用进入房间接口,需要从考场接口获取考场token.为了调用考场接口,需要从登陆接口获取登陆token.元件说明如下: 学生登录,提取登录${token}传入 ...
- day-02-循环
while 循环 why:大气循环, 吃饭,上课,睡觉,日复一日,歌曲列表循序环,程序中:输入用户名密码, what:while 无限循环. how: 基本结构: while 条件: 循环体 初识循环 ...
- Dynamics CRM实体系列之窗体
本节开始讲Dynamics CRM的窗体排版和设计,窗体也就是我们实际可以看到的表单界面.Dynamics CRM提供了一套独立的表单模板设计引擎,可以很方便的为开发者提供无代码开发,只需要简单的拖动 ...
- Dynamics CRM修改密码界面
我们再实施Dynamics CRM的过程中经常会被客户吐槽没有一个修改密码的页面.市面上也有一些人通过自己操作AD库进行修改密码的解决方案不过多多少少会有一些BUG存在.其实ADFS提供了一个修改密码 ...
- Python简单实现杨辉三角
n=input("请输入要打印的行数")n=int(n)for x in range(0,n+1): p=1 print(''.rjust(n-x),end="" ...
- 结对编程-stage_2
教学班 罗杰.任建班周五3.4节 gitlab项目地址 Here it is. 成员 周远航(3004) 李辰洋(3477) 结对编程体验 经过了上一阶段的磨合,第二阶段我们的配合更加流畅,也熟悉了对 ...
- 呵呵,Semaphore,就这?
这是并发线程工具类的第二篇文章,在第一篇中,我们分析过 CountDownLatch 的相关内容,你可以参考 一文搞懂 CountDownLatch 用法和源码! 那么本篇文章我们继续来和你聊聊并发工 ...