ZooKeeperアンサンブル設定

SolrにはApache ZooKeeperがバンドルされていますが、本番環境では外部ZooKeeperの設定を使用することを強くお勧めします。

Solrの組み込みZooKeeperインスタンスの使用は、開始するには問題ありませんが、フェイルオーバーを提供しないため、本番環境では使用しないでください。ZooKeeperをホストするSolrインスタンスがシャットダウンすると、ZooKeeperもシャットダウンします。それに依存するシャードやSolrインスタンスは、ZooKeeperと通信できなくなります。

この問題の解決策は、外部ZooKeeper *アンサンブル* を設定することです。これは、クラスタのアクティビティを調整するために互いに通信する複数のZooKeeperを実行しているサーバーです。

ZooKeeperノードの数

最初に回答する必要がある質問は、アンサンブルで実行するZooKeeperノードの数です。

設定するZooKeeperノードの数を計画する際には、ZooKeeperアンサンブルの主な原則は、リクエストに応答するサーバーの過半数を維持することであることに注意してください。この過半数は*クォーラム*と呼ばれます。

「ZooKeeperサービスをアクティブにするには、互いに通信できる障害のないマシンの過半数が必要です。**F台のマシンの障害に耐える展開を作成するには、2xF+1台のマシンの展開を計画する必要があります。**」

— ZooKeeper管理者ガイド
https://zookeeper.dokyumento.jp/doc/r3.9.1/zookeeperAdmin.html

クォーラムを適切に維持するには、アンサンブル内のZooKeeperサーバーの数を奇数にすることを強くお勧めします。そうすることで、過半数が維持されます。

その理由を説明するために、次のシナリオを考えてみましょう。2つのZooKeeperノードがあり、1つがダウンした場合、使用可能なサーバーの50%しか使用できません。これは過半数ではないため、ZooKeeperはリクエストに応答しなくなります。

ただし、3つのZooKeeperノードがあり、1つがダウンした場合、サーバーの66%が使用可能になり、ZooKeeperはダウンしたノードを修復している間も正常に動作します。5つのノードがある場合、必要に応じて2つのノードがダウンしていても動作を続けることができます。

一般的に、5つのノードを超えることはお勧めしません。より多くのノードは、より高いフォールトトレランスと可用性を提供するように見えるかもしれませんが、実際には、発生するノード間の調整の量のために、効率が低下します。本当に大規模なSolrクラスタ(数千ノード規模)でない限り、一般的なルールとして3つ、またはクラスタが大きい場合は5つにとどめるようにしてください。

ZooKeeperクラスタの詳細については、ZooKeeperのドキュメントhttps://zookeeper.dokyumento.jp/doc/r3.9.1/zookeeperAdmin.html#sc_zkMulitServerSetupを参照してください。

Apache ZooKeeperのダウンロード

Apache ZooKeeperの設定の最初のステップは、もちろんソフトウェアをダウンロードすることです。https://zookeeper.dokyumento.jp/releases.htmlから入手できます。

Solrは現在、Apache ZooKeeper v3.9.1を使用しています。

外部ZooKeeperアンサンブルを使用する場合は、Solrと共に配布される最新バージョンにローカルインストールを最新の状態に保つ必要があります。このシナリオではスタンドアロンアプリケーションであるため、標準的なSolrアップグレードの一部としてアップグレードされません。

ZooKeeperのインストール

インストールは、ZooKeeperが内部データを保存する特定のターゲットディレクトリにファイルを抽出することからなります。実際のディレクトリ自体は、場所がわかっていれば問題ありません。

ZooKeeperパッケージを解凍するコマンドは次のとおりです。

tar xvf zookeeper-3.9.1.tar.gz

この場所は、このサーバー上のZooKeeperの<ZOOKEEPER_HOME>です。

ZooKeeperのインストールと解凍は、ZooKeeperが実行される各サーバーで繰り返す必要があります。

ZooKeeperアンサンブルの構成

インストール後、まずZooKeeperの基本的な構成、次に各ノードをアンサンブルの一部として構成するための特定のパラメーターを見ていきます。

初期構成

ZooKeeperインスタンスを構成するには、<ZOOKEEPER_HOME>/conf/zoo.cfgという名前のファイルを作成します。サンプル構成ファイルは、ZooKeeperインストールにconf/zoo_sample.cfgとして含まれています。必要に応じて、新規に作成する代わりに、そのファイルを編集して名前を変更できます。

