Zookeeper遷移(擴容/縮容)

zookeeper選舉原理

在遷移前有必要了解zookeeper的選舉原理,以便更科學的遷移。

快速選舉FastLeaderElection

zookeeper默認使用快速選舉,在此重點了解快速選舉:

  1. 向集羣中的其他zookeeper建立連接,並且只有myid比對方大的連接纔會被接受(也就是每2臺只會有1個連接,避免連接浪費)

  2. 每臺zookeeper默認先投自己,然後向集羣廣播自己的選票

  3. 收到對方的選票時,依次比較epoch(選舉輪數)、zxid(事務id)、myid,較大者勝出,更新選票並廣播

  4. 如果收到的選票中有某個節點超過集羣半數,則勝出當選爲leader,其他節點爲follower

注意事項

  • zookeeper集羣的數量應爲奇數:

    因爲根據paxos理論,只有集羣中超過半數的節點還存活才能保證集羣的一致性。假如目前集羣有5個節點,我們最多允許2個節點不可用,因爲3>5\2。當集羣擴容到6個節點的時候,我們仍然只能最多允許2個節點不可用,到3個節點不可用時,將不滿足paxos理論,因爲3>6\2不成立。也就是說當集羣節點數n爲偶數時,其可用性與n-1是一樣的,那我們何必多浪費一臺機器呢?

  • 由於zookeeper只允許mid大的節點連接到mid小的節點,我們啓動zookeeper的順序應該按照myid小的到myid大的,最後再啓動leader節點!

遷移目標

遷移過程中要保證原zookeeper集羣還是能提供服務,新zookeeper集羣同步老集羣的數據,將zookeeper 域名指向新集羣的3個節點,停掉老zookeeper集羣。

相當於先擴容zookeeper,然後縮容zookeeper…

遷移步驟

原有zookeeper集羣(server1、server2、server3)zoo.cfg配置如下:

1
2
3
4
5

# 省略其他配置
dataDir=/data
server.1=node1:2888:3888
server.2=node2:2888:3888
server.3=node3:2888:3888

使用命令:echo srvr | nc HOSTNAME 2181檢查誰是leader({?}依次替換爲1、2、3)

ps:也可以用echo stat | nc HOSTNAME 2181顯示更詳細信息

這裏假設leader爲node2.(按照正常情況,leader也理應是node2)

步驟1:新增節點4

  1. /data目錄創建mid文件,內容爲4

  2. 配置zoo.cfg,內容如下:

    1
    2
    3
    4
    5
    6

    # 省略其他配置
    dataDir=/data
    server.1=node1:2888:3888
    server.2=node2:2888:3888
    server.3=node3:2888:3888
    server.4=node4:2888:3888

  3. 啓動zookeeper:{zookeeperDir}/bin/zkServer.sh start

  4. 檢查所有節點是否提供服務,且集羣中只有一個leader,例如以下命令:

    image2019-5-23_11-11-1.png?version=1&modificationDate=1558581062000&api=v2

可以看到Mode表示該節點的角色爲leader。依次檢查每一個節點,如果沒有響應,或者出現多個leader,需要還原整個集羣!

步驟2:新增節點5

  1. /data目錄創建mid文件,內容爲5

  2. 配置zoo.cfg,內容如下:

    1
    2
    3
    4
    5
    6
    7

    # 省略其他配置
    dataDir=/data
    server.1=node1:2888:3888
    server.2=node2:2888:3888
    server.3=node3:2888:3888
    server.4=node4:2888:3888
    server.5=node5:2888:3888

  3. 啓動zookeeper:{zookeeperDir}/bin/zkServer.sh start

  4. 檢查所有節點是否提供服務,且集羣中只有一個leader:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

    $ echo srvr | nc HOSTNAME 2181
    ...
    $ echo srvr | nc HOSTNAME 2181
    ...
    $ echo srvr | nc HOSTNAME 2181
    ...
    $ echo srvr | nc HOSTNAME 2181
    ...
    $ echo srvr | nc HOSTNAME 2181
    ...

步驟3:新增節點6

  1. /data目錄創建mid文件,內容爲6

  2. 配置zoo.cfg,內容如下:

    1
    2
    3
    4
    5
    6
    7
    8

    # 省略其他配置
    dataDir=/data
    server.1=node1:2888:3888
    server.2=node2:2888:3888
    server.3=node3:2888:3888
    server.4=node4:2888:3888
    server.5=node5:2888:3888
    server.6=node6:2888:3888

  3. 啓動zookeeper:{zookeeperDir}/bin/zkServer.sh start

  4. 檢查所有節點是否提供服務,且集羣中只有一個leader:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12

    $ echo srvr | nc HOSTNAME 2181
    ...
    $ echo srvr | nc HOSTNAME 2181
    ...
    $ echo srvr | nc HOSTNAME 2181
    ...
    $ echo srvr | nc HOSTNAME 2181
    ...
    $ echo srvr | nc HOSTNAME 2181
    ...
    $ echo srvr | nc HOSTNAME 2181
    ...

