本稼働での ZooKeeper の実行¶
Apache Kafka® は、ZooKeeper を使用して永続的なクラスターメタデータを保存する、Confluent Platform デプロイの非常に重要なコンポーネントです。たとえば、ZooKeeper 内の Kafka データ が失われると、Broker へのレプリカのマッピングとトピック構成も失われるため、Kafka クラスターが機能しなくなり、すべてのデータが失われることになります。
このドキュメントは、ZooKeeper クラスターをライブにする前の主要な考慮事項を説明していますが、本稼働環境で ZooKeeper を実行するための完全なガイドではありません。詳細については、『 ZooKeeper Administrator's Guide 』を参照してください。
サポートされるバージョン¶
Confluent Platform では、安定したバージョンの ZooKeeper が出荷されています。ENVI の「4 文字の単語」を使用して、nc
で実行中のサーバーの現在のバージョンを見つけることができます。その例を次に示します。
echo envi | nc localhost 2181
これで、バージョンなど、ZooKeeper サーバーのすべての環境情報が表示されます。
注釈
ZooKeeper 起動スクリプトと ZooKeeper の機能は、このバージョンの ZooKeeper でのみテストされています。
ハードウェア¶
本稼働の ZooKeeper クラスターは、さまざまな使用事例に対応できます。推奨事項は、ZooKeeper サーバーのクラスターに適切なハードウェアを選択するための一般的なガイドラインとして示されています。このドキュメントですべての事例を説明することはできませんので、最終決定を下す際は、実際の使用事例とビジネス要件を考慮してください。
メモリ¶
一般的に ZooKeeper は、Kafka で保存されているデータのみを処理しているときには、メモリ負荷の高いアプリケーションではありません。ZooKeeper サーバーに必要な物理的メモリは、アンサンブルで保存されている znode のサイズに応じて異なります。これは、どの時点でも、各 ZooKeeper がすべての znode コンテンツをメモリに保持しているためです。Kafka の場合、znode 作成でメモリ使用量が増える主な要因は、クラスター内のパーティションの数です。一般的な本稼働の事例では、ZooKeeper 専用の RAM が 4 GB 以上、必要です。ZooKeeper はスワッピングの影響を受けやすいため、ZooKeeper サーバーを実行しているホストでは、スワッピングを避けるようにしてください。
CPU¶
一般的には、Kafka メタデータストアとしての ZooKeeper が、大量の CPU リソースを消費することはありません。ただし、ZooKeeper を共有しているか、ZooKeeper サーバーを実行しているホストを共有している場合は、CPU を考慮する必要があります。ZooKeeper には、レイテンシに敏感な機能があるため、同時に CPU を使用する他のプロセスがある場合や、ZooKeeper アンサンブルを複数の用途に使用している場合は、コンテキストスイッチが問題にならないように、専用の CPU コアを用意することを検討してください。
ディスク¶
ディスクのパフォーマンスは、健全な ZooKeeper クラスターを維持するために、極めて重要です。最適なパフォーマンスを得るために、ZooKeeper には、低レイテンシのディスク書き込みが必要であるため、ソリッドステートドライブ(SSD)を強くお勧めします。ZooKeeper の各要求は、クォーラム内の各サーバー上のディスクにコミットされる必要があり、その後にその結果を読み取ることができます。本稼働デプロイには、64 GB 以上のサイズの専用 SSD を各 ZooKeeper サーバーに用意することをお勧めします。autopurge.purgeInterval
および autopurge.snapRetainCount
を使用すると、ZooKeeper データの自動クリーンアップを行い、メンテナンスのオーバーヘッドを削減することができます。
JVM¶
ZooKeeper は JVM として動作します。Kafka の使用事例での動作時には、特に大量のヒープを使用するわけではありません。ほとんどの事例、およびヒープ使用状況のモニタリングには、ガベージコレクションによる遅延が発生しないようにするために、1 GB のヒープサイズをお勧めします。
構成オプション¶
ZooKeeper の構成プロパティファイルは /etc/kafka/zookeeper.properties
にあります。
ほとんどのデプロイでは、ZooKeeper の構成を調整する必要はありません。ここでは、考慮する必要のある重要なパラメータをいくつか説明します。すべての構成パラメータのリストについては、ZooKeeper プロジェクトページ をご覧ください。
clientPort
ZooKeeper クライアントがリッスンするポートです。Broker はこのポートを使用して ZooKeeper に接続します。通常は 2181 に設定されます。
- 型:int
- 重要度:必須
dataDir
ZooKeeper インメモリデータベースのスナップショットが配置されるディレクトリ。
dataLogDir
で指定していない場合は、このデータベースへの更新のトランザクションログも、ここに配置されます。この場所は、専用のディスク(SSD が望ましい)である必要があります。詳細については、『 ZooKeeper Administrator's Guide 』を参照してください。- 型: string
- 重要度:必須
dataLogDir
トランザクションログが書き込まれる場所。このオプションを指定しない場合は、dataDir にログが書き込まれます。このオプションを指定すると、専用ログデバイスを使用し、ログとスナップショットの競合を発生しにくくすることができます。詳細については、『 ZooKeeper Administrator's Guide 』を参照してください。
- 型: string
- 重要度:任意
tickTime
ZooKeeper の時間の単位です。ミリ秒で表されます。時間に依存する ZooKeeper 処理はすべて、この単位に基づきます。特に、ハートビートおよびタイムアウトに使用されます。最小セッションタイムアウトは 2 tick になります。
- 型:int
- デフォルト:3000
- 重要度: 高
maxClientCnxns
1 台の ZooKeeper サーバーに許容される最大クライアント接続数。許容される接続数が不足しないようにするには、0(無制限)に設定します。
- 型:int
- デフォルト:60
- 重要度: 高
autopurge.snapRetainCount
有効にすると、ZooKeeper の自動パージ機能により、autopurge.snapRetainCount の最新のスナップショットと、dataDir および dataLogDir 内の対応する各トランザクションログが保持され、それ以外は削除されます。
- 型:int
- デフォルト:3
- 重要度: 高
autopurge.purgeInterval
パージタスクがトリガーされる時間の間隔(単位:時間)。正の整数(1 以上)を設定すると、自動パージが有効になります。
- 型:int
- デフォルト:0
- 重要度: 高
モニタリング¶
ZooKeeper サーバーは、正常に機能していることを確認し、問題を事前に特定するために監視する必要があります。このセクションでは、一般的なモニタリングのベストプラクティスについて説明します。
オペレーティングシステム¶
基盤となる OS メトリクスは、ZooKeeper サービスに問題が発生する時期を予測するために役立ちます。特に、以下を監視する必要があります。
- 開いているファイルハンドルの数 -- これは、システム全体にわたり、ZooKeeper プロセスを実行しているユーザーについて監視する必要があります。開いているファイルハンドルの許容される最大数と照合して、値を検討してください。ZooKeeper では、頻繁に接続の開始と終了が発生するため、複数のファイルハンドルから選択できるようにしておく必要があります。
- ネットワーク帯域幅の使用率 -- ZooKeeper では状態がトラッキングされているため、ネットワークレイテンシによるタイムアウトが発生しやすくなっています。ネットワーク帯域幅が使い果たされると、原因不明のタイムアウトがクライアントセッションで発生する場合があり、Kafka クラスターの信頼性が低下します。
「4 文字の単語」¶
ZooKeeper は、それぞれが 4 文字の長さの特定のコマンドに応答します。各コマンドの説明と、それが使用可能になったバージョンについては、この ドキュメント をご覧ください。コマンドを実行するには、ZooKeeper クライアントポートにメッセージを(netcat
または telnet
経由で)送信する必要があります。たとえば、echo stat | nc localhost 2181
を実行すると、stdout への STAT
コマンドの出力が返されます。
4 文字の単語、STAT
および MNTR
を監視します。環境ごとに状況は異なりますが、STAT と MNTR で報告されるすべてのメトリクスの急増や急減を監視してください。これらのコマンドで報告されるメトリクスは通常は変動しません(送受信パケット数は時間の経過に従ってゆっくりと増加します)。
JMX モニタリング¶
Confluent Control Center は、 ここ に示すように、Broker から ZooKeeper への接続を監視します。
ZooKeeper サーバーは、数多くの JMX メトリクスも提供しており、それらについては、こちら のプロジェクトドキュメントで説明しています。
以下の JMX メトリクスのモニタリングは重要です。
- NumAliveConnections -
maxClientCnxns
で設定された最大値に近づかないようにします。 - OutstandingRequests - 通常は 10 未満です。
- AvgRequestLatency - 10 ms 未満を目標にします。
- HeapMemoryUsage(Java 組み込み)- 通常は比較的変動が少なく、最大ヒープサイズより大幅に少なくなります。
ZooKeeper が提供する JMX メトリクスに加え、Kafka では、多くの関連 ZooKeeper イベントを SessionExpireListener
を介してトラッキングします。このメトリクスを監視して、ZooKeeper と Kafka の通信の正常性を確保する必要があります。メトリクスの詳細については、「ZooKeeper のメトリクス」を参照してください。
- ZooKeeperAuthFailuresPerSec(セキュアな環境のみ)
- ZooKeeperDisconnectsPerSec
- ZooKeeperExpiresPerSec
- ZooKeeperReadOnlyConnectsPerSec
- ZooKeeperSaslAuthenticationsPerSec(セキュアな環境のみ)
- ZooKeeperSyncConnectsPerSec
- SessionState
マルチノードセットアップ¶
本稼働環境では、ZooKeeper サーバーが複数のノードにデプロイされます。これはアンサンブルと呼ばれます。アンサンブルとは、2n + 1
台の ZooKeeper サーバーのセットです。ここで、n
は、0 より大きい任意の数です。サーバーが奇数台の場合は、ZooKeeper が多数決でリーダーを選ぶことができます。どの時点においても、アンサンブル内の最大 n
台のサーバーに障害が発生する場合がありますが、ZooKeeper クラスターでは クォーラム
(定足数)が保持されます。どの時点でも、クォーラム
が失われた場合は、ZooKeeper クラスターがダウンします。以下に、マルチノード ZooKeeper アンサンブルの一般的な考慮事項をいくつか示します。
- 最初は、3 台または 5 台のサーバーの小規模なアンサンブルを使用し、実際に(または、 フォールトトレランスのために)必要になった数だけ、サーバーを増やすようにします。各書き込みは、アンサンブル内の
クォーラム
のサーバーに伝播される必要があります。つまり、サーバーが 3 台のアンサンブルを実行する場合は、1 台のサーバーの損失に耐えることができます。各書き込みは、コミットされる前に、2 台のサーバーに伝播される必要があります。サーバーが 5 台のアンサンブルの場合は、2 台のサーバーの損失に耐えることができますが、各書き込みは、コミットされる前に、3 台のサーバーに伝播される必要があります。 - 物理/ハードウェア/ネットワークレイアウトでの冗長性:これらすべてを、同じラックに配置しないようにします。ある程度以上のグレードのハードウェアを使用し、余裕のある電力やネットワークパスを保持します。
- 仮想化:複数のアベイラビリティゾーンにサーバーを配置して、相関クラッシュを回避し、ZooKeeper のトランザクションログとスナップショットの作成要件に対応できるストレージシステムを確保できるようにします。
- 確実でない場合は、単純にします。ZooKeeper には、重要なデータが保管されているため、新規デプロイモデルを本稼働で試すより、安定性と耐久性を優先してください。
マルチノードセットアップでは、追加の構成がいくつか必要です。これらについての包括的な概要は、プロジェクトドキュメント に記載されています。以下に、始める際に役立つ具体的な構成例を示します。
tickTime=2000
dataDir=/var/lib/zookeeper/
clientPort=2181
initLimit=5
syncLimit=2
server.1=zoo1:2888:3888
server.2=zoo2:2888:3888
server.3=zoo3:2888:3888
autopurge.snapRetainCount=3
autopurge.purgeInterval=24
これは、3 ノードのアンサンブルの例です。この構成ファイルは、アンサンブルのすべてのメンバーで同じであると想定されています。内容を見ると、tickTime
、dataDir
、および clientPort
がすべて、1 台のサーバー向けの一般的な値に設定されています。initLimit
および syncLimit
を使用して、リーダー以外の ZooKeeper サーバーが、現在のリーダーで初期化されるのにかかる時間と、リーダーと非同期になっている時間が決定されます。この構成では、リーダー以外のサーバーの初期化に 10000ms かかり、2000ms に設定された tickTime
に基づいて最大 4000ms、非同期である場合があります。
server.*
プロパティで、アンサンブルのメンバーシップが設定されます。その形式は server.<myid>=<hostname> :<leaderport>:<electionport>
です。簡単に説明します。
myid
はサーバー識別番号です。この例では、サーバーが 3 台であるため、各サーバーには、1
、2
、および3
の値を持つ異なるmyid
が付けられています。myid
は、人間が判読可能な ASCII テキストで 1 つの整数を記述したmyid
という名前のファイルをdataDir
に作成することにより設定されます。この整数値は、構成ファイルのmyid
値のいずれかに一致する必要があります。競合するmyid
値を持つ別のアンサンブルメンバーがすでに起動している場合は、起動時にエラーがスローされます。leaderport
は、リーダー以外のメンバー(フォロワー)が、アクティブなリーダーに接続するために使用します。このポートは、すべての ZooKeeper アンサンブルメンバー間で開かれている必要があります。electionport
は、アンサンブルメンバー間でリーダーを選ぶために使用されます。このポートは、すべての ZooKeeper アンサンブルメンバー間で開かれている必要があります。
autopurge.snapRetainCount
および autopurge.purgeInterval
は、24 時間ごとに 3 つのスナップショット以外をすべてパージするよう設定されています。
デプロイ後¶
ZooKeeper クラスターのデプロイ後、ZooKeeper は、わずかなメンテナンスのみで問題なく動作します。プロジェクトドキュメント には、dataDir
のクリーンアップの管理、ロギング、トラブルシューティングなどの処理に関する有用なヒントが数多く記載されています。
注釈
2021 年に Kafka は、ZooKeeper の使用に代わって、自社製の組み込みコンセンサスレイヤを採用します。詳細については、「Preparing Your Clients and Tools for KIP-500: ZooKeeper Removal from Apache Kafka」をご覧ください。
おすすめのリソース¶
- ポッドキャスト: The Truth About ZooKeeper Removal and the KIP-500 Release in Apache Kafka, featuring Jason Gustafson and Colin McCabe
- ZooKeeper に関するブログの投稿記事
- KIP-500: Apache Kafka Without ZooKeeper(ビデオトーク)
- KIP-500: Apache Kafka Without ZooKeeper(ポッドキャスト)
- Kafka Needs No ZooKeeper (video talk from Kafka Summit 2019)