Solrでrsyncによるレプリケーション

solrでレプリケーションをする際にbandwidthの制限ができなそうだったので、rsyncを使ってレプリするようにした。


通常はsolr/conf/scriptconfig.xmlに以下のような設定があると、更新があったときにレプリケーションされる。

<requestHandler name="/replication" class="solr.ReplicationHandler" >
  <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://localhost:8983/solr/replication</str>
    <str name="pollInterval">00:00:60</str>
  </lst>
</requestHandler>


ただ、大規模になれば、ネットワークに負担がかかってくるので、bandwidthの制限ができないか設定を探したが、それらしきもの見つからなかった。少し探して見つけたのはcompression, httpConnTimeout, httpReadTimeoutだけど、求めるものとは違っていた。

  • compression

データを圧縮して送れる。externalにすれば、Tomcatで何かできるっぽいけど、詳しくは調べてない。

<!-- THE FOLLOWING PARAMETERS ARE USUALLY NOT REQUIRED-->

<!--to use compression while transferring the index files. The possible values are internal|external
 if the value is 'external' make sure that your master Solr has the settings to honor the
 accept-encoding header.
 See here for details: http://wiki.apache.org/solr/SolrHttpCompression
 If it is 'internal' everything will be taken care of automatically.
 USE THIS ONLY IF YOUR BANDWIDTH IS LOW . THIS CAN ACTUALLY SLOWDOWN REPLICATION IN A LAN-->

 <str name="compression">internal</str>
  • httpConnTimeout, httpReadTimeout

タイムアウトの設定ができる。

<!--The following values are used when the slave connects to the master to download the index files.
 Default values implicitly set as 5000ms and 10000ms respectively. The user DOES NOT need to specify
 these unless the bandwidth is extremely low or if there is an extremely high latency-->

 <str name="httpConnTimeout">5000</str>
 <str name="httpReadTimeout">10000</str>

ということで、rsyncレプリケーションをするようにした。

rsyncレプリケーション

もともと 1.1~1.3 では rsync でのレプリが提供されていたらしいので、今でもソースには rsync でのレプリ用のスクリプト (apache-solr-3.6.2/solr/scripts以下にある) が残っている。これらを solr/bin 以下にコピーし、solr/conf/scripts.conf に設定を書けば、rsync でのレプリができるようになる。


流れとしては

  1. master:スナップショットとる
  2. slave:masterの最新のスナップショットをrsyncで取得する
  3. slave:取得したスナップショットを反映

masterの設定

  • スナップショットを取れるようにする

solr/conf/solrconfig.xml に以下を書くと、更新があったときに、solr/bin/snapshooter が呼ばれ、インデックスのスナップショットが取られる。
なぜか exe に絶対パスを指定しないとうまくいかなかった。

<updateHandler class="solr.DirectUpdateHandler2">
  <listener event="postCommit" class="solr.RunExecutableListener">
    <str name="exe">${solr.home}/bin/snapshooter</str>
    <str name="dir">.</str>
    <bool name="wait">true</bool>
  </listener>
</updateHandler>
  • rsyncでスナップショットをslaveに送れるようにする

slave 側が rsync で最新のスナップショットを取得できるように、solr/bin/rsyncd-enable と solr/bin/rsyncd-start で rsyncd を動作させる。
solr/conf/scripts.conf に rsyncd_bwlimit=1000 や compress=z とかを書くと、rsync する際に、bandwidth の制限や圧縮ができる

  • スナップショットの削除 (slaveでも)

solr/bin/snapcleaner で定期的にスナップショットを削除する

slaveの設定

solr/bin/snappuler-enable でスナップショットを取得できるようにしておき、cron でスナップショットの取得 (solr/bin/snappuller) と反映 (solr/bin/snapinstaller) をできるようにする。

*/5 * * * * <solr.solr.home>/solr/bin/snappuller;<solr.solr.home>/solr/bin/snapinstaller


これでrsyncレプリケーションができるようになる。もしかしたらrsyncじゃなくてもできるのかもしれない。