開始するには、ファイルに次の情報を含める必要があります。

tickTime=2000
dataDir=/var/lib/zookeeper
clientPort=2181
4lw.commands.whitelist=mntr,conf,ruok

パラメーターは次のとおりです。

tickTime

必須

デフォルト:なし

ZooKeeperの機能の一部として、いつでもどのサーバーが稼働しているかを判断することがあり、最小セッションタイムアウトは2つの「ティック」として定義されます。tickTimeパラメーターは、各ティックの長さをミリ秒単位で指定します。

dataDir

必須

デフォルト:なし

これは、ZooKeeperがクラスタに関するデータを保存するディレクトリです。このディレクトリは、ZooKeeperを初めて起動する前に空である必要があります。

clientPort

必須

デフォルト:なし

これは、SolrがZooKeeperにアクセスするポートです。

4lw.commands.whitelist

オプション

デフォルト:なし

これにより、Solr管理UIがZooKeeperにクエリを実行できます。「4文字の単語」をすべて有効にするには、オプションで*を使用します。リストされている3つ(mntrconfruok)は、管理UIを有効にします。

これらは、各ZooKeeperノードで使用される必要がある基本的なパラメーターであるため、このファイルを各ノードにコピーするか、各ノードで作成する必要があります。

次に、この構成をアンサンブル内で動作するようにカスタマイズします。

アンサンブル構成

アンサンブルの構成を完了するには、各ノードがアンサンブル内の自分の位置と他のすべてのノードの位置を認識できるように、追加のパラメーターを設定する必要があります。

以下の各例では、異なるホスト名を持つ異なるサーバーにZooKeeperをインストールしていると仮定しています。

完了すると、zoo.cfgファイルは次のようになります。

tickTime=2000
dataDir=/var/lib/zookeeper
clientPort=2181
4lw.commands.whitelist=mntr,conf,ruok

initLimit=5
syncLimit=2
server.1=zoo1:2888:3888
server.2=zoo2:2888:3888
server.3=zoo3:2888:3888

autopurge.snapRetainCount=3
autopurge.purgeInterval=1

すでに存在していた3つのパラメーターに、これらのパラメーターを追加しました。

initLimit

必須

デフォルト:なし

フォロワーがリーダーに接続して同期するために許可される時間(ティック単位)。この場合、5ティックあり、それぞれ2000ミリ秒の長さであるため、サーバーはリーダーに接続して同期するために最大10秒待機します。

syncLimit

必須

デフォルト:なし

フォロワーがZooKeeperと同期するために許可される時間(ティック単位)。フォロワーがリーダーから遅れすぎると、削除されます。

server.X

必須

デフォルト:なし

これらは、アンサンブル内のすべてのサーバーのサーバーID(X部分)、ホスト名(またはIPアドレス)、ポートです。IDはアンサンブルの各ノードを区別し、各ノードが他の各ノードの場所を認識できるようにします。ポートは任意のポートを選択できます。ZooKeeperのデフォルトポートは2888:3888です。

サーバーIDを特定のホスト/ポートに割り当てているため、このノードがリスト内のどのサーバーであるかも定義する必要があります。これは、dataDirパラメーターで定義されたデータディレクトリに格納されているmyidファイルを使用して行います。myidファイルの内容はサーバーIDのみです。

上記の構成例の場合、この例のように、内容が「1」(引用符なし)の/var/lib/zookeeper/1/myidファイルを作成します。

1
autopurge.snapRetainCount

オプション

デフォルト:3

古いスナップショットとトランザクションログをパージする際に保持するスナップショットと対応するトランザクションログの数。

ZooKeeperは自動的にトランザクションログを保持し、変更が行われるとそれに書き込みます。現在の状態のスナップショットは定期的に作成され、このスナップショットはスナップショットよりも古いトランザクションログに取って代わります。ただし、ZooKeeperは古いスナップショットと古いトランザクションログのいずれもクリーンアップしないため、時間の経過とともに、各サーバーで使用可能なディスク容量を徐々に埋めていきます。

これを回避するには、autopurge.snapRetainCountパラメーターとautopurge.purgeIntervalパラメーターを設定して、定期的に自動クリーンアップ(パージ)を実行できるようにします。autopurge.snapRetainCountパラメーターは、クリーンアップが発生したときに、定義された数のスナップショットとトランザクションログを保持します。このパラメーターは3より大きく設定できますが、3より小さく設定することはできません。

