Apache Solr

 

SorlServerをseasarでinjectionしてsolrjから呼び出す

seasarでSolrServerをインジェクションします。diconファイルで自由にSolrServerを入れ替える事ができます。インジェクションしたSolrServerを呼び出し、solrjでマルチスレッドでインデクシングしましょう!

新サイト、tree-mapsを公開しました!!

tree-maps: 地図のWEB TOOLの事ならtree-mapsにお任せ!

地図に関するWEB TOOL専門サイトです!!

大画面で大量の緯度経度を一気にプロット、ジオコーディング、DMS<->DEGの相互変換等ができます!

◯ 広告

The Seasar Project

seasarは電通国際のひがやすおハイパー・グレート・クリエイターやすをさん作のJavaフレームワークです。

近年seasarを使うのは一般的になっており、使っている方も多いと思われます。

seasarは色々な方法でseasarのコンポーネントにクラスを登録する事ができます。

今回はdiconファイルを使って、org.apache.solr.client.solrj.SolrServerをインジェクションします。

diconでSolrServerを設定できると、実装を簡単に入れ替える事ができるので便利です。

インジェクションするためのdiconファイル、例えばsolr.diconという名前で以下を作成します。

なお、マルチコアの事は考えていないのでご了承下さい。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container 2.4//EN" 
    "http://www.seasar.org/dtd/components24.dtd">
<components namespace="solr">

    <!-- httpClient -->
    <component name="httpClient" class="org.apache.http.impl.client.DefaultHttpClient" autoBinding="none">
        <arg>
            <component class="org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager"/>
        </arg>
    </component>

    <!-- 住所インデクサ -->
    <component class="tree.solr.search.address.AddressIndexer">
        <property name="solrServer">
            <component class="org.apache.solr.client.solrj.impl.ConcurrentUpdateSolrServer">
                <!-- serverのurl -->
                <arg>"http://localhost:8983/solr/address/"</arg>
                <!-- queueサイズ -->
                <arg>"20"</arg>
                <!-- スレッド数 -->
                <arg>"8"</arg>
            </component>
        </property>
    </component>

    <!-- 住所サーチャー -->
    <component class="tree.solr.search.address.AddressSearcher">
        <property name="solrServer">
            <component class="org.apache.solr.client.solrj.impl.HttpSolrServer">
                <!-- serverのurl -->
                <arg>"http://localhost:8983/solr/address/"</arg>
                <!-- httpClient -->
                <arg>httpClient</arg>
            </component>
        </property>
    </component>
</components>

ここで使うHttpClientは4系です。3系ではありません。

ポイントは、インデクサでConcurrentUpdateSolrServerをインジェクションしている点です。

ConcurrentUpdateSolrServerはインデクシング処理をマルチスレッドで行う事ができる、スグレモノなのです。

引数にキュー数とスレッド数を指定することができるので、CPU数・コア数に合わせて調整しましょう。

開発環境の場合は4スレッド、本番環境は20スレッド、等と環境毎にsolr.diconを用意するのもいいかと思います。

サーチャーはVIPを指定する前提でHttpSolrServerにしていますが、LBHttpSolrServerでもいいと思います。


solr.diconの作成が終わったら、任意のdiconでincludeしてあげましょう。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container 2.4//EN" 
    "http://www.seasar.org/dtd/components24.dtd">
<components>
    <include path="convention.dicon"/>
    <include path="aop.dicon"/>
    <include path="s2jdbc.dicon"/>
    <include path="solr.dicon"/>
</components>

設定はこれで完了です。続いてインジェクションするクラスを用意しましょう。

package tree.solr.search;

import java.io.IOException;

import org.apache.solr.client.solrj.SolrServer;
import org.apache.solr.client.solrj.SolrServerException;

import tree.solr.exception.SolrException;

/**
 * SolrServer基底クラスです。
 * @author tree
 */
public abstract class BaseServer {

    private SolrServer server;

    /**
     * SolrServerを設定します。<br>
     * solr.diconでインジェクションするためのメソッドです。
     * @param server SolrServer
     */
    public void setSolrServer(SolrServer server) {
        this.server = server;
    }

    /**
     * SolrServerを取得します。
     * @return
     */
    protected SolrServer getSolrServer() {
        return server;
    }

    /**
     * SolrServerにpingします。
     */
    protected void ping() {
        try {
            server.ping();
        } catch (SolrServerException e) {
            throw new SolrException(e);
        } catch (IOException e) {
            throw new SolrException(e);
        }
    }
}