步驟4:更新節點4

  1. 修改節點4的配置如下:

    1
    2
    3
    4
    5
    6
    7
    8

    # 省略其他配置
    dataDir=/data
    server.1=node1:2888:3888
    server.2=node2:2888:3888
    server.3=node3:2888:3888
    server.4=node4:2888:3888
    server.5=node5:2888:3888
    server.6=node6:2888:3888

  2. 重啓節點4的zookeeper:{zookeeperDir}/bin/zkServer.sh restart

  3. 檢查所有節點是否提供服務,且集羣中只有一個leader:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12

    $ echo srvr | nc HOSTNAME 2181
    ...
    $ echo srvr | nc HOSTNAME 2181
    ...
    $ echo srvr | nc HOSTNAME 2181
    ...
    $ echo srvr | nc HOSTNAME 2181
    ...
    $ echo srvr | nc HOSTNAME 2181
    ...
    $ echo srvr | nc HOSTNAME 2181
    ...

步驟5:更新節點5

同步驟4

步驟6:更新老集羣節點1

  1. 修改節點1的配置如下:

    1
    2
    3
    4
    5
    6
    7
    8

    # 省略其他配置
    dataDir=/data
    server.1=node1:2888:3888
    server.2=node2:2888:3888
    server.3=node3:2888:3888
    server.4=node4:2888:3888
    server.5=node5:2888:3888
    server.6=node6:2888:3888

  2. 重啓節點4的zookeeper:{zookeeperDir}/bin/zkServer.sh restart

  3. 檢查所有節點是否提供服務,且集羣中只有一個leader:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12

    $ echo srvr | nc HOSTNAME 2181
    ...
    $ echo srvr | nc HOSTNAME 2181
    ...
    $ echo srvr | nc HOSTNAME 2181
    ...
    $ echo srvr | nc HOSTNAME 2181
    ...
    $ echo srvr | nc HOSTNAME 2181
    ...
    $ echo srvr | nc HOSTNAME 2181
    ...

步驟7:更新老集羣節點3

同步驟6

步驟8:更新老集羣節點2

最後更新leader節點:node2,同步驟6

ps:這時候如果沒有讀寫zookeeper操作,集羣的leader將變爲節點6(因爲節點6的myid最大)

步驟9:將原有zookeeper的url指向新的節點

修改域名解析,將zookeeper解析到新的3個節點上 (例如test1.zookeeper.com、test2.zookeeper.com、test3.zookeeper.com)指向node4,node5,node6

相關業務系統重啓(避免緩存)

步驟10:老zookeeper集羣下線

這一步需要等待所有的業務系統都重啓之後。

這時候還是得一臺一臺關閉(下線),因爲假如同時關閉HOSTNAME和node2,那當重啓node3的時候集羣將不可用(沒有超過集羣半數的節點存活)

步驟10.1:下線zookeeper老集羣中的節點1

關閉HOSTNAME: {zookeeperDir}/bin/zkServer.sh stop

依次修改node2,3,4,5,6的配置,並且重啓,配置如下:

1
2
3
4
5
6
7

# 省略其他配置
dataDir=/data
server.2=node2:2888:3888
server.3=node3:2888:3888
server.4=node4:2888:3888
server.5=node5:2888:3888
server.6=node6:2888:3888

重啓後檢查所有節點是否提供服務,且集羣中只有一個leader。

ps:這時候如果沒有讀寫zookeeper操作,leader將變成node5,因爲node6節點重啓的時候,集羣重新選舉,node5的myid最大

步驟10.2:下線zookeeper老集羣中的節點2

關閉node2: {zookeeperDir}/bin/zkServer.sh stop

依次修改node3,4,5,6的配置,並且重啓,配置如下:

1
2
3
4
5
6

# 省略其他配置
dataDir=/data
server.3=node3:2888:3888
server.4=node4:2888:3888
server.5=node5:2888:3888
server.6=node6:2888:3888

重啓後檢查所有節點是否提供服務,且集羣中只有一個leader。

ps:這時候如果沒有讀寫zookeeper操作,leader將重新變成node6

步驟10.3:下線zookeeper老集羣中的節點3

關閉node3: {zookeeperDir}/bin/zkServer.sh stop

依次修改node4,5,6的配置,並且重啓,配置如下:

1
2
3
4
5

# 省略其他配置
dataDir=/data
server.4=node4:2888:3888
server.5=node5:2888:3888
server.6=node6:2888:3888

重啓後檢查所有節點是否提供服務,且集羣中只有一個leader。

ps:這時候如果沒有讀寫zookeeper操作,node5將成爲最終的leader

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章