autopurge.purgeInterval

オプション

デフォルト:0

パージタスク間の時間(時間単位)。このパラメーターのデフォルトは0であるため、スナップショットとトランザクションログの自動クリーンアップを有効にするには1以上に設定する必要があります。1日に1回にする場合は、24のように高く設定しても問題ありません。

この構成を各ノードで繰り返します。

2番目のノードでは、<ZOOKEEPER_HOME>/conf/zoo.cfgファイルを更新して、ノード1の内容と一致させます(特にサーバーのホストとポート)。

tickTime=2000
dataDir=/var/lib/zookeeper
clientPort=2181
4lw.commands.whitelist=mntr,conf,ruok

initLimit=5
syncLimit=2
server.1=zoo1:2888:3888
server.2=zoo2:2888:3888
server.3=zoo3:2888:3888

autopurge.snapRetainCount=3
autopurge.purgeInterval=1

2番目のノードでは、内容が「2」のmyidファイルを作成し、/var/lib/zookeeperディレクトリに配置します。

2

3番目のノードでは、<ZOOKEEPER_HOME>/conf/zoo.cfgファイルを更新して、ノード1とノード2の内容と一致させます(特にサーバーのホストとポート)。

tickTime=2000
dataDir=/var/lib/zookeeper
clientPort=2181
4lw.commands.whitelist=mntr,conf,ruok

initLimit=5
syncLimit=2
server.1=zoo1:2888:3888
server.2=zoo2:2888:3888
server.3=zoo3:2888:3888

autopurge.snapRetainCount=3
autopurge.purgeInterval=1

そして、/var/lib/zookeeperディレクトリにmyidファイルを作成します。

3

5ノードのアンサンブルを作成する場合(まれなケース)、サーバー4と5についてもこれを繰り返します。

ZooKeeper環境構成

後でアンサンブルに問題が発生した場合のトラブルシューティングを容易にするために、ロギングを有効にして適切なJVMガベージコレクション(GC)設定でZooKeeperを実行することをお勧めします。

  1. zookeeper-env.shという名前のファイルを作成し、<ZOOKEEPER_HOME>/confディレクトリ(zoo.cfgを配置したのと同じ場所)に配置します。このファイルは、アンサンブルの各サーバーに存在する必要があります。

  2. ファイルに次の設定を追加します。

    ZOO_LOG_DIR="/path/for/log/files"
    ZOO_LOG4J_PROP="INFO,ROLLINGFILE"
    
    SERVER_JVMFLAGS="-Xms2048m -Xmx2048m -verbose:gc -XX:+PrintHeapAtGC -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -XX:+PrintTenuringDistribution -XX:+PrintGCApplicationStoppedTime -Xloggc:$ZOO_LOG_DIR/zookeeper_gc.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=9 -XX:GCLogFileSize=20M"

    プロパティZOO_LOG_DIRは、ZooKeeperがログを出力するサーバー上の場所を定義します。ZOO_LOG4J_PROPは、ログレベルとログアペンダーを設定します。

    SERVER_JVMFLAGSを使用して、ガベージコレクションとGC関連イベントのログ記録に関するいくつかのパラメーターを定義しました。システムパラメーターの1つは-Xloggc:$ZOO_LOG_DIR/zookeeper_gc.logであり、これにより、ZooKeeperログ用に定義したのと同じディレクトリに、zookeeper_gc.logという名前のファイルにガベージコレクションログが配置されます。

  3. <ZOOKEEPER_HOME>/conf/log4j.propertiesのデフォルト設定、特にlog4j.appender.ROLLINGFILE.MaxFileSizeパラメーターを確認します。これは、ログファイルがロールオーバーされるサイズを設定し、デフォルトは10MBです。

  4. zookeeper-env.shlog4j.propertiesへの変更をアンサンブル内の各サーバーにコピーします。

上記の指示はLinuxサーバーのみを対象としています。デフォルトのzkServer.shスクリプトにはzookeeper-env.shファイルのサポートが含まれていますが、スクリプトのWindowsバージョンであるzkServer.cmdには含まれていません。Windowsサーバーで同じ構成を行うには、zkServer.cmdで直接変更する必要があります。

これで、ZooKeeperアンサンブルを開始する準備ができました。

