Linux下zookeeper集群搭建

一、zookeeper集群简介

       Zookeeper集群的特点:可复制性

       强烈建立使用奇数个服务器,每个服务运行在单独的机器上.容错激设置至少需要3台服务器.

记录:

     1.设置zookeeper集群是一定要部署为2xF+1(即奇数)个server,这样可以允许F个Server出错(宕机或其他)。即:假设有三台server,则最多可以允许一台服务器宕机。集群继续正常工作。

     2. 设计zookeeper集群时,为了尽量抬高可靠性、容错性。部署服务器的时候,尽量让服务器位于不同的机房、或者在同一个机房中连接不同的交换机。防止一台交换机出错时,导致整体不可用。

二、集群中的配置介绍

需要注意的配置

    1.initLimit:

        集群中的小弟follower服务器,和领导leader服务器之间完成初始化同步连接时的能接受的最大心跳数,

        此时如果集群环境非常大,同步数据的时间较长,这个参数我们需要进行适当调整.  

    注意,在zookeeper中,任何时间的设置都是以ticktime的倍数来进行定义,如果我们设置initLimit=2.那我们能接受的最大时间就是ticktime*2

    2.syncLimit:

        follower和leader之间请求和应答能接受的最大心跳数

    集群节点的配置

        server.id = host:port:port

        id:通过在各自的dataDir目录下创建一个myId的文件来为每台机器赋予一个服务器id,这个id我们一般用基数数字表示

        两个port:第一个follower用来连接到leader,第二个用来选举leader

记录:了解Leader选举

        Zookeeper的启动过程中leader选举是非常重要而且最复杂的一个环节。那么什么是leader选举呢?zookeeper为什么需要leader选举呢?zookeeper的leader选举的过程又是什么样子的?

  首先我们来看看什么是leader选举。其实这个很好理解,leader选举就像总统选举一样,每人一票,获得多数票的人就当选为总统了。在zookeeper集群中也是一样,每个节点都会投票,如果某个节点获得超过半数以上的节点的投票,则该节点就是leader节点了。

  以一个简单的例子来说明整个选举的过程.

         假设有五台服务器组成的zookeeper集群,它们的id从1-5,同时它们都是最新启动的,也就是没有历史数据,在存放数据量这一点上,都是一样的.假设这些服务器依序启动,来看看会发生什么 。

         1) 服务器1启动,此时只有它一台服务器启动了,它发出去的报没有任何响应,所以它的选举状态一直是LOOKING状态  

         2) 服务器2启动,它与最开始启动的服务器1进行通信,互相交换自己的选举结果,由于两者都没有历史数据,所以id值较大的服务器2胜出,但是由于没有达到超过半数以上的服务器都同意选举它(这个例子中的半数以上是3),所以服务器1,2还是继续保持LOOKING状态.  

         3) 服务器3启动,根据前面的理论分析,服务器3成为服务器1,2,3中的老大,而与上面不同的是,此时有三台服务器选举了它,所以它成为了这次选举的leader.  

         4) 服务器4启动,根据前面的分析,理论上服务器4应该是服务器1,2,3,4中最大的,但是由于前面已经有半数以上的服务器选举了服务器3,所以它只能接收当小弟的命了.  

         5) 服务器5启动,同4一样,当小弟

三、zookeeper集群搭建

1>机器及端口准备

注意:防火墙问题,关闭防火墙或是防火墙过滤端口优先选择过滤端口

   需要在防火墙配置中(/etc/sysconfig/iptables)过滤以上使用到的端口号(Centos7默认防火墙firewall)

2>安装JDK  【此步骤省略】。

3>Zookeeper压缩包上传到服务器(这儿使用的是zookeeper-3.4.10.tar.gz);

压缩包下载地址:

https://archive.apache.org/dist/zookeeper/zookeeper-3.4.10/zookeeper-3.4.10.tar.gz

4>将zookeeper压缩包解压到/opt/zookeeper/目录下(这儿看个人公司要求,我们的组件默认都在此目录下)

tar -zxvf zookeeper-3.4.10.tar.gz -C /opt/zookeeper/

5>将 zookeeper-3.4.10/conf下zoo_sample.cfg 文件改名为 zoo.cfg

mv zoo_sample.cfg zoo.cfg

6>修改/opt/zookeeper/zookeeper-3.4.10/conf/zoo.cfg

vim /opt/zookeeper/zookeeper-3.4.10/conf/zoo.cfg

