NearRealTimeSearchの紹介

あけましておめでとうございます。大谷です。本年もよろしくおねがいいたします。
新年最初のエントリーはNearRealTimeSearchの紹介です。(
PDF版はこちら

1. NearRealTimeSearchとは
Solrを利用した検索サイトを作成するとき、多くの場合は登録するデータはバッチによる定期的な更新を行うようにするのが一般的です。これは、Solrのインデックスへの書き込みがトランザクションに対応していないことやインデックス更新を行なっている間の検索性能の劣化などが要因となっています。
ただ、最近では定時更新ではなく、よりリアルタイムに検索インデックスにデータの追加更新を反映したいという要件が多くなってきています。この要件に対応するために提案、実装されたものがNearRealTimeSearch(ほぼリアルタイム検索)と呼ばれる機能です(以降ではNRTと略します。)。
Luceneには2.9ですでにNRTが実装されていましたが、Solrにて利用できる形にするためにSOLR-2193で提案されました。

2. NRTの仕組み
NRTはLuceneのNRTを利用した仕組みになります。LuceneのNRTはインデックスの書き込みを行うIndexWriterから、Index検索のためのオブジェクトIndexReaderを取得することができるようになる機能になります。すなわち、インデックスがファイルに書き込まれる前の(メモリ上にあるインデックス)状態で検索が可能になることになります。
Solrでは、この機能を利用するためにこれまでコミット(commit)と呼ばれていた機能を以下の2つコミットとして再定義しました。

  • Hard Commit
    これまでのコミットと同義。停電からのデータロスをなくすためにfsyncを呼び出し、ファイルにインデックスを出力する。
  • Soft Commit
    新たに追加されたコミットの種類。インデックスの変更をファイルに反映せず、メモリ上に反映する。
    Soft CommitがNRTを利用するためのコミットとなります。ディスクへの書き込みは保証されませんが、ほぼリアルタイムに検索結果に反映がされます。

3. 制約事項
現在、NRTが利用できるのはtrunkである4.x系のみとなります。3.x系以前では残念ながら利用できません。
前述ですが、ディスクへ書き込みも保証されません。VMがクラッシュしたり停電が発生した場合は直前のHard Commitが実行された時点までインデックスの状態が戻ることに注意が必要です。
また、Soft Commitの仕組み上、レプリケーションによる同期が利用できません。こちらもHard Commit時点ごとにしかレプリケーションが動作しません。Soft Commitによるほぼリアルタイム反映についてはデータ更新対象となっているSolrサーバでのみ恩恵をうけることが可能です。

4. 利用方法
2で説明しましたが、Commitの新しいタイプとしてSoft Commitが追加されています。まずは、XMLによるコミット時の指定は次の様になります。

softCommit=”true”オプションを指定するとSoft Commitの動作となります。
管理画面のPendingDocsを見ると、Soft Commit前に更新したデータ件数がコミットされていない状態がわかります。ただし、Soft Commitは実施されていますので、検索結果には表示されます。
次は設定によるAutoCommitについてです。Solrではsolrconfig.xmlの設定によりAutoCommitが設定可能です。設定は次の通りです。

これまで同様、maxDocsによる指定とmaxTimeによる指定が可能です。

  • maxDocs
    直前のSoft Commitが実施されてから登録されたデータ数が指定された数に達した場合にSoft Commitが実行される。
  • maxTime
    データが登録されてから指定されたミリ秒経過するとSoft Commitが実行される。
    Hard Commitの設定についてはこれまでと同様のタグにて指定可能です。Soft Commitを毎秒、Hard Commitを数分おきとすることで、定期的にファイルにインデックスを保存しつつ、ほぼリアルタイムに更新を反映させるといった設定が可能になります。

5. 今後の展開
前述しましたがNRTは、マスタスレーブ構成(レプリケーション)には対応していません。マスタスレーブ構成についてはSolrのMLで話が上がりましたが、現在のレプリケーションの機能との併用は望めないようです。代わりにSolrCloudと呼ばれる別の新しい分散インデックスの機能が紹介されています。SolrCloudとはクラウドでの検索サービスとしてSolrを運用管理するために現状のSolrの拡張する機能です。
NRTについてはまずは、マスタスレーブでない環境で利用してみるのはいかがでしょうか。

参考:
http://wiki.apache.org/solr/NearRealtimeSearch
http://wiki.apache.org/solr/UpdateXmlMessages#Optional_attributes_for_.22commit.22_and_.22optimize.22
http://wiki.apache.org/solr/SolrConfigXml?#Update_Handler_Section
http://www.lucidimagination.com/blog/2011/07/11/benchmarking-the-new-solr-%E2%80%98near-realtime%E2%80%99-improvements/
http://lucene.472066.n3.nabble.com/NRT-and-replication-tt3422940.html
http://wiki.apache.org/solr/NewSolrCloudDesign

Solr勉強会第7回でlucene-gosenについて発表しました。

お久しぶりです、大谷です。

12/19(月)に開催されたSolr勉強会でlucene-gosenについて発表してきました。

lucene-gosenとは?
私がコミッターとして参加している形態素解析ライブラリになります。
Solr入門でサンプルとして利用していたSenがメンテナンスされなくなり、その後継のGoSenも出てきたのですが、こちらもメンテナンスがされなくなりと、
フリーで利用できる形態素解析器がなくなってきたところ、Lucene/Solrのコミッターの方々がGoSenを引き取り、公開した形態素解析器がlucene-gosenになります。
Solrのコミッターである関口さんの紹介で、今年の4月から私も微力ながら参加しています。
Solrでも簡単に利用できる形態素解析器となっていますので、どんどん利用してください。

発表資料
発表資料はこちらになります。簡単ですが、Solrのインデックスの作りから、lucene-gosenの機能の紹介まで入っていますので、参考にどうぞ。

あと、その他のセッションについてはこちらにログをのこしてありますので、参考までに。

SolrJ使用上の注意(Too many open files)

お久しぶりです、大谷です。

朝晩めっきり涼しくなり、少しずつ秋の気配を感じることができる日が増えてきました、いかがお過ごしですか。
シルバーウィークも近づいているので、どこか遊びに行こうかと妄想している日々が続いています。

さて、今回はSolrJの利用方法の注意点についてです。

よく、Solrを利用していて「Too many open files」が発生して困っていますという話を聞きます。(今年は3回くらいきいている)
この話を聞いたときに、毎回ハマるのですが、Solrが動作しているサーバ側で発生していると思い、
「optimize」していますか?とか「リクエスト数はどのくらいで負荷テストしていますか?」などという質問をしてしまいます。

よくよく話を聞いていく(ここまでに数回やり取りをする)と、実はSolrが動作しているサーバではなく、SolrJを利用しているクライアントアプリ側で
「Too many open files」と出力されているという話に行き着きます。そこで、いつもSolrJの利用方法に問題があることを思い出します。

では、なぜ、Solrへリクエストを投げているだけのクライアント側で「Too many open files」が発生してしまうのでしょう。
実は、SolrJのあるクラスをリクエストごとにインスタンス化していることが問題です。
「CommonsHttpSolrServer」がそのクラスになります。

SolrのWikiなどを見てもmain関数で呼び出す例だけですので詳しく書かれていません。
おそらく、この利用方法を見て、かつ、SolrJのJavaDocにも目立つところに注意点は書かれていないので、
リクエストごとに(Solrへの接続が必要になるタイミングで)毎回CommonsHttpSolrServerをnewしているのでしょう。

CommonsHttpSolrServerはApacheのHttpClientというHttp接続用のライブラリを内部で利用しており、HttpClientにあるMultiThreadConnectionManager
というConnectionを管理するクラスを利用しています。
このクラスですが、内部でConnectionをプールする機能を持っています。(http://hc.apache.org/httpclient-3.x/threading.html
MultiThreadConnectionManagerをnewするたびに、特定の本数のConnectionが生成され、プールされていきます。ConnectionはSocketを開きますので、ファイルディスクリプタが消費されます。
このため、負荷をかけ続けたり、リクエストを処理していくと「Too many open files」が発生し始めるのです。
SolrJでは、特に指定をしない場合、Solrのホスト名に対して最大32本のコネクションが生成されます。
Linuxなどでは通常、ファイルディスクリプタを利用できる上限が1028となっています。ですので、あっという間にエラーが出始めることになるのです。

解決策は次のような方法になります。

  • CommonsHttpSolrServerのインスタンスを再利用する(singletonで利用するなど)
  • MultiThreadConnectionManagerを再利用する形とし、HttpClientを引数とするCommonsHttpSolrServerのコンストラクタを利用する

ということで、自戒の意味も込めますが、「「Too many open files」エラーが出たときはSolrJの利用方法に問題がないかチェックするのも必要である」というのを忘れないようにしましょう。

※拙著である、Solr入門ではSolrJのサンプルプログラムでCommonsHttpSolrServerを利用していますが、Servletのインスタンス変数として定義し、
initにて1度だけCommonsHttpSolrServerをnewしています。(もう少し詳しく注意点を書いておくべきでした。)

Solrの機能と性能について

はじめまして、シーマークの大谷です。

Solr入門が出版されてから1年以上経ちました。

SolrのコミュニティはSolr入門を書いて以降も活発に活動が続いており、Luceneプロジェクトと統合され、現在はバージョン3.3がリリースされています。(最近は2ヶ月おきにリリースが行われるくらいです)

Solrも多くのサイトで導入が検討されたり、実際に利用されてきています。

ただ、Solrは手軽に様々な機能が利用出来る反面、構成やケアすべき点が色々と存在します。

 

私の方では新機能の紹介や、Wikipediaのデータを利用した簡単な性能測定の結果などを

このブログで取り組んでいこうと思っています。よろしくお願いします。

 

※あと、個人のブログですが、lucene-gosenというSenの後継にあたる形態素解析ツールについて記述をしています。こちらも参考にしていただければと。