ZooKeeperの詳細情報

ZooKeeperは、追加の構成を通じて多くの機能を提供しますが、それらに詳しく説明することはSolrのドキュメントの範囲外です。詳細については、ZooKeeperドキュメントを参照してください。

ZooKeeperの開始と停止

ZooKeeperの開始

アンサンブルを開始するには、このコマンドのように、<ZOOKEEPER_HOME>/bin/zkServer.shまたはzkServer.cmdスクリプトを使用します。

Linux OS
zkServer.sh start
Windows OS
zkServer.cmd start

このコマンドは、ZooKeeperを実行する各サーバーで実行する必要があります。

ZooKeeperログは、ログの保存先として定義したディレクトリに表示されます。ただし、起動直後は、ガベージコレクションが初めて発生するまではzookeeper_gc.logが表示されない可能性があります。

ZooKeeperのシャットダウン

ZooKeeperをシャットダウンするには、「stop」コマンドを使用して、各サーバーで同じzkServer.shまたはzkServer.cmdスクリプトを使用します。

Linux OS
zkServer.sh stop
Windows OS
zkServer.cmd stop

Solrの構成

Solrを起動する際には、ZooKeeperのアドレスを指定する必要があります。そうでないと、SolrはZooKeeperの使用方法がわかりません。これは、Solrクラスタの各ノードで起動時にZooKeeperが実行されているサーバーのリストである接続文字列を定義するか、Solrのインクルードファイルを永続的なシステムパラメーターとして編集することの2つの方法で行うことができます。どちらの方法についても以下に説明します。

Solr内でZooKeeperの場所を参照する際には、アンサンブル内のすべてのサーバーのアドレスを使用することをお勧めします。1つがダウンした場合でも、Solrは自動的に要求をリスト内の別のサーバーに送信できます。

ZooKeeperバージョン3.5以降は、サーバーアドレスとロールの動的な再構成をサポートしています。ただし、Solrは静的なZooKeeper接続文字列にリストされているサーバーのみに接続できます。

chrootの使用

アンサンブルがSolr以外の他のシステムで共有されている場合、または共有される予定の場合、アプリケーション固有のznode、つまりSolrのファイルのみを含む階層的な名前空間を定義することを検討する必要があります。

各アプリケーションのznodeを作成したら、chrootとも呼ばれるその名前を、SolrにZooKeeperへのアクセス先を指示するたびに接続文字列の最後に追加します。

chrootの作成は、bin/solrコマンドを使用して行います。

bin/solr zk mkroot /solr -z zk1:2181,zk2:2181,zk3:2181

このコマンドの例については、znodeの作成セクションを参照してください。

znodeが作成されると、ファイルシステム上のディレクトリと同様に動作します。ZooKeeperにSolrによって保存されるデータは、メインデータディレクトリのネストされた下にあり、同じZooKeeperアンサンブルを使用する他のシステムまたはプロセスからのデータと混在することはありません。

あるいは、Solrは最初のSolrインスタンスの起動時にznodeを自動的に作成できます。例については、以下を参照してください。

bin/solrでの-zパラメーターの使用

作成したZooKeeperアンサンブルをSolrにポイントするには、bin/solrスクリプトを使用するときに-zパラメーターを使用するだけです。

たとえば、3つのサーバーでポート2181で開始したZooKeeperにSolrインスタンスをポイントし、chroot /solr(上記chrootの使用を参照)を使用する場合は、次の手順を実行する必要があります。

bin/solr start -e cloud -z zk1:2181,zk2:2181,zk3:2181/solr

znodeが存在しない場合は、ZK_CREATE_CHROOT環境変数をtrueに設定して、起動時に自動的に作成できます。

ZK_CREATE_CHROOT=true bin/solr start -e cloud -z zk1:2181,zk2:2181,zk3:2181/solr

Solrインクルードファイルの更新

Solrのインクルードファイル(solr.in.shまたはsolr.in.cmd)を更新して、bin/solrで使用されるデフォルト値を上書きした場合、bin/solrコマンドで-zパラメータを使用する必要はなくなります。

Linux: solr.in.sh

変更するセクションはコメントアウトされています。

# Set the ZooKeeper connection string if using an external ZooKeeper ensemble
# e.g. host1:2181,host2:2181/chroot
# Leave empty if not using SolrCloud
#ZK_HOST=""

