うさぎ好きエンジニアの備忘録

うさぎたちに日々癒されているエンジニアが業務で直面したもの & 個人的な学習メモを残していきます。

ZooKeeper のクラスタを構築してみる。

何をしようかと考えてみたのですが、特に思い浮かばなかったので ZooKeeper のクラスタを構築してみようと思います。

今回使うサーバ

今回は以下の条件でクラスタを構築していきたいと思います。

  • ホスト名 … ponteru.zk00[1-3]
  • ZooKeeper のバージョン … 3.4.10

前準備

ZooKeeper は実行時に Java が必要になるので前もって入れておきましょう。

$ sudo yum install java-1.8.0-openjdk java-1.8.0-openjdk-devel

ZooKeeper のインストー

以下の手順で ZooKeeper をインストールしていきます。

# バイナリとかのダウンロード
$ wget http://ftp.riken.jp/net/apache/zookeeper/zookeeper-3.4.10/zookeeper-3.4.10.tar.gz
  
# ダウンロードしたファイルの解凍
$ tar xzf zookeeper-3.4.10.tar.gz

今回は /usr/local/ 配下にダウンロードしたディレクトリを配置してリンクを生成しておきました。

# 今回は /usr/local に配置
$ sudo mv zookeeper-3.4.10 /usr/local
  
# シンボリックリンクを作っておく
$ sudo ln -s /usr/local/zookeeper-3.4.10 /usr/local/zookeeper

設定ファイルの編集

zoo.cfg の作成

今回は conf/zoo_sample.cfg を流用して設定ファイルを作成していくので conf/zoo_sample.cfg を conf/zoo.cfg としてコピーします。

$ sudo cp /usr/local/zookeeper/conf/zoo_sample.cfg /usr/local/zookeeper/conf/zoo.cfg

今回は zoo.cfg を以下のように編集しました。

# dataDir=/tmp のままだと情報が保持されないので保存先ディレクトリを変更
dataDir=/var/lib/zookeeper
  
# 末尾に quorum を構成する ZooKeeper 一覧を追記
server.1=ponteru.zk001:2182:2183
server.2=ponteru.zk002:2182:2183
server.3=ponteru.zk003:2182:2183

なお、zoo.cfg の末尾に追記した内容 server.=:<port_1>:<port_2> の規則に従っています。

変数名 説明
nodeId 各 ZooKeeper に割り当てる一意の値 (myid ファイルに記述)
hostname 割り当てた nodeId に対応した ZooKeeper のホスト名
port_1 他の ZooKeeper と通信するために使用するポート番号
port_2 リーダーと通信するために使用するポート番号
データディレクトリの作成

dataDir で指定したディレクトリがない場合は作成しておきましょう。

$ sudo mkdir /var/lib/zookeeper
myid ファイルの作成

各 ZooKeeper に対して、割り当てる nodeId を記述した myid ファイルをデータディレクトリ配下 (/var/lib/zookeeper) に作成します。

# ponteru.zk001 の場合
$ echo 1 | sudo tee /var/lib/zookeeper/myid
  
# ponteru.zk002 の場合
$ echo 2 | sudo tee /var/lib/zookeeper/myid
  
# ponteru.zk003 の場合
$ echo 3 | sudo tee /var/lib/zookeeper/myid

ZooKeeper の起動

以下のコマンドを全ホストで行えばおkです。

$ sudo /usr/local/zookeeper/bin/zkServer.sh start

ちょっと検証してみる

とりあえずクラスタが構築できているか確認するために status を確認してみます。

# ponteru.zk001 ... リーダーじゃない
$ /usr/local/zookeeper/bin/zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /usr/local/zookeeper/bin/../conf/zoo.cfg
Mode: follower

# ponteru.zk002 ... リーダーじゃない
$ /usr/local/zookeeper/bin/zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /usr/local/zookeeper/bin/../conf/zoo.cfg
Mode: follower
 
# ponteru.zk003 ... リーダー
$ /usr/local/zookeeper/bin/zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /usr/local/zookeeper/bin/../conf/zoo.cfg
Mode: leader

上記の結果からクラスタが構築できていることがわかりました。

次にリーダーを落としてみます。

# ponteru.zk003
$ sudo /usr/local/zookeeper/bin/zkServer.sh stop
ZooKeeper JMX enabled by default
Using config: /usr/local/zookeeper/bin/../conf/zoo.cfg
Stopping zookeeper ... STOPPED

# ponteru.zk002
$ /usr/local/zookeeper/bin/zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /usr/local/zookeeper/bin/../conf/zoo.cfg
Mode: leader

# ponteru.zk001
$ /usr/local/zookeeper/bin/zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /usr/local/zookeeper/bin/../conf/zoo.cfg
Mode: follower

リーダーが ponteru.zk002 に移りました!さらにリーダーを落としてみます。

# ponteru.zk002
$ sudo /usr/local/zookeeper/bin/zkServer.sh stop
ZooKeeper JMX enabled by default
Using config: /usr/local/zookeeper/bin/../conf/zoo.cfg
Stopping zookeeper ... STOPPED

# ponteru.zk001
$ /usr/local/zookeeper/bin/zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /usr/local/zookeeper/bin/../conf/zoo.cfg
Error contacting service. It is probably not running.

クラスタとしての機能がなくなりました。(ZooKeeper のクラスタは多数決の原理で動作しているので、過半数のホストが落ちると機能しなくなります。)

まとめてきなもの

ZooKeeper のクラスタ構築方法についてまとめてみました。 意外と ZooKeeper を使うシーンは多いので、まだ構築したことないという方はぜひ!