失敗は一時の恥

パッケージソフト開発をしているプログラマが気の赴くままに何かを投稿するブログ.

ZooKeeper の管理コマンド

ZooKeeper の管理コマンド

概要

Apache ZooKeeper には,稼働状況などを取得するための管理コマンドがあります.

この管理コマンドでどのようなことができるのか試してみたいと思います.

管理コマンド

管理コマンドの内容は,ZooKeeper Administrator's Guide で説明されています.

管理コマンドは,クライアントライブラリ等を使用するのではなく,TCP 接続でメッセージを送ることで呼び出します. 送信するメッセージが 4 文字なので,4 文字コマンド (Four Letter Worlds commands) と呼ばれます.

最も簡単な例として,"ruok" コマンドを呼んでみます.これは "Are you OK?" の意味で,ZooKeeper が稼働していれば "imok" を返すというだけのものです.

$ echo ruok | nc localhost 2181
imok

このようなコマンドが十数個提供されています.

  • conf
  • cons
  • crst
  • dump
  • envi
  • ruok
  • srst
  • srvr
  • stat
  • wchs
  • wchc
  • wchp
  • mntr

管理コマンドを有効にする

呼び出せる管理コマンドは,プロパティファイル zoo.cfg の 4lw.commands.whitelist で指定することができます (あるいは,Javaシステムプロパティ zookeeper.4lw.commands.whitelist でも可).

このプロパティを指定しなかった場合はデフォルトで,"wchp" と "wchc" を除くすべてのコマンドが呼び出せる状態となっています.

注意!: ZooKeeper 3.5 ではこのデフォルトが変更されています.プロパティ未指定の場合に呼び出せるコマンドは srvr のみです.

各コマンドの内容

各コマンドを実際に呼んでみます. 数がそこそこあるので,ゆるい感じでサクっと試します.

ここで挙げる例は,Docker で起動した ZooKeeper から得られたものです.

conf

適用されている設定 (zoo.cfg に記述するもの) を取得します.

$ echo conf | nc localhost 2181
clientPort=2181
dataDir=/data/version-2
dataLogDir=/datalog/version-2
tickTime=2000
maxClientCnxns=60
minSessionTimeout=4000
maxSessionTimeout=40000
serverId=0

上記の出力について,実際の zoo.cfg には dataDir=/data と指定しているのですが,それとは異なる値が取れてきています. 細かい挙動は注意して使ったほうがいいのかもしれません.

cons

現在サーバーに接続してるすべてのクライアントのコネクション/セッションを表示します. 送受信したパケット数,セッション ID,レイテンシ等さまざまな情報が付随します.

echo cons | nc localhost 2181
/127.0.0.1:37251[0](queued=0,recved=1,sent=0)
/127.0.0.1:58686[1](queued=0,recved=4,sent=4,sid=0x100088f2a4e0000,lop=PING,est=1523313273401,to=30000,lzxid=0x3,lresp=144169653,llat=1,minlat=0,avglat=0,maxlat=1)
/127.0.0.1:58740[1](queued=0,recved=4,sent=4,sid=0x100088f2a4e0001,lop=PING,est=1523313322911,to=30000,lzxid=0x3,lresp=144164469,llat=0,minlat=0,avglat=0,maxlat=0)

crst

コネクション/セッションに関する統計をすべてリセットします (Connection reset の略?). コネクションを切断するわけではありません.

echo crst | nc localhost 2181
Connection stats reset.

dump

リファレンスには

Lists the outstanding sessions and ephemeral nodes. This only works on the leader.

とあります.試しに zkcli から短命ノード /ephemeral_node を作成して,コマンドを実行してみると……

$ echo dump | nc localhost 2181
SessionTracker dump:
Session Sets (6):
0 expire at Sat Jan 03 04:32:32 GMT 1970:
0 expire at Sat Jan 03 04:32:34 GMT 1970:
0 expire at Sat Jan 03 04:32:42 GMT 1970:
0 expire at Sat Jan 03 04:32:44 GMT 1970:
1 expire at Sat Jan 03 04:32:52 GMT 1970:
    0x1000b42a5440001
1 expire at Sat Jan 03 04:32:54 GMT 1970:
    0x1000b42a5440000
ephemeral nodes dump:
Sessions with Ephemerals (1):
0x1000b42a5440000:
    /ephemeral_node

一見よくわからないものもありますが (← おい),0x1000b42a54400010x1000b42a5440000 は zkcli で接続しているコネクションです. また,ID が 0x1000b42a5440000 のセッションが /ephemeral_node という短命ノードを作成していることが読み取れます.

envi

サーバ環境に関する情報を取得します. Javaシステムプロパティのようなものでしょうか.

