使用小记: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()函数,实现如下: //自定 ...
随机推荐
- sqli-labs系列——第五关
less5 更改id后无果,不能用union联合查询 此处用报错注入 报错注入的概念:(1). 通过floor报错 and (select 1 from (select count(*),concat ...
- 开源的 Switch 模拟器——GitHub 热点速览 v.21.12
作者:HelloGitHub-小鱼干 脸滚键盘操作选手小鱼干这里要推荐一个超酷 Switch 模拟器,不能埋没你的游戏天赋.Ryujinx 是一个 C# 写的 Switch 模拟器,1700+ 游戏可 ...
- Kubernetes 部署策略详解-转载学习
Kubernetes 部署策略详解 参考:https://www.qikqiak.com/post/k8s-deployment-strategies/ 在Kubernetes中有几种不同的方式发布应 ...
- [图论]最短路径问题 :Floyed-Warshall
最短路径问题 目录 最短路径问题 Description Input Output Sample Input Sample Output 解析 了解Floyed算法 Floyed算法的核心思想: 代码 ...
- 快速了解Web MVC设计模式
MVC概述 MVC即 Model-View-Controller 的缩写,是按照职责划分模块一种设计模式,其中Model是核心. Model:模型.负责执行实际的业务,包含数据操作,可以向视图推送数据 ...
- OO第三单元作业——魔教规格
OO第三单元作业--魔教规格 JML的理论基础和相关工具 JML(Java Modeling Language,Java建模语言),在Java代码种增加了一些符号,这些符号用来标志一个方法是干什么 ...
- spring-cloud-stream消息驱动的微服务
Spring Cloud Stream 是 一 个用来为微服务应用构建消息驱动能力的框架. 它可以基于Spring Boot 来创建独立的. 可用于生产的 Spring 应用程序. 它通过使用 Spr ...
- Anacoda下报错conda command not found 以及TypeError: __new__() got an unexpected keyword argument 'serialized_options'
在anacoda安装完成后,执行conda list命令,显示command not found 解决方法: 对于anaconda 2 , 输入export PATH=~/anaconda2/bin ...
- Java后端进阶-网络编程(Netty线程模型)
前言 我们在使用Netty进行服务端开发的时候,一般来说会定义两个NioEventLoopGroup线程池,一个"bossGroup"线程池去负责处理客户端连接,一个"w ...
- [开源]制作docker镜像不依赖linux和Docker环境
背景 最近群友们经常反馈docker镜像制作起来有点麻烦,我开源的antdeploy工具虽然可以制作镜像但是必须有一个提前:有一台安装好docker的linux服务器.因为大家开发环境基本上都是win ...