zookeeper的安装基本上可以按照 zookeeperStartedhtml 这个页面上的步骤完成安装,这里主要介绍下部署一个集群的步骤,因为这个官方页面似乎讲得并不是非常详细(Running Replicated Zookeeper)。
由于手头机器不足,所以在一台机器上部署了3个server,如果你手头也比较紧,也可以这么做。那么我建了3个文件夹,如下
server1 server2 server3
然后每个文件夹里面解压一个zookeeper的下载包,并且还建了几个文件夹,总体结构如下,最后那个是下载过来压缩包的解压文件
data dataLog logs zookeeper-332
那么首先进入data目录,创建一个myid的文件,里面写入一个数字,比如我这个是server1,那么就写一个1,server2对应myid文件就写入2,server3对应myid文件就写个3
然后进入zookeeper-332/conf目录,那么如果是刚下过来,会有3个文件,configurationxml, log4jproperties,zoo_samplecfg,这3个文件我们首先要做的就是在这个目录创建一个zoocfg的配置文件,当然你可以把zoo_samplecfg文件改成zoocfg,配置的内容如下所示:
tickTime=2000
initLimit=5
syncLimit=2
dataDir=xxxx/zookeeper/server1/data
dataLogDir=xxx/zookeeper/server1/dataLog
clientPort=2181
server1=127001:2888:3888
server2=127001:2889:3889
server3=127001:2890:3890
标红的几个配置应该官网讲得很清楚了,只是需要注意的是clientPort这个端口如果你是在1台机器上部署多个server,那么每台机器都要不同的clientPort,比如我server1是2181,server2是2182,server3是2183,dataDir和dataLogDir也需要区分下。
最后几行唯一需要注意的地方就是 serverX 这个数字就是对应 data/myid中的数字。你在3个server的myid文件中分别写入了1,2,3,那么每个server中的zoocfg都配server1,server2,server3就OK了。因为在同一台机器上,后面连着的2个端口3个server都不要一样,否则端口冲突,其中第一个端口用来集群成员的信息交换,第二个端口是在leader挂掉时专门用来进行选举leader所用。
进入zookeeper-332/bin 目录中,/zkServersh start启动一个server,这时会报大量错误看其实没什么关系,因为现在集群只起了1台server,zookeeper服务器端起来会根据zoocfg的服务器列表发起选举leader的请求,因为连不上其他机器而报错,那么当我们起第二个zookeeper实例后,leader将会被选出,从而一致性服务开始可以使用,这是因为3台机器只要有2台可用就可以选出leader并且对外提供服务(2n+1台机器,可以容n台机器挂掉)。
接下来就可以使用了,我们可以先通过 zookeeper自带的客户端交互程序来简单感受下zookeeper到底做一些什么事情。进入zookeeper-332/bin(3个server中任意一个)下,/zkClish –server 127001:2182,我连的是开着2182端口的机器。
那么,首先我们随便打个命令,因为zookeeper不认识,他会给出命令的help,如下图
ls(查看当前节点数据),
ls2(查看当前节点数据并能看到更新次数等数据) ,
create(创建一个节点) ,
get(得到一个节点,包含数据和更新次数等数据),
set(修改节点)
delete(删除一个节点)
通过上述命令实践,我们可以发现,zookeeper使用了一个类似文件系统的树结构,数据可以挂在某个节点上,可以对这个节点进行删改。另外我们还发现,当改动一个节点的时候,集群中活着的机器都会更新到一致的数据。在 Application Virtualization Server Management Console 中创建服务器组之后,可以使用以下过程向该组中添加服务器。注意 服务器组中的所有服务器必须连接到相同的数据存储。
向组中添加服务器单击左窗格中的“服务器组”节点,展开服务器组列表。右键单击所需的服务器组,然后选择“新建 Application Virtualization Management Server”。在“新建服务器组向导”中,输入“显示名称”和“DNS 主机名”。保留“最大内存分配”字段中的默认值作为服务器缓存,并将“警告内存分配”字段中的默认值指定为阈值警告级别。单击“下一步”。
如果需要,请在“连接安全模式”对话框中,选中“使用增强的安全性”框以选择增强的安全性模式。必要时,完成“证书向导”或查看现有证书。单击“下一步”。在“App Virt 端口设置”对话框中,选择“使用默认端口”,或选择“用户自定义端口”单选按钮并输入自定义端口号。单击“完成”。按照 docker搭建zookeeper集群 中步骤,安装完docker,配置好三台容器后,启动zookeeper环境。发现两台正常,一台报Notification timeout的日志。
而异常的原因是cannot assign requested address。该问题要么ip、port不通要么就是开启监听的server地址和发送消息的地址不对。
查看源码位置,发现在QuorumCnxManagerjava文件中抛的异常
找到异常,去上下看看是否有迹可循
然后,去日志看下绑定的ip、port是什么。发现Slave1的日志里打印出了信息
2018-06-15 01:28:53,612 [myid:3] - INFO [Slave2/1721704:3890:QuorumCnxManager$Listener@534] - My election bind port: Slave2/1721704:3890
我的zoocfg server配置如下
server1=Master:2888:3888
server2=Slave1:2889:3889
server3=Slave2:2890:3890
参考“艾伦蓝”的博客介绍了
serverA=B:C:D: 其中 A 是一个数字,表示这个是第几号服务器; B 是这个服务器的 ip 地址;C 表示的是这个服务器与集群中的 Leader 服务器交换信息的端口;D 表示的是万一集群中的 Leader 服务器挂了,需要一个端口来重新进行选举,选出一个新的 Leader,而这个端口就是用来执行选举时服务器相互通信的端口。 如果是伪集群的配置方式,由于 B 都是一样,所以不同的 Zookeeper 实例通信端口号不能一样,所以要给它们分配不同的端口号。
也就是说我本地绑定的端口是server3的端口。(看日志感觉应该起的server2的3889才对!)
剩下的工作就是看看zookeeper配置文件如何加载,为什么解析的不正确!
回到刚才的源码,获取addr的地方:
addr = selfquorumPeersget(selfgetId())electionAddr;
查看QuorumPeerConfigjava发现quorumPeers存的是server1,2,3的信息。那id是哪来的?
public long getId() {
return myid;
}
myid又是从哪里来的?
这个myid是解析myid的文件来的。
莫非是这个myid还要和server#的值必须匹配起来?
server2的myid必须是2。
查看Slave1和Slave2的myid文件,果然Slave1 写的3,Slave2写的2。
以上!得出结论修改Slave1和Slave2的myid文件为2,3。
问题解决!!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)