Solr4を動かしてみるシリーズの5回目です。
今回はSolr4でmaster-slaveの単純レプリケーションを構築したいと思います。
レプリケーションの構成にはReplicationHandlerを使います。
coreのインスタンスディレクトリ下のconf内にあるsolrconfig.xmlを開くと、レプリケーション構成のテンプレートが記述してあり、この部分のコメントを外して必要な項目を設定すればレプリケーション完了なのです(`_´)ゞ
非常にかんたんです。
レプリケーションを構築するにあたっては何はともあれ、MasterとSlaveの2サーバが必要です。
ここから先は、Master用のサーバとSlave用のサーバの2つがあると仮定して話をすすめます。
5.1. Masterの設定をおこなう
まずはMaster側の設定から行いましょう。
Masterサーバのsolrconfig.xmlを開きます。
こんなふうにReplicationの設定がコメントアウトされています。
<!-- Solr Replication The SolrReplicationHandler supports replicating indexes from a "master" used for indexing and "slaves" used for queries. http://wiki.apache.org/solr/SolrReplication It is also necessary for SolrCloud to function (in Cloud mode, the replication handler is used to bulk transfer segments when nodes are added or need to recover). https://wiki.apache.org/solr/SolrCloud/ --> <requestHandler name="/replication" class="solr.ReplicationHandler" > <!-- To enable simple master/slave replication, uncomment one of the sections below, depending on whether this solr instance should be the "master" or a "slave". If this instance is a "slave" you will also need to fill in the masterUrl to point to a real machine. --> <!-- <lst name="master"> <str name="replicateAfter">commit</str> <str name="replicateAfter">startup</str> <str name="confFiles">schema.xml,stopwords.txt</str> </lst> --> <!-- <lst name="slave"> <str name="masterUrl">http://your-master-hostname:8983/solr</str> <str name="pollInterval">00:00:60</str> </lst> --> </requestHandler>
これをこんなふうに変更します。
<requestHandler name="/replication" class="solr.ReplicationHandler" > <!-- コメント外します。 --> <lst name="master"> <str name="enable">true</str> <str name="replicateAfter">commit</str> <str name="replicateAfter">startup</str> <str name="confFiles">schema.xml,stopwords.txt,elevate.xml</str> <str name="commitReserveDuration">00:00:10</str> </lst> <!-- slaveの設定は削除しちゃいます。 --> <!-- バックアップファイルの数を指定しました。 --> <str name="maxNumberOfBackups">1</str> </requestHandler>
設定内容について、詳しくはhttp://wiki.apache.org/solr/SolrReplicationを見ろということですが、
ざっくり解説します。
# | 項目 | 内容 | 例 | 備考 |
---|---|---|---|---|
1 | enable | Masterとして有効かどうかを指定します。 | true/false | falseを指定すると、Masterサーバとしては動きません。 |
2 | replicateAfter | レプリケーションを行うトリガーとなるアクションを指定します。commitを指定するとコミット時にslaveにインデックスが同期されます。 startupのみを指定すると、起動時にしかレプリケーションを行わないので、実質レプリケーションとなりません^^; |
commit | commit: コミット時、startup: 起動時、optimize: 最適化時の1つ以上を指定します。 |
3 | confFiles | slaveに同期する設定ファイルを指定します。サーバの設定以外に、ユーザディクショナリ系のファイルも指定した方がよいでしょう。 | schema.xml,stopwords.txt | カンマ区切りで複数指定できます。slave用のsolrconfig.xmlを別名で保存しておき、slaveにはsolrconfig.xmlとして同期することもできます。
<str name=”confFiles”> |
4 | commitReserveDuration | 指定がない場合デフォルト値の10secが使われます。おおよそ5MBを転送できる時間。 | 00:00:10 | コミット量が多かったり、ネットワーク速度が遅い場合に指定しろと・・・ |
5 | backupAfter | バックアップを行うトリガーとなるアクションを指定します。 レプリケーションの機能として必要なわけではありません。 |
commit | commit: コミット時、startup: 起動時、optimize: 最適化時の1つ以上を指定します。 |
6 | maxNumberOfBackups | バックアップを作成する場合に、保持するバックアップファイルの数を指定します。 | 2 | Solr3.6系ではバグがあったようです。https://issues.apache.org/jira/browse/SOLR-3361 |
solrconfig.xmlを編集したら、Solrを再起動してに設定を反映させましょう。
service solr restart
5.2. Slaveの設定をおこなう
つづいて**Slave**側の設定も行いましょう。
Slaveサーバのsolrconfig.xmlを開きます。
<requestHandler name="/replication" class="solr.ReplicationHandler" > <!-- masterの設定は削除しちゃいます。 --> <lst name="slave"> <str name="enable">true</str> <str name="masterUrl">http://master_host:port/solr/corename</str> <str name="pollInterval">00:00:20</str> <str name="compression">internal</str> <str name="httpConnTimeout">5000</str> <str name="httpReadTimeout">10000</str> <!-- <str name="httpBasicAuthUser">username</str> <str name="httpBasicAuthPassword">password</str> --> </lst> <!-- バックアップファイルの数を指定しました。 --> <str name="maxNumberOfBackups">1</str> </requestHandler>
Masterの設定項目と全然ちがいます。
(あたりまえですが・・)
Slaveの設定項目もざっくり解説します。
# | 項目 | 内容 | 例 | 備考 |
---|---|---|---|---|
1 | enable | Slaveとして有効かどうかを指定します。 | true/false | falseを指定すると、Slaveサーバとしては動きません。 |
1 | masterUrl | MasterサーバのURLを指定します。 | http://master.solr.local:8983/solr/core0 | つまり、httpプロトコルで疎通するということです。 |
2 | pollInterval | masterにポーリングする間隔をHH:mm:ss形式で指定します。 | 00:00:20 | pollIntervalを指定しなかった場合、自動でのポーリングは行いません。 管理ツールから同期させるとかHTTP APIを叩くとかでmasterとの同期を行う必要があります。 |
3 | compression | インデックスファイルの転送時に圧縮を行いたい場合に指定します。 | internal | ‘internal'(slave側で圧縮)と’external'(master側で圧縮)を指定できますが、’external’を指定した場合にはmasterサーバの方でaccept-encodingヘッダの設定が必要となります。 |
4 | httpConnTimeout | masterサーバからインデックスファイルを取得する際のコネクションタイムアウトを指定します。 | 5000 | ミリ秒で指定します。デフォルト値は5,000msです。特に指定する必要はありません(と書いてありました)。 |
5 | httpReadTimeout | masterサーバからインデックスファイルを取得する際のリードタイムアウトを指定します。 | 10000 | ミリ秒で指定します。デフォルト値は10,000msです。ここも特に指定する必要はありません(と書いてありました)。 |
6 | httpBasicAuthUser | masterサーバでBasic認証を行っている場合にBasic認証ユーザを指定します。 | solr-repl | |
7 | httpBasicAuthPassword | masterサーバでBasic認証を行っている場合にBasic認証パスワードを指定します。 | password |
Slaveサーバも、solrconfig.xmlを編集したら、Solrを再起動してに設定を反映させましょう。
service solr restart
5.3. 管理ツールから確認する
レプリケーションの設定は以上で完了です。
管理ツールで見てみましょう。
Master
管理ツールでコアを選択します(私の設定ではcore0)。
コアを選択したら次にReplicationを選択します。
Masterに設定した内容を確認することができます。
Slave
Slaveの管理ツールも開いてみます。
SlaveのmasterUrlに存在しないサーバを指定したので「Invalid Server」となってしまいました。
正しく疎通ができればMasterの管理ツールのようにenabledになります。
5.4. Master-Slaveで共通のsolrconfig.xmlを使うための工夫
solrconfig.xmlのレプリケーション設定をpropertyファイルに委譲して、Master-Slaveで共通のsolrconfig.xmlを使うことにしましょう。
こうすることで、masterが死んだときにすばやくslaveをmasterに昇格できたり、後で記述するRepeaterの役割をさせたりすることができます。
5.4.1. solrconfig.xmlのReplicationHandlerにパラメータを設定する
solrconfig.xmlを編集します。
ReplicationHandlerにMasterの項目とSlaveの項目両方を記述し、さらに値をパラメータ化します。
<requestHandler name="/replication" class="solr.ReplicationHandler" > <!-- master向けの設定 --> <lst name="master"> <str name="enable">${master.enable}</str> <str name="replicateAfter">${master.replicateAfter1}</str> <str name="replicateAfter">${master.replicateAfter2}</str> <str name="confFiles">${master.confFiles}</str> <str name="commitReserveDuration">${master.commitReserveDuration}</str> </lst> <!-- slave向けの設定 --> <lst name="slave"> <str name="enable">${slave.enable}</str> <str name="masterUrl">${slave.masterUrl}</str> <str name="pollInterval">${slave.pollInterval}</str> <str name="compression">${slave.compression}</str> <str name="httpConnTimeout">${slave.httpConnTimeout}</str> <str name="httpReadTimeout">${slave.httpReadTimeout}</str> </lst> <!-- バックアップファイルの数を指定しました。 --> <str name="maxNumberOfBackups">${maxNumberOfBackups}</str> </requestHandler>
5.4.2. プロパティファイルを作成する
Master向けのプロパティファイルとSlave向けのプロパティファイルを作成します。
confの下にmaster.propertiesとslave.propertiesを作成します。
master.properties
# masterの設定 master.enable=true # master向けの設定なのでtrueを指定します。 master.replicateAfter1=commit master.replicateAfter2=startup master.confFiles=schema.xml,stopwords.txt,elevate.xml master.commitReserveDuration=00:00:10 # slaveの設定 slave.enable=false # slave.enableにはfalseを指定します。 slave.masterUrl=http://master_host:port/solr/corename slave.pollInterval=00:00:20 slave.compression=internal slave.httpConnTimeout=5000 slave.httpReadTimeout=10000
slave.properties
# masterの設定 master.enable=false # slave向けの設定なのでfalseを指定します。 master.replicateAfter1=commit master.replicateAfter2=startup master.confFiles=schema.xml,stopwords.txt,elevate.xml master.commitReserveDuration=00:00:10 # slaveの設定 slave.enable=false # slave向けの設定なのでtrueを指定します。 slave.masterUrl=http://master_host:port/solr/corename slave.pollInterval=00:00:20 slave.compression=internal slave.httpConnTimeout=5000 slave.httpReadTimeout=10000
で、Solrの起動時にプロパティファイルとしてこれらを指定します。
第1回目で/etc/default/jettyにJAVA_OPTIONSを設定しました。
つまり私の環境では、Solr起動時のJVMパラメータは/etc/default/jettyに記述するようになっています。
このJAVA_OPTIONS変数にプロパティファイルの指定を追加します。
/etc/default/jetty(Master向けの設定)
SOLR_OPTIONS="-Dsolr.solr.home=/opt/solr/server/solr -Dsolr.properties=master.properties" # 追加しました JAVA_HOME=/etc/alternatives/java_sdk JAVA_OPTIONS="-Djava.awt.headless=true -server -XX:+UseGCOverheadLimit -XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode -XX:+UseTLAB -XX:MaxPermSize=128m -Xms512M -Xmx1024M $JAVA_OPTIONS $SOLR_OPTIONS" # **$SOLR_OPTIONS**を追加しました。 JETTY_HOME=/opt/solr/server JETTY_USER=root JETTY_PORT=8983 JETTY_LOGS=/var/log/solr
/etc/default/jetty(Slave向けの設定)
SOLR_OPTIONS="-Dsolr.solr.home=/opt/solr/server/solr -Dsolr.properties=slave.properties" # 追加しました JAVA_HOME=/etc/alternatives/java_sdk JAVA_OPTIONS="-Djava.awt.headless=true -server -XX:+UseGCOverheadLimit -XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode -XX:+UseTLAB -XX:MaxPermSize=128m -Xms512M -Xmx1024M $JAVA_OPTIONS $SOLR_OPTIONS" # **$SOLR_OPTIONS**を追加しました。 JETTY_HOME=/opt/solr/server JETTY_USER=root JETTY_PORT=8983 JETTY_LOGS=/var/log/solr
Master, SlaveともにSolrを再起動します。
5.5. Repeaterを使う
SolrにはRepeaterという仕組みがあります。
Repeaterとは何かといいますと、その名の通り中継機の役割をします。
Masterサーバに対してはSlaveとして振る舞うことができ、Slaveサーバに対してはMasterサーバとして振る舞うことができます。
1台のMasterに対してたくさんのSlaveがいるケースや、MasterとSlaveの拠点間が物理的に遠い場合を想像してみてください。結構なネットワーク負荷がかかってしまいます。
そんなときにこのRepeaterサーバを設置します。
1台のmasterでたくさんのslaveの相手をしなくてはならない・・・
真のMasterと通信を行うのはRepeater、SlaveはRepeaterのみと通信を行うことでMasterにかかる負荷を低減することができます。
repeaterを追加して解決
あるサーバをRepeaterサーバとするには、solrconfig.xmlのReplicationHandlerに、Masterとしての設定とSlaveとしての設定の両方を記述します。
Repeaterのsolrconfig.xml
<requestHandler name="/replication" class="solr.ReplicationHandler" > <!-- masterとしての設定 --> <lst name="master"> <str name="enable">${master.enable}</str> <str name="replicateAfter">${master.replicateAfter1}</str> <str name="replicateAfter">${master.replicateAfter2}</str> <str name="confFiles">${master.confFiles}</str> <str name="commitReserveDuration">${master.commitReserveDuration}</str> </lst> <!-- slaveとしての設定 --> <lst name="slave"> <str name="enable">${slave.enable}</str> <str name="masterUrl">${slave.masterUrl}</str> <str name="pollInterval">${slave.pollInterval}</str> <str name="compression">${slave.compression}</str> <str name="httpConnTimeout">${slave.httpConnTimeout}</str> <str name="httpReadTimeout">${slave.httpReadTimeout}</str> </lst> <!-- バックアップファイルの数を指定しました。 --> <str name="maxNumberOfBackups">${maxNumberOfBackups}</str> </requestHandler>
Repeaterのプロパティファイル( repeater.properties )
# masterとしての設定 master.enable=true # repeaterなのでmasterもslaveもtrueにします。 master.replicateAfter1=commit master.replicateAfter2=startup master.confFiles=schema.xml,stopwords.txt,elevate.xml master.commitReserveDuration=00:00:10 # slaveの設定 slave.enable=true # repeaterなのでmasterもslaveもtrueにします。 slave.masterUrl=http://master_host:port/solr/corename slave.pollInterval=00:00:20 slave.compression=internal slave.httpConnTimeout=5000 slave.httpReadTimeout=10000
こちらも再起動して内容を反映させます。
以上でSolr4のレプリケーション設定についておしまいです。