$ echo envi | nc localhost 2181
Environment:
zookeeper.version=3.4.11-37e277162d567b55a07d1755f0b31c32e93c01a0, built on 11/01/2017 18:06 GMT
host.name=7de453fdb571
java.version=1.8.0_151
java.vendor=Oracle Corporation
java.home=/usr/lib/jvm/java-1.8-openjdk/jre
java.class.path=/zookeeper-3.4.11/bin/../build/classes:/zookeeper-3.4.11/bin/../build/lib/*.jar:/zookeeper-3.4.11/bin/../lib/slf4j-log4j12-1.6.1.jar:/zookeeper-3.4.11/bin/../lib/slf4j-api-1.6.1.jar:/zookeeper-3.4.11/bin/../lib/netty-3.10.5.Final.jar:/zookeeper-3.4.11/bin/../lib/log4j-1.2.16.jar:/zookeeper-3.4.11/bin/../lib/jline-0.9.94.jar:/zookeeper-3.4.11/bin/../lib/audience-annotations-0.5.0.jar:/zookeeper-3.4.11/bin/../zookeeper-3.4.11.jar:/zookeeper-3.4.11/bin/../src/java/lib/*.jar:/conf:
java.library.path=/usr/lib/jvm/java-1.8-openjdk/jre/lib/amd64/server:/usr/lib/jvm/java-1.8-openjdk/jre/lib/amd64:/usr/lib/jvm/java-1.8-openjdk/jre/../lib/amd64:/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib
java.io.tmpdir=/tmp
java.compiler=<NA>
os.name=Linux
os.arch=amd64
os.version=4.9.87-linuxkit-aufs
user.name=zookeeper
user.home=/home/zookeeper
user.dir=/zookeeper-3.4.11

ruok

ZooKeeper が正常に稼働していれば「imok」と応答します.それ以外は何も返しません.(Are you OK の略)

$ echo ruok | nc localhost 2181
imok

srst

サーバの統計情報をリセットします.(Server reset の略?)

$ echo srst | nc localhost 2181
Server stats reset.

srvr

サーバの全詳細情報を取得します. サーバがリーダーなのかフォロワーなのか,それともスタンドアローンなのかもこれでわかります.

$ echo srvr | nc localhost 2181
Zookeeper version: 3.4.11-37e277162d567b55a07d1755f0b31c32e93c01a0, built on 11/01/2017 18:06 GMT
Latency min/avg/max: 0/0/0
Received: 16
Sent: 16
Connections: 3
Outstanding: 0
Zxid: 0x3
Mode: standalone
Node count: 5

stat

サーバとコネクションに関する情報の要約を出力します.

echo stat | nc localhost 2181
Zookeeper version: 3.4.11-37e277162d567b55a07d1755f0b31c32e93c01a0, built on 11/01/2017 18:06 GMT
Clients:
 /127.0.0.1:58902[1](queued=0,recved=4421,sent=4421)
 /127.0.0.1:58904[1](queued=0,recved=4418,sent=4418)
 /127.0.0.1:40145[0](queued=0,recved=1,sent=0)

Latency min/avg/max: 0/0/10
Received: 89
Sent: 89
Connections: 3
Outstanding: 0
Zxid: 0x3
Mode: standalone
Node count: 5

wchs

設定されている監視の要約を取得します.

echo wchs | nc localhost 2181
1 connections watching 1 paths
Total watches:1

wchc

設定されている監視を,それを設定しているコネクションごとに取得します.

$ echo wchc | nc localhost 2181
0x1000b42a5440000
    /watch

wchp

監視が設定されているパスと,そこを監視しているコネクションを取得します.

$ echo wchp | nc localhost 2181
/watch
    0x1000b42a5440000

mntr

ZooKeeper アンサンブルのヘルスをモニタリングするのに使えそうな値を取得します.

echo mntr | nc localhost 2181
zk_version  3.4.11-37e277162d567b55a07d1755f0b31c32e93c01a0, built on 11/01/2017 18:06 GMT
zk_avg_latency  0
zk_max_latency  10
zk_min_latency  0
zk_packets_received 302
zk_packets_sent 302
zk_num_alive_connections    3
zk_outstanding_requests 0
zk_server_state standalone
zk_znode_count  6
zk_watch_count  1
zk_ephemerals_count 1
zk_approximate_data_size    93
zk_open_file_descriptor_count   29
zk_max_file_descriptor_count    1048576

Java から管理コマンドを呼ぶ

通常クライアントとして使用する クラス ZooKeeper からコマンドを呼ぶことはできないので,ソケットを繋いで取得します.

Socket socket = new Socket("localhost", 2181)
OutputStream out = socket.getOutputStream()
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()))
out.write("ruok".getBytes())
in.readLine() // 正常に稼働中なら "imok" が返る

コマンド用の簡単なクライアントをこちらで実装 (途中) しています: https://github.com/snobutaka/zk-command

おわり

dump など見方がパッと分からないものもありましたが…… ruok, srvr, mntr あたりは ZooKeeper のステータスチェックに利用できそうに感じました.

ZooKeeper 3.5 では Dynamic Reconfiguration という機能も追加されているので,管理コマンドと組み合わせてアンサンブルを動的に運用したり……がうまくできると面白そうです.