zoo.cfg文件配置如下:(当前为我们的外网环境配置示范)

# The number of milliseconds of each tick
tickTime=2000
# The number of ticks that the initial 
# synchronization phase can take
initLimit=10
# The number of ticks that can pass between 
# sending a request and getting an acknowledgement
syncLimit=5
# the directory where the snapshot is stored.
# do not use /tmp for storage, /tmp here is just 
# example sakes.(保存数据的路径,需要绝对路径)
dataDir=/data02/zookeeper/data		//数据存储路径
dataLogDir=/data01/zookeeper/log			//日志存储路径
# the port at which the clients will connect
clientPort=9611		//当前实例端口号
# the maximum number of client connections.
# increase this if you need to handle more clients
#maxClientCnxns=60
#
# Be sure to read the maintenance section of the 
# administrator guide before turning on autopurge.
#
# http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance
#
# The number of snapshots to retain in dataDir
#autopurge.snapRetainCount=3
# Purge task interval in hours
# Set to "0" to disable auto purge feature
#autopurge.purgeInterval=1
server.1= 10.123.14.32:9612:9613
server.2= 10.123.14.33:9612:9613
server.3= 10.123.14.34:9612:9613

参数说明 :

  1. 10.123.14.xx记录的是每个zookeeper实例的ip
  2. 9612 每个zookeeper实例通信的端口号s
  3. 9613选举leader时zookeeper实例使用的端口号

注意:data01下的zookeeper需手动创建(mkdir zookeeper) 

data02下的zookeeper/data需手动创建

7>同步/opt/zookeeper/zookeeper-3.4.10目录内容到另外两台机器(可在另外两台机器重复以上操作也可用命令)

scp	/opt/zookeeper/zookeeper-3.4.10 [email protected]:/opt/zookeeper/
scp	/opt/zookeeper/zookeeper-3.4.10 [email protected]:/opt/zookeeper/

注意:zookeeper目录需要手动创建(在opt/下执行 mkdir zookeeper) 否则会找不到路径

8>在每个实例配置文件zoo.cfg中dataDir指定的路径下(即/data02/zookeeper/data)创建一个myid文件,myid文件内容即为zookeeper实例的序列号,第一个实例即1,第二个即2,以此类推(即server.X= 10.123.14.32:9612:9613中的X)

记录:dataDir和dataLogDir

        zookeeper官方建议我们添加上dataLogDir来存放事务日志。如果只有dataDir目录而没有dataLogDir目录的话,它会把运行日志和事务日志都放在dataDir的那个目录上面去,事务日志和运行日志有什么区别?这个事务日志就相当于我们zookeeper的数据库,需要使用到读取和恢复等功能的时候,它就需要这么一个数据库来恢复。

9>修改环境变量 vim /etc/profile(已做jdk环境变量可忽略)

export ZOOKEEPER_HOME=/usr/local/zookeeper-3.4.10
export PATH=$ZOOKEEPER_HOME/bin:$PATH

配置生效:

source /etc/profile

10>添加zookeeper用户并设置密码(看个人公司要求,为规避风险尽量避免使用root用户)

useradd zookeeper
passwd  zookeeper

删除用户:userdel 用户名

11>将opt下的zookeeper所属切换到zookeeper用户下,文件赋予zookeeper用户权限

在opt路径下执行(数据日志和事务日志文件夹需同样的操作)

chown -R  zookeeper:zookeeper zookeeper/

12>将当前的root用户切换到zookeeper用户

su zookeeper

13>集群启动-在zookeeper用户下分别启动集群下各个zookeeper实例(规避风险-非root用户启动)

bin/zkServer.sh start

14>查看zk启动状态

bin/zkServer.sh status

至此,搭建完成

三、zookeeper集群测试

 客户端连接:

./bin/zkCli.sh -server 10.123.14.33:9611

一些操作命令

