更新:下面的操作都是基于不停机不停服务的前提下的。如果可以停服务的话,你想怎么折腾就怎么折腾(只要zoo.cfg和myid一致就行)。
收告警邮件实在是收到烦了,zookeeper实例的机器挂掉了,机器一直没人处理。最后最终还是改了告警的脚本(呵呵,等到快出问题的时刻才告警)。
过程中也尝试了添加删除节点,下面是对本次体验的一些记载。
告警的检查脚本帖出来:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
| msg=`$HADOOP_HOME/bin/hdfs getconf -confKey ha.zookeeper.quorum 2>/dev/null`
zks_total=`echo "$msg" | awk 'BEGIN{RS=","; } {print}' | grep -v '^$' `
total_count=`echo "$zks_total" | wc -l `
lost_zks=`echo "$zks_total" | while read zk ; do if ! echo mntr | nc ${zk//:/ } | grep zk_server_state >/dev/null ; then echo "$zk " ; fi ; done `
lost_count=`echo "$lost_zks" | grep -v "^$" | wc -l `
lost_zks=`echo $lost_zks `
message="Zookeepers total: $total_count, dead: $lost_count"
if [[ "$lost_count" != 0 ]]
then
message="$message; Dead: $lost_zks"
fi
if (( $lost_count*2 > $total_count )) ; then
echo "CRITICAL - $message"
exit 2
elif (( $total_count/2 == $lost_count )) ; then
echo "WARNING - $message"
exit 1
else
echo "OK - $message"
exit 0
fi
|
zookeeper3.5
zookeeper3.5的版本已经有动态增删节点的功能。
手动割接问题节点
生产的是3.4的,不支持reconfig的命令。这里使用 rolling restarts 手动切换的方式来进行割接,在测试环境通过不同的端口来模拟3台机器:
割接的时刻,最好一台台的加,不然可能会出现数据不一致的情况:https://www.slideshare.net/Hadoop_Summit/dynamic-reconfiguration-of-zookeeper
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
| [hadoop@cu3 zktest]$ mv zoo_sample.cfg zoo1.cfg
[hadoop@cu3 zktest]$ sed -e 's/12181/22181/' -e 's/data1/data2/' zoo1.cfg >zoo2.cfg
[hadoop@cu3 zktest]$ sed -e 's/12181/32181/' -e 's/data1/data3/' zoo1.cfg >zoo3.cfg
[hadoop@cu3 zktest]$ cat zoo3.cfg
tickTime=2000
initLimit=10
syncLimit=5
#maxClientCnxns=60
dataDir=/home/hadoop/zktest/data3
clientPort=32181
server.1=localhost:13888:13999
server.2=localhost:23888:23999
server.3=localhost:33888:33999
[hadoop@cu3 zktest]$ for i in {1..3} ; do echo $i >data$i/myid ; done
# 添加两个便利的函数
[hadoop@cu3 zktest]$ function zkstat {
> for i in {1..4} ; do ( echo "${i}2181 => `cat data$i/zookeeper_server.pid` : `echo mntr | nc localhost ${i}2181 | grep zk_server_state | awk '{print $2}' ` " ) ; done
> }
[hadoop@cu3 zktest]$ function zkstart {
> for i in "$@" ; do (cd data$i ; ~/zookeeper-3.4.6/bin/zkServer.sh start /home/hadoop/zktest/zoo$i.cfg ) ; done
> }
[hadoop@cu3 zktest]$ zkstart {1..3}
|
切换时,Leader一直不变
模拟server.1进程down掉,用一个新的server.4代替: 切换的过程中不能停leader!!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
| # 配置server.4
[hadoop@cu3 zktest]$ sed -e 's/12181/42181/' -e 's/data1/data4/' zoo1.cfg >zoo4.cfg
[hadoop@cu3 zktest]$ mkdir data4
[hadoop@cu3 zktest]$ echo 4 > data4/myid
# 去掉server.1,添加server.4
[hadoop@cu3 zktest]$ vi zoo4.cfg
...
server.4=localhost:43888:43999
[hadoop@cu3 zktest]$ zkstat
12181 => 20750 : follower
22181 => 21037 : leader
32181 => 21075 : follower
42181 => 19757 :
# 停server.1
[hadoop@cu3 zktest]$ kill 20750
# 启动server.4
[hadoop@cu3 zktest]$ zkstart {2..4}
[hadoop@cu3 zktest]$ zkstat
12181 => 20750 :
22181 => 21037 : leader
32181 => 21075 : follower
42181 => 21246 : follower
此时server.4是新的配置,server.2和server.3是旧的配置。
# 停server.3,注意这里不能停leader!!
[hadoop@cu3 zktest]$ kill 21075
[hadoop@cu3 zktest]$ zkstat
12181 => 20750 :
22181 => 21037 : leader
32181 => 21075 :
42181 => 21246 : follower
# server.3的配置:server.1换成server.4
[hadoop@cu3 zktest]$ vi zoo3.cfg
[hadoop@cu3 zktest]$ zkstart 3
JMX enabled by default
Using config: /home/hadoop/zktest/zoo3.cfg
Starting zookeeper ... STARTED
[hadoop@cu3 zktest]$ zkstat
12181 => 20750 :
22181 => 21037 : leader
32181 => 21791 : follower
42181 => 21246 : follower
3个server有两个已经是新的配置,现在停掉leader后重新选举也是ok的。
# 最后停leader,修改zoo2.cfg。集群down节点成功切换!!
[hadoop@cu3 zktest]$ zkstat
12181 => 20750 :
22181 => 22044 : follower
32181 => 21791 : follower
42181 => 21246 : leader
|
中间停Leader,重新选领导失败
现在再测试下中间过程停leader会是什么效果呢?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
| # 先zoo4挂掉了,用zoo1来补充。
[hadoop@cu3 zktest]$ zkstat
12181 => 20750 :
22181 => 22044 : leader
32181 => 21791 : follower
42181 => 21246 :
配置 zoo1:
# 修改zoo1的配置 和 myid,不能用原来的旧id: Have smaller server identifier, so dropping the connection: (3, 1)
server.5=localhost:13888:13999
server.2=localhost:23888:23999
server.3=localhost:33888:33999
# 此时zoo2,zoo3的配置为:
server.2=localhost:23888:23999
server.3=localhost:33888:33999
server.4=localhost:43888:43999
# 启动zoo1(id=5)
[hadoop@cu3 zktest]$ zkstart 1
[hadoop@cu3 zktest]$ zkstat
12181 => 22439 : follower
22181 => 22044 : leader
32181 => 21791 : follower
42181 => 21246 :
如果这里停的leader,zoo1收不到大于1/2的投票?
(觉得:只能在配置里面server才会被接受选票,
所以停了zoo2(leader)后,zoo3配置里面的server就只有自己了,zoo3也就拒接服务,然后接着zoo1(id=5)也拒接服务)
[hadoop@cu3 zktest]$ kill 22044
[hadoop@cu3 zktest]$ zkstat
12181 => 22439 :
22181 => 22044 :
32181 => 21791 :
42181 => 21246 :
[hadoop@cu3 zktest]$ jps -m | grep zktest
21791 QuorumPeerMain /home/hadoop/zktest/zoo3.cfg
22439 QuorumPeerMain /home/hadoop/zktest/zoo1.cfg
服务挂了!!
|
所以说5台zookeeper还是很有必要的,5台的话挂掉一台,Leader在切换的过程中停掉了其他三台机器也能正常选举出新的Leader。
正常切换后,应用不需要修改。只要zkserver中的一台zk服务器能连接就可以了。但可能监控的需要进行修改,因为原来是监控所有服务的,配置可能需要进行相应的修改。
–END