solr.diconはsetSolrServerメソッドを使ってSolrServerをインジェクションします。

SolrServerはinterfaceであり、注入される実装クラスはsolr.diconで任意に指定されます。


ここから先のインデクシング処理は「solrjで独自のインデクサを実装する」をご覧下さい。

BaseSolrServerを継承したクラスがgetSolrServer()でConcurrentUpdateSolrServerが取得できます。

ConcurrentUpdateSolrServerでインデクシングした際のログは以下のようになります。

・・・略・・・
ConcurrentUpdateSolrServer.run starting runner: org.apache.solr.client.solrj.impl.ConcurrentUpdateSolrServer$Runner@3f0ccac7
ConcurrentUpdateSolrServer.run starting runner: org.apache.solr.client.solrj.impl.ConcurrentUpdateSolrServer$Runner@338929d
ConcurrentUpdateSolrServer.run starting runner: org.apache.solr.client.solrj.impl.ConcurrentUpdateSolrServer$Runner@77218311
ConcurrentUpdateSolrServer.run starting runner: org.apache.solr.client.solrj.impl.ConcurrentUpdateSolrServer$Runner@39240e31
ConcurrentUpdateSolrServer.run starting runner: org.apache.solr.client.solrj.impl.ConcurrentUpdateSolrServer$Runner@4dfaa832
ConcurrentUpdateSolrServer.run starting runner: org.apache.solr.client.solrj.impl.ConcurrentUpdateSolrServer$Runner@4dfaa832
ConcurrentUpdateSolrServer.run starting runner: org.apache.solr.client.solrj.impl.ConcurrentUpdateSolrServer$Runner@3ba11b1b
ConcurrentUpdateSolrServer.run starting runner: org.apache.solr.client.solrj.impl.ConcurrentUpdateSolrServer$Runner@60d4ef27
ConcurrentUpdateSolrServer.run Status for: 4747208472080015000 is 200
ConcurrentUpdateSolrServer.run Status for: 4747208472080011005 is 200
ConcurrentUpdateSolrServer.run finished: org.apache.solr.client.solrj.impl.ConcurrentUpdateSolrServer$Runner@4dfaa832
ConcurrentUpdateSolrServer.run Status for: 4747208472080014000 is 200
ConcurrentUpdateSolrServer.run Status for: 4747208472080016002 is 200
ConcurrentUpdateSolrServer.run finished: org.apache.solr.client.solrj.impl.ConcurrentUpdateSolrServer$Runner@3f0ccac7
ConcurrentUpdateSolrServer.run finished: org.apache.solr.client.solrj.impl.ConcurrentUpdateSolrServer$Runner@60d4ef27
ConcurrentUpdateSolrServer.run Status for: 4747208472080013001 is 200
ConcurrentUpdateSolrServer.run finished: org.apache.solr.client.solrj.impl.ConcurrentUpdateSolrServer$Runner@4dfaa832
ConcurrentUpdateSolrServer.run Status for: 4747208472080016001 is 200
ConcurrentUpdateSolrServer.run Status for: 4747208472080013002 is 200
ConcurrentUpdateSolrServer.run finished: org.apache.solr.client.solrj.impl.ConcurrentUpdateSolrServer$Runner@3ba11b1b
ConcurrentUpdateSolrServer.run finished: org.apache.solr.client.solrj.impl.ConcurrentUpdateSolrServer$Runner@77218311
ConcurrentUpdateSolrServer.run Status for: 4747208472080012000 is 200
ConcurrentUpdateSolrServer.run finished: org.apache.solr.client.solrj.impl.ConcurrentUpdateSolrServer$Runner@39240e31
ConcurrentUpdateSolrServer.run finished: org.apache.solr.client.solrj.impl.ConcurrentUpdateSolrServer$Runner@338929d
・・・略・・・

こんなログが大量に流れます。solr.diconで8スレッド指定したので、8つrun/finishしていますね。

ConcurrentUpdateSolrServerは内部でExecutorServiceでキューイング+スレッド実行、という実装をしています。

なお、ConcurrentUpdateSolrServerはインデクシング部分のみマルチスレッドなので注意です。

その他の処理は普通にシングルスレッドです。

仮にConcurrentUpdateSolrServerでエラーが起きた場合、rollbackする事が可能です(commitしない)。

簡単且つ安全にマルチスレッドでインデクシングできるので、ConcurrentUpdateSolrServerを使いましょう!

◯ 広告