行の先頭のコメントマークを削除し、ZooKeeper接続文字列を入力してください。

# Set the ZooKeeper connection string if using an external ZooKeeper ensemble
# e.g. host1:2181,host2:2181/chroot
# Leave empty if not using SolrCloud
ZK_HOST="zk1:2181,zk2:2181,zk3:2181/solr"

Windows: solr.in.cmd

変更するセクションはコメントアウトされています。

REM Set the ZooKeeper connection string if using an external ZooKeeper ensemble
REM e.g. host1:2181,host2:2181/chroot
REM Leave empty if not using SolrCloud
REM set ZK_HOST=

行の先頭のコメントマークを削除し、ZooKeeper接続文字列を入力してください。

REM Set the ZooKeeper connection string if using an external ZooKeeper ensemble
REM e.g. host1:2181,host2:2181/chroot
REM Leave empty if not using SolrCloud
set ZK_HOST=zk1:2181,zk2:2181,zk3:2181/solr

これで、Solr起動時に接続文字列を入力する必要がなくなります。

ファイルサイズ制限の増加

ZooKeeperは、キロバイト単位の小さなファイルを保持するように設計されています。デフォルトでは、ZooKeeperのファイルサイズ制限は1MBです。これより大きなファイルの書き込みまたは読み込みを試行すると、エラーが発生します。

テキスト分析の同義語、LTR、OpenNLP名前エンティティ認識など、一部のSolr機能では、デフォルトの制限を超える可能性のある構成リソースが必要です。ZooKeeperは、Javaシステムプロパティjute.maxbufferを使用して、この制限を増やすように構成できます。この構成は、ZooKeeperサーバーとサーバーに接続するすべてのクライアントの両方で必要であり、指定されているすべての場所で同じである必要があることに注意してください。

ZooKeeperノードでのjute.maxbufferの構成

jute.maxbufferは、各外部ZooKeeperノードで構成する必要があります。これは、以下のいずれかの方法で実現できますが、最初の方法のみがWindowsで機能することに注意してください。

  1. <ZOOKEEPER_HOME>/conf/zoo.cfgで、たとえば、ファイルサイズ制限を10MB未満の1バイトに増やすには、次の行を追加します。

    jute.maxbuffer=0x9fffff
  2. <ZOOKEEPER_HOME>/conf/zookeeper-env.shで、たとえば、ファイルサイズ制限を50MiBに増やすには、次の行を追加します。

    JVMFLAGS="$JVMFLAGS -Djute.maxbuffer=50000000"
  3. <ZOOKEEPER_HOME>/bin/zkServer.shで、スクリプトの先頭にJVMFLAGS環境変数の割り当てを追加します。たとえば、ファイルサイズ制限を5MiBに増やすには、次のようになります。

    JVMFLAGS="$JVMFLAGS -Djute.maxbuffer=5000000"

ZooKeeperクライアントのjute.maxbufferの構成

bin/solrスクリプトは、ZooKeeperクライアントとして機能するJavaプログラムを呼び出します。外部ZooKeeperアンサンブルを設定する代わりに、SolrにバンドルされたZooKeeperサーバーを使用する場合、下記の構成によってZooKeeperサーバーも構成されます。

Solrのインクルードファイル(bin/solr.in.shまたはsolr.in.cmd)のSOLR_OPTS環境変数に設定を追加します。

Linux: solr.in.sh

変更するセクションはここから始まります。

# Anything you add to the SOLR_OPTS variable will be included in the java
# start command line as-is, in ADDITION to other options. If you specify the
# -a option on start script, those options will be appended as well. Examples:

ファイルサイズ制限を2MBに増やすには、次の行を追加します。

SOLR_OPTS="$SOLR_OPTS -Djute.maxbuffer=0x200000"

Windows: solr.in.cmd

変更するセクションはここから始まります。

REM Anything you add to the SOLR_OPTS variable will be included in the java
REM start command line as-is, in ADDITION to other options. If you specify the
REM -a option on start script, those options will be appended as well. Examples:

ファイルサイズ制限を2MBに増やすには、次の行を追加します。

set SOLR_OPTS=%SOLR_OPTS% -Djute.maxbuffer=0x200000

ZooKeeper接続のセキュリティ保護

ZooKeeperとSolr間の通信を保護することもできます。

znodesのACL保護を設定するには、ZooKeeperアクセス制御セクションを参照してください。