著者は、Write for DOnationsプログラムの一部として寄付を受け取るためにWikimedia Foundation Inc.を選択しました。
前書き
Apache ZooKeeperは、復元力と信頼性の高い分散調整を可能にするオープンソースソフトウェアです。 分散システムで一般的に使用され、構成情報、ネームサービス、分散同期、クォーラム、および状態を管理します。 さらに、分散システムは、コンセンサス、リーダー選挙、およびグループ管理を実装するためにZooKeeperに依存しています。
このガイドでは、Ubuntu 18.04にApache ZooKeeper 3.4.13をインストールして構成します。 復元力と高可用性を実現するために、ZooKeeperは、アンサンブルと呼ばれる一連のホストに複製されることを目的としています。 最初に、単一ノードのZooKeeperサーバーのスタンドアロンインストールを作成し、マルチノードクラスターをセットアップするための詳細を追加します。 スタンドアロンインストールは開発環境とテスト環境で役立ちますが、クラスターは実稼働環境で最も実用的なソリューションです。
前提条件
このインストールおよび構成ガイドを開始する前に、次のものが必要です。
-
スタンドアロンインストールには、sudo権限を持つ非rootユーザーとファイアウォールを含め、the Ubuntu 18.04 initial server setup guideに従って設定された最低4GBのRAMを備えた1台のUbuntu18.04サーバーが必要です。 マルチノードクラスタには、同じ手順に従ってセットアップされた2つの追加サーバーが必要です。
-
ZooKeeperの実行にはJavaが必要であるため、サーバーにOpenJDK 8がインストールされています。 これを行うには、How To Install Java with
apt
on Ubuntu 18.04ガイドの「OpenJDKの特定のバージョンをインストールする」手順に従います。
ZooKeeperはデータをメモリに保持して高スループットと低レイテンシを実現するため、実稼働システムは8GBのRAMで最適に動作します。 RAMの量が少ないと、JVMスワッピングが発生し、ZooKeeperサーバーの待ち時間が発生する可能性があります。 ZooKeeperサーバーの遅延が大きいと、クライアントセッションのタイムアウトなどの問題が発生し、システムの機能に悪影響を及ぼす可能性があります。
[[step-1 -—- creating-a-user-for-zookeeper]] ==ステップ1—ZooKeeperのユーザーを作成する
専用ユーザーは、ネットワーク経由でリクエストを処理し、リソースを消費するサービスを実行する必要があります。 このプラクティスにより、環境のセキュリティと管理性を向上させる分離と制御が作成されます。 このステップでは、このチュートリアルでzkという名前の非root sudoユーザーを作成して、ZooKeeperサービスを実行します。
最初に、前提条件で作成した非ルートsudoユーザーとしてログインします。
ssh sammy@your_server_ip
ZooKeeperサービスを実行するユーザーを作成します。
sudo useradd zk -m
-m
フラグをuseradd
コマンドに渡すと、このユーザーのホームディレクトリが作成されます。 zkのホームディレクトリは、デフォルトでは/home/zk
になります。
zkユーザーのデフォルトシェルとしてbash
を設定します。
sudo usermod --shell /bin/bash zk
このユーザーのパスワードを設定します。
sudo passwd zk
次に、zkユーザーをsudoグループに追加して、特権モードでコマンドを実行できるようにします。
usermod -aG sudo zk
セキュリティの観点から、できる限り少ないユーザーにSSHアクセスを許可することをお勧めします。 sammyとしてリモートでログインし、su
を使用して目的のユーザーに切り替えると、システムにアクセスするための資格情報と実行中のプロセスの資格情報が一定レベル分離されます。 この手順では、zkユーザーとrootユーザーの両方のSSHアクセスを無効にします。
sshd_config
ファイルを開きます。
sudo nano /etc/ssh/sshd_config
PermitRootLogin
行を見つけ、値をno
に設定して、rootユーザーのSSHアクセスを無効にします。
/etc/ssh/sshd_config
PermitRootLogin no
PermitRootLogin
値の下に、DenyUsers
行を追加し、SSHアクセスを無効にする必要があるユーザーとして値を設定します。
/etc/ssh/sshd_config
DenyUsers zk
ファイルを保存して終了し、SSHデーモンを再起動して変更を有効にします。
sudo systemctl restart sshd
zkユーザーに切り替えます。
su -l zk
-l
フラグは、ユーザーを切り替えた後にログインシェルを呼び出します。 ログインシェルは環境変数をリセットし、ユーザーにクリーンスタートを提供します。
プロンプトでパスワードを入力して、ユーザーを認証します。
zkユーザーとして作成、構成、およびログインしたので、ZooKeeperデータを格納するためのディレクトリーを作成します。
[[step-2 -—- creating-a-data-directory-for-zookeeper]] ==ステップ2—ZooKeeperのデータディレクトリを作成する
ZooKeeperは、すべての構成および状態データをディスクに保持するため、再起動後も存続できます。 この手順では、ZooKeeperがデータの読み取りと書き込みに使用するデータディレクトリを作成します。 ローカルファイルシステムまたはリモートストレージドライブにデータディレクトリを作成できます。 このチュートリアルでは、ローカルファイルシステムにデータディレクトリを作成することに焦点を当てます。
ZooKeeperが使用するディレクトリを作成します。
sudo mkdir -p /data/zookeeper
zkのユーザー所有権をディレクトリに付与します。
sudo chown zk:zk /data/zookeeper
chown
は、/data/zookeeper
ディレクトリの所有権とグループを変更して、グループzkに属するユーザーzkがデータディレクトリを所有するようにします。
データディレクトリの作成と設定が正常に完了しました。 ZooKeeperの構成に移るとき、ZooKeeperがファイルの保存に使用するデータディレクトリとしてこのパスを指定します。
[[step-3 -—- download-and-extracting-the-zookeeper-binaries]] ==ステップ3—ZooKeeperバイナリのダウンロードと抽出
このステップでは、ZooKeeperバイナリを手動でダウンロードして/opt
ディレクトリに抽出します。 Advanced Packaging Toolapt
を使用してZooKeeperをダウンロードできますが、機能が異なる古いバージョンがインストールされる場合があります。 ZooKeeperを手動でインストールすると、使用するバージョンを完全に制御できます。
これらのファイルを手動でダウンロードしているので、/opt
ディレクトリに移動することから始めます。
cd /opt
ローカルマシンから、Apache download pageに移動します。 このページは、最速のダウンロードのために、あなたに最も近いミラーを自動的に提供します。 提案されたミラーサイトへのリンクをクリックし、下にスクロールしてzookeeper/をクリックし、利用可能なリリースを表示します。 インストールするZooKeeperのバージョンを選択します。 このチュートリアルでは、3.4.13の使用に焦点を当てます。 バージョンを選択したら、.tar.gz
で終わるバイナリファイルを右クリックして、リンクアドレスをコピーします。
サーバーから、コピーされたリンクとともにwget
コマンドを使用して、ZooKeeperバイナリをダウンロードします。
sudo wget http://apache.osuosl.org/zookeeper/zookeeper-3.4.13/zookeeper-3.4.13.tar.gz
圧縮アーカイブからバイナリを抽出します。
sudo tar -xvf zookeeper-3.4.13.tar.gz
.tar.gz
拡張子は、TARパッケージとそれに続くGNU zip(gzip)圧縮の組み合わせを表します。 アーカイブを抽出するコマンドにフラグ-xvf
を渡したことがわかります。 フラグx
は抽出を表し、v
は詳細モードで抽出の進行状況を表示し、f
は入力(この場合はzookeeper-3.4.13.tar.gz
)をSTDINではなく指定できるようにします。
次に、実行可能ファイルを実行できるように、抽出されたバイナリのzkユーザー所有権を付与します。 次のように所有権を変更できます。
sudo chown zk:zk -R zookeeper-3.4.13
次に、シンボリックリンクを構成して、ZooKeeperディレクトリが更新後も関連性を保つようにします。 シンボリックリンクを使用してディレクトリ名を短縮することもできます。これにより、構成ファイルのセットアップにかかる時間を短縮できます。
ln
コマンドを使用してシンボリックリンクを作成します。
sudo ln -s zookeeper-3.4.13 zookeeper
そのリンクの所有権をzk:zk
に変更します。 リンク自体の所有権を変更するために-h
フラグを渡したことに注意してください。 -h
を指定しないと、前の手順で明示的に行ったリンクのターゲットの所有権が変更されます。
sudo chown -h zk:zk zookeeper
シンボリックリンクが作成されると、構成内のディレクトリパスは関連性を維持し、将来のアップグレードを通じて変更されません。 ZooKeeperを構成できるようになりました。
[[step-4 -—- configuring-zookeeper]] ==ステップ4—ZooKeeperの構成
環境を設定したら、ZooKeeperを設定する準備ができました。
構成ファイルは/opt/zookeeper/conf
ディレクトリにあります。 このディレクトリには、ZooKeeperディストリビューションに付属のサンプル構成ファイルが含まれています。 zoo_sample.cfg
という名前のこのサンプルファイルには、最も一般的な構成パラメーター定義とこれらのパラメーターのサンプル値が含まれています。 一般的なパラメータの一部は次のとおりです。
-
tickTime
:ティックの長さをミリ秒単位で設定します。 ティックは、ZooKeeperがハートビート間の長さを測定するために使用する時間単位です。 最小セッションタイムアウトはtickTimeの2倍です。 -
dataDir
:インメモリデータベースのスナップショットと更新のトランザクションログを保存するために使用されるディレクトリを指定します。 トランザクションログ用に別のディレクトリを指定することもできます。 -
clientPort
:クライアント接続をリッスンするために使用されるポート。 -
maxClientCnxns
:クライアント接続の最大数を制限します。
/opt/zookeeper/conf
にzoo.cfg
という名前の構成ファイルを作成します。 nano
またはお気に入りのエディターを使用してファイルを作成して開くことができます。
nano /opt/zookeeper/conf/zoo.cfg
そのファイルに次のプロパティと値のセットを追加します。
/opt/zookeeper/conf/zoo.cfg
tickTime=2000
dataDir=/data/zookeeper
clientPort=2181
maxClientCnxns=60
2000ミリ秒のtickTime
は、ハートビート間の推奨間隔です。 間隔を短くすると、システムのオーバーヘッドにつながり、メリットが制限される可能性があります。 dataDir
パラメータは、前のセクションで作成したシンボリックリンクによって定義されたパスを指します。 従来、ZooKeeperはポート2181
を使用してクライアント接続をリッスンしていました。 ほとんどの場合、60の許可されたクライアント接続で開発とテストに十分です。
ファイルを保存し、エディターを終了します。
ZooKeeperを構成し、サーバーを起動する準備ができました。
[[step-5 -—- starting-zookeeper-and-testing-the-standalone-installation]] ==ステップ5—ZooKeeperを起動してスタンドアロンインストールをテストする
ZooKeeperの実行に必要なすべてのコンポーネントを構成しました。 この手順では、ZooKeeperサービスを開始し、サービスにローカルに接続して構成をテストします。
/opt/zookeeper
ディレクトリに戻ります。
cd /opt/zookeeper
zkServer.sh
コマンドでZooKeeperを起動します。
bin/zkServer.sh start
標準出力に以下が表示されます。
OutputZooKeeper JMX enabled by default
Using config: /opt/zookeeper/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED
次のコマンドを使用して、ローカルのZooKeeperサーバーに接続します。
bin/zkCli.sh -server 127.0.0.1:2181
ラベルCONNECTED
のプロンプトが表示されます。 これにより、ローカルのスタンドアロンZooKeeperが正常にインストールされたことを確認できます。 エラーが発生した場合は、構成が正しいことを確認する必要があります。
OutputConnecting to 127.0.0.1:2181
...
...
[zk: 127.0.0.1:2181(CONNECTED) 0]
このプロンプトでhelp
と入力して、クライアントから実行できるコマンドのリストを取得します。 出力は次のようになります。
Output[zk: 127.0.0.1:2181(CONNECTED) 0] help
ZooKeeper -server host:port cmd args
stat path [watch]
set path data [version]
ls path [watch]
delquota [-n|-b] path
ls2 path [watch]
setAcl path acl
setquota -n|-b val path
history
redo cmdno
printwatches on|off
delete path [version]
sync path
listquota path
rmr path
get path [watch]
create [-s] [-e] path data acl
addauth scheme auth
quit
getAcl path
close
connect host:port
いくつかのテストを行った後、プロンプトでquit
と入力して、クライアントセッションを閉じます。 クライアントセッションを閉じた後、ZooKeeperサービスは引き続き実行されます。 次の手順でsystemd
サービスとして構成するため、ZooKeeperサービスをシャットダウンします。
bin/zkServer.sh stop
これで、スタンドアロンのZooKeeperサービスをインストール、構成、およびテストできました。 この設定は、ZooKeeperに慣れるのに役立ちますが、開発環境およびテスト環境にも役立ちます。 構成が機能することがわかったので、systemd
を構成して、ZooKeeperサービスの管理を簡素化します。
[[step-6 -—- systemd-unit-fileの作成と使用]] ==ステップ6—systemdユニットファイルの作成と使用
systemd
、システムおよびサービスマネージャーは、ユーザースペースをブートストラップし、ブート後にシステムプロセスを管理するために使用されるinitシステムです。 systemd
を使用して、ZooKeeperのステータスを開始および確認するためのデーモンを作成できます。
Systemd Essentialsは、systemd
とその構成要素についてさらに学ぶための優れた入門リソースです。
エディタを使用して、/etc/systemd/system/
にzk.service
という名前の.service
ファイルを作成します。
sudo nano /etc/systemd/system/zk.service
ファイルに次の行を追加して、ZooKeeperサービスを定義します。
/etc/systemd/system/zk.service
[Unit]
Description=Zookeeper Daemon
Documentation=http://zookeeper.apache.org
Requires=network.target
After=network.target
[Service]
Type=forking
WorkingDirectory=/opt/zookeeper
User=zk
Group=zk
ExecStart=/opt/zookeeper/bin/zkServer.sh start /opt/zookeeper/conf/zoo.cfg
ExecStop=/opt/zookeeper/bin/zkServer.sh stop /opt/zookeeper/conf/zoo.cfg
ExecReload=/opt/zookeeper/bin/zkServer.sh restart /opt/zookeeper/conf/zoo.cfg
TimeoutSec=30
Restart=on-failure
[Install]
WantedBy=default.target
ユニットファイル構成のService
セクションは、作業ディレクトリ、サービスを実行するユーザー、およびZooKeeperサービスを開始、停止、および再起動するための実行可能コマンドを指定します。 すべてのユニットファイル構成オプションの詳細については、Understanding Systemd Units and Unit Filesの記事を参照してください。
ファイルを保存し、エディターを終了します。
systemd
構成が整ったので、次のサービスを開始できます。
sudo systemctl start zk
systemd
ファイルでサービスを正常に開始できることを確認したら、起動時にサービスを開始できるようにします。
sudo systemctl enable zk
この出力は、シンボリックリンクの作成を確認します。
OutputCreated symlink /etc/systemd/system/multi-user.target.wants/zk.service → /etc/systemd/system/zk.service.
次を使用して、ZooKeeperサービスのステータスを確認します。
sudo systemctl status zk
systemctl
を使用してZooKeeperサービスを停止します。
sudo systemctl stop zk
最後に、デーモンを再起動するには、次のコマンドを使用します。
sudo systemctl restart zk
systemd
メカニズムは、多くのLinuxディストリビューションで選択されるinitシステムになりつつあります。 ZooKeeperを管理するようにsystemd
を構成したので、この高速で柔軟なinitモデルを利用して、ZooKeeperサービスを開始、停止、および再起動できます。
[[step-7 -—- configuring-a-multi-node-zookeeper-cluster]] ==ステップ7—マルチノードZooKeeperクラスターの構成
スタンドアロンZooKeeperサーバーは開発とテストに役立ちますが、すべての実稼働環境には複製されたマルチノードクラスターが必要です。
アプリケーションとして連携するZooKeeperクラスター内のノードは、quorumを形成します。 クォーラムとは、トランザクションをコミットする前に合意する必要があるノードの最小数を指します。 クォーラムには、過半数を確立できるように奇数のノードが必要です。 ノードの数が偶数の場合、同点になる可能性があります。これは、ノードが過半数またはコンセンサスに達しないことを意味します。
実稼働環境では、各ZooKeeperノードを個別のホストで実行する必要があります。 これにより、ホストのハードウェア障害または再起動によるサービスの中断を防ぎます。 これは、復元力があり、可用性の高い分散システムを構築するための重要で必要なアーキテクチャ上の考慮事項です。
このチュートリアルでは、クォーラムに3つのノードをインストールして構成し、マルチノードセットアップを示します。 3ノードクラスターを構成する前に、スタンドアロンZooKeeperインストールと同じ構成で2つの追加サーバーをスピンアップします。 2つの追加ノードが前提条件を満たしていることを確認してから、手順1〜6を実行して、実行中のZooKeeperインスタンスをセットアップします。
新しいノードの手順1〜6を実行したら、各ノードのエディターでzoo.cfg
を開きます。
sudo nano /opt/zookeeper/conf/zoo.cfg
クォーラムのすべてのノードには、同じ構成ファイルが必要です。 3つのノードのそれぞれのzoo.cfg
ファイルで、ファイルの最後に、クォーラム内のinitLimit
、syncLimit
、およびサーバーの追加の構成パラメーターと値を追加します。
/opt/zookeeper/conf/zoo.cfg
tickTime=2000
dataDir=/data/zookeeper
clientPort=2181
maxClientCnxns=60
initLimit=10
syncLimit=5
server.1=your_zookeeper_node_1:2888:3888
server.2=your_zookeeper_node_2:2888:3888
server.3=your_zookeeper_node_3:2888:3888
initLimit
は、最初の同期フェーズにかかる時間を指定します。 これは、クォーラム内の各ノードがリーダーに接続する必要がある時間です。 syncLimit
は、要求を送信してから確認応答を受信するまでに経過できる時間を指定します。 これは、ノードがリーダーから同期できなくなる最大時間です。 ZooKeeperノードは、フォロワーノードがリーダーノードに接続するため、およびリーダーの選出のために、それぞれポートのペア:2888
と:3888
を使用します。
各ノードでファイルを更新したら、エディターを保存して終了します。
マルチノード構成を完了するには、各サーバーでノードIDを指定します。 これを行うには、各ノードにmyid
ファイルを作成します。 各ファイルには、構成ファイルで割り当てられたサーバー番号に相関する番号が含まれます。
your_zookeeper_node_1で、ノードIDを指定するmyid
ファイルを作成します。
sudo nano /data/zookeeper/myid
your_zookeeper_node_1はserver.1
として識別されるため、1
と入力してノードIDを定義します。 値を追加すると、ファイルは次のようになります。
your_zookeeper_node_1 /data/zookeeper/myid1
残りのノードについても同じ手順に従います。 各ノードのmyid
ファイルは次のようになります。
your_zookeeper_node_1 /data/zookeeper/myid1
your_zookeeper_node_2 /data/zookeeper/myid2
your_zookeeper_node_3 /data/zookeeper/myid3
これで、3ノードのZooKeeperクラスターが構成されました。 次に、クラスターを実行し、インストールをテストします。
[[step-8 -—- running-and-testing-the-multi-node-installation]] ==ステップ8—マルチノードインストールの実行とテスト
各ノードがクラスターとして機能するように構成されたら、クォーラムを開始する準備が整います。 この手順では、各ノードでクォーラムを開始し、ZooKeeperでサンプルデータを作成してクラスターをテストします。
クォーラムノードを開始するには、最初に各ノードの/opt/zookeeper
ディレクトリに移動します。
cd /opt/zookeeper
次のコマンドで各ノードを起動します。
java -cp zookeeper-3.4.13.jar:lib/log4j-1.2.17.jar:lib/slf4j-log4j12-1.7.25.jar:lib/slf4j-api-1.7.25.jar:conf org.apache.zookeeper.server.quorum.QuorumPeerMain conf/zoo.cfg
ノードが起動すると、接続エラーが断続的に表示され、その後、クォーラムに参加してリーダーを選出する段階が続きます。 数秒の初期化の後、インストールのテストを開始できます。
前提条件で構成した非rootユーザーとしてSSH経由でyour_zookeeper_node_3にログインします。
ssh sammy@your_zookeeper_node_3
ログインしたら、zkユーザーに切り替えます。
your_zookeeper_node_3 /data/zookeeper/myidsu -l zk
zkユーザーのパスワードを入力します。 ログインしたら、ディレクトリを/opt/zookeeper
に変更します。
your_zookeeper_node_3 /data/zookeeper/myidcd /opt/zookeeper
ここで、ZooKeeperコマンドラインクライアントを起動し、your_zookeeper_node_1でZooKeeperに接続します。
your_zookeeper_node_3 /data/zookeeper/myidbin/zkCli.sh -server your_zookeeper_node_1:2181
スタンドアロンインストールでは、クライアントとサーバーの両方が同じホストで実行されていました。 これにより、localhost
を使用してZooKeeperサーバーとのクライアント接続を確立できました。 クライアントとサーバーはマルチノードクラスター内の異なるノードで実行されているため、前の手順では、それに接続するためにyour_zookeeper_node_1のIPアドレスを指定する必要がありました。
手順5で見たのと同様に、CONNECTED
ラベルが付いたおなじみのプロンプトが表示されます。
次に、znodeを作成、一覧表示、削除します。 znodeは、ZooKeeperの基本的な抽象概念であり、ファイルシステム上のファイルおよびディレクトリに類似しています。 ZooKeeperはそのデータを階層的な名前空間で管理し、znodeはこの名前空間のデータレジスタです。
znodeを正常に作成、一覧表示、および削除できることをテストすることは、ZooKeeperクラスターが正しくインストールおよび構成されていることを確認するために不可欠です。
zk_znode_1
という名前のznodeを作成し、文字列sample_data
をそれに関連付けます。
create /zk_znode_1 sample_data
作成すると、次の出力が表示されます。
OutputCreated /zk_znode_1
新しく作成されたznodeをリストします。
ls /
関連するデータを取得します。
get /zk_znode_1
ZooKeeperは次のように応答します。
Output[zk: your_zookeeper_node_1:2181(CONNECTED)] ls /
[zk_znode_1, zookeeper]
[zk: your_zookeeper_node_1:2181(CONNECTED)] get /zk_znode_1
sample_data
cZxid = 0x100000002
ctime = Tue Nov 06 19:47:41 UTC 2018
mZxid = 0x100000002
mtime = Tue Nov 06 19:47:41 UTC 2018
pZxid = 0x100000002
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 11
numChildren = 0
出力は、zk_node_1
に関連付けた値sample_data
を確認します。 ZooKeeperは、作成時間ctime
および変更時間mtime
に関する追加情報も提供します。 ZooKeeperはバージョン管理されたデータストアであるため、データバージョンに関するメタデータも表示されます。
zk_znode_1
znodeを削除します。
delete /zk_znode_1
この手順では、2つのZooKeeperノード間の接続を正常にテストしました。 また、znodeを作成、一覧表示、および削除することにより、基本的なznode管理を学びました。 マルチノード設定が完了し、ZooKeeperの使用を開始する準備が整いました。
結論
このチュートリアルでは、スタンドアロン環境とマルチノードZooKeeper環境の両方を構成およびテストしました。 マルチノードのZooKeeperデプロイメントを使用する準備ができたので、追加情報とプロジェクトについてofficial ZooKeeper documentationを確認できます。