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しています。(もう少し詳しく注意点を書いておくべきでした。)