[zk: 10.123.14.33:9611(CONNECTED) 2] create /zk_test hello
Created /zk_test
[zk: 10.123.14.33:9611(CONNECTED) 3] get /zk_test
hello
cZxid = 0x100000003
ctime = Wed Sep 19 18:04:00 CST 2018
mZxid = 0x100000003
mtime = Wed Sep 19 18:04:00 CST 2018
pZxid = 0x100000003
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 5
numChildren = 0
[zk: 10.123.14.33:9611(CONNECTED) 4] set /zk_test fuck
cZxid = 0x100000007
ctime = Wed Sep 19 18:09:32 CST 2018
mZxid = 0x100000008
mtime = Wed Sep 19 18:09:40 CST 2018
pZxid = 0x100000007
cversion = 0
dataVersion = 1
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 4
numChildren = 0
[zk: 10.123.14.33:9611(CONNECTED) 5] get /zk_test
fuck
cZxid = 0x100000007
ctime = Wed Sep 19 18:09:32 CST 2018
mZxid = 0x100000008
mtime = Wed Sep 19 18:09:40 CST 2018
pZxid = 0x100000007
cversion = 0
dataVersion = 1
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 4
numChildren = 0
[zk: 10.123.14.33:9611(CONNECTED) 6] delete /zk_test
[zk: 10.123.14.33:9611(CONNECTED) 7] ls /
[zookeeper]
[zk: 10.123.14.33:9611(CONNECTED) 8]

四、zookeeper高可用测试

  1. 准备:配置了3台的测试环境,三台完全启动之后,查看状态,两台是follower,一台是leader.
  2. 开始测试高可用:
  1. 运行kill -9 命令杀死三个zookeeper中的一个。集群运行正常。

     2. 运行kill -9 命令杀死三个zookeeper中的两个。集群全部失效。

总结:也就是说三台服务器中,如果一台宕机,集群是可以继续正常运行的,但是两台宕机就不可以了。

查阅官网文档之后,发现如下的doc:

Cross Machine Requirements
For the ZooKeeper service to be active, there must be a majority of non-failing machines that can communicate with each other. To create a deployment that can tolerate the failure of F machines, you should count on deploying 2xF+1 machines. Thus, a deployment that consists of three machines can handle one failure, and a deployment of five machines can handle two failures. Note that a deployment of six machines can only handle two failures since three machines is not a majority. For this reason, ZooKeeper deployments are usually made up of an odd number of machines.
To achieve the highest probability of tolerating a failure you should try to make machine failures independent. For example, if most of the machines share the same switch, failure of that switch could cause a correlated failure and bring down the service. The same holds true of shared power circuits, cooling systems, etc.

 总结起来,就是如下几点:

1.设置zookeeper集群是一定要部署为2xF+1(即奇数)个server,这样可以允许F个Server出错(宕机或其他)。即:假设有三台server,则最多可以允许一台服务器宕机。集群继续正常工作。

2. 设计zookeeper集群时,为了尽量抬高可靠性、容错性。部署服务器的时候,尽量让服务器位于不同的机房、或者在同一个机房中连接不同的交换机。防止一台交换机出错时,导致整体不可用。

五、异常情况----安装或启动异常

1>连接异常:(服务是否正常启动,端口号是否已过滤开放)

端口号开放:

  1. 查询端口号80 是否开启:firewall-cmd --query-port=80/tcp
  2. 永久开放80端口号:firewall-cmd --permanent --zone=public --add-port=80/tcp
  3. 移除80端口号:firewall-cmd --permanent --zone=public --remove-port=80/tcp
  4. --zone #作用域
    --add-port=80/tcp  #添加端口,格式为:端口/通讯协议
    --permanent   #永久生效,没有此参数重启后失效

查看防火墙状态
systemctl status firewalld.service
启动|关闭|重新启动  防火墙
systemctl [start|stop|restart] firewalld.service 

2>Error contacting service. It is probably not running.

网上问题答案有许多种,一一归纳:

1. zoo.cfg配置文件中指定目录却没有创建! 创建相应目录即可。

2. zoo.cfg中dataDir指定路径为Myid文件的路径。

Myid内容与:server.?=localhost:2888:3888 中你所设置?一致!

3.使用service iptables stop 关闭防火墙

使用service iptables status确认

4. 1,打开zkServer.sh 找到

status)

STAT=`echo stat | nc localhost $(grep clientPort "$ZOOCFG" | sed -e 's/.*=//') 2> /dev/null| grep Mode`

在nc与localhost之间加上 -q 1 (是数字1而不是字母l)

如果已存在则去掉

5.2181端口被占用! #我就是死在这的,死了很久很久。。

zkServer.sh stop #先停止zookeep

netstat -an | grep 9611 #查看端口是否占用,如果占用

clientPort = 9611 #随便找个没占用的端口号!

你可能感兴趣的:(zookeeper集群搭建,zookeeper集群常见错误,linux,zookeeper集群,zookeeper集群异常)