Apache Solr

 

solrを使う前に知っておくべき事

solrというものが何ができて何ができないか、得意・不得意な点はどこか、を検証します。主にMySQL等のRDBとの比較になります。私が実際に業務でsolrを使った際に得た知識を元に書いています。

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

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

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

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

◯ 広告

Apache solr

solr wiki

オープンソースのpure javaの全文検索エンジンです。

Apacheのトッププロジェクトであり、twitterやfacebook級のサイトでも使用されています。

  • 超高速検索のエンジンを自分で作成可能(オレオレMySQLのようなものを作る事ができる)。
  • 検索する項目を自分で定義可能(RDBのカラム)。
  • 定義した項目に、順序を保持したままリスト形式で値を保存可能(カラムにjavaでいうところのListを保存できる)。
  • 完全一致検索可能
  • 中間一致検索可能(フルスキャンで超低速になるので非推奨)。
  • 前方一致検索可能
  • 超高速に件数を取得する、ファセット検索が可能。(select count(*)を100回同時に行なっても超高速)
  • 超高速に同義語検索可能で、同義語の辞書を自分で定義可能。(or name = 'アップル' or name = 'apple' ....)
  • 形態素解析を利用した全文検索(フリーワード検索)が可能で、形態素解析の辞書を自分で作成可能
  • 類似検索可能(googleのもしかして機能)。
  • 検索ワードに対しての関連度検索可能(この商品もおすすめです機能)。
  • 検索結果から統計情報を取得可能(男性+30代+会社員の平均貯蓄額の算出等)。
  • 分散検索可能(複数のサーバにデータを分散して並列に同時検索)。
  • クラウドで分散検索可能(スケールして負荷分散)。
  • レスポンスの形式(csv・xml・binary等)を自由にカスタマイズ可能(レスポンスを返す前にデータを整形できる)。
  • 簡単にレプリケーション可能(サーバ間のデータ・設定ファイルの同期)。
  • キャッシュ機能を標準搭載(RDBのレコード・カラムキャッシュ等)。
  • 管理画面が標準搭載(データの確認、レプリケーションの開始等)。
  • あらゆるデータをバイナリ型で保存でき、復元可能

標準機能でできる事が多い事と、検索が超高速な点がポイントです。

  • 複雑なjoinはできない(簡単なjoinは可能)。
  • 複雑なグルーピングできない(簡単なgroup byはfacet fieldで可能)。
  • 後方一致検索できない(RDBの like '%hoge')。
  • 以上(greaterEqual)・以下(lessEqual)、大なり(greaterThan)、小なり(lessThan)のクエリが簡単に書けない。(範囲検索で代用)
  • null値は検索できない(そもそもnull値は値として保存されない)。
  • ロールバックは物理ファイルはロールバックされない。(RDBのロールバックと挙動が違う)

大体弱点は代替案があります。

ロールバックの挙動は要注意です。物理ファイルは破損したままで、サーチャーが破損インデックスを読み込まないだけの動作です。tomcat等を再起動すると破損したインデックスが読み込まれます。

  • 適当に作っても適当なクエリでもあらゆる検索が超高速
  • 件数取得が必要な要件は多く、検索が速い
  • 形態素解析+同義語を利用した精度の高い検索が可能(RDBのlike検索だと精度が悪すぎる)。
  • 単純なファイルコピーでデータの複製・backupが可能
  • 中心点から半径nメートル内を検索、等の位置情報検索が非常に簡単
  • レプリケーションが簡単なので参照の負荷分散は非常に簡単。

クエリが適当でも、誤って10回同じ検索しても、とにかく超高速。

  • 日本語の情報・解説サイトは少ない。(solr wikiは英語です)
  • 設定ファイルが巨大で扱いも少々難しい。(solrconfig.xmlは1600行あります)
  • 動かすまでに苦労する。(情報の少なさに直結)
  • ソートはそれ程速くない。(第2ソート程度で止めておくのがよい)
  • 集計が必要なレポート生成等は厳しい、というか無理。(group byできないので死ねます)
  • データ生成(インデックス生成)が超遅い。(RDBのinsert/updateと比較して遅い)

「solrにできない事」がそのまま不得意な点になってます。

検索が超高速な代わりに、データ生成が遅いです。

レポート集計をsolrで行うのは正気の沙汰ではないです。素直にRDBでやりましょう。

更新性能が重要なシステムも不向きです。インデックス生成は遅いです。

厳密なトランザクション管理もできないので、RDBと同等の厳密さを求めている場合は使えません。

  • 一度に大量の件数取得(select count(*))が必要な場合
  • フリーワード検索が必要な場合
  • データの更新速度より検索速度を重視したい場合

高機能で高速検索が可能ですが、検索・データ生成のノウハウ・コストが高いので、無闇にsolrを使うべきではありません。

もし使うならsolrだけなく、RDBとsolrの共存するとよいです。

solrのインデックス生成はDBを使う場合がほとんどです。

タイムラグとは、DBの状態とsolrの状態が同じにならないという事を指します。

DBを更新した後にインデックス生成するので、その間は修正が反映されないのです。

よくある失敗フローは以下のようになります。

  1. 運用者が管理画面からデータを更新。DBのデータは更新された。
  2. 運用者は早速フロント画面を見る。しかし、修正したデータが反映されない!
  3. クレームの電話が来る。
  4. 運用者「なんで反映されないんだ!!!これはバグだ!バグを修正しろ!」
  5. 開発者「・・・という理由でタイムラグが発生してしまいまして、反映まで10分程時間が・・・」
  6. 運用者「わかった。10分後に確認する。(そわそわ・・)」
  7. 1週間後・・・
  8. クレームの電話が来る。
  9. 運用者「なんで反映されないんだ!!!これはバグだ!バグを修正しろ!」
  10. 開発者「・・・という理由でタイムラグが発生してしまいまして、反映まで10分程時間が・・・」
  11. 運用者「わかった。10分後に確認する。(そわそわ・・)」
  12. 以下、無限ループ

運用者からみると、更新内容が即座に反映されるのが当たり前で、即座に反映されない事が不安なのです。

運用者にタイムラグをしっかりと事前に伝えておくことで、不安を解消し、クレームの電話を減らしましょう。

実際のタイムラグの時間は以下の合計値になる場合が多いかと思います。

  • cronの周期
  • DBの更新時間
  • DBのレプリケーション時間
  • solrのインデックス生成時間
  • solrのレプリケーション時間

要件→PM+営業、DB構造→DBA、画面表示・検索仕様→PM+設計者、と連携してようやくsolrの項目定義が可能です。

パラメータの持ち方等、実装方式によって項目変更する事もよくあるので、検索画面実装担当者とも連携が必要です。

プロジェクトの参加人数に比例して連携量が増えるので、solr担当者は激務になりがちです。

solrの知識を有する方は少ないうえ、後述のようにDBスキルも必要なので、タスク分散が非常にし難いのです。

GoogleAppEngineのDataStoreと同様、RDBの正規化とは真逆の項目定義が必要です。

大抵RDBと共存するので、DBの構造を全て把握し、検索の要件、画面表示の要件を把握する必要があります。

インデックス生成時は大抵DBから値を取得するのですが、DBのselectの方がボトルネックになり易いです。

従って、DBのスキルも高くないと、インデックス生成時間に相当差がでます。

もしインデックス生成が遅いと、リアルタイムの差分更新の要件等を満たせない可能性すらあります。

以上の理由から、大抵solrの開発とDBAを兼任する事になりがちです。

カラム型の全文検索エンジンなので、MySQL等のRDBと概念は同じです。

クエリの書き方やデータ生成方法はRDBと異なりますが、検索の概念はRDBと同じです。

にも関わらず、未知の技術だから解らない、と言われる事があります。

よく解らない技術だからスケジュールが遅れてもよい、という免罪符的な言い訳材料にされ易いです。

大抵はよく解らない事にして、スケジュール遅延の言い訳材料にしたいだけの場合が多いです。

solrの検索担当者がRDBのORMのように扱えるIFを用意しているので、検索自体は簡単な場合が多いです。

単に検索メソッドに検索条件クラスを引数に渡すと、検索結果のDTOがListで返る程度の簡単なIFになります。

それでも執拗に「よく解らない」と連呼する人はさっさとご退場願いましょう。

一見 DB設計 -> solrのフィールド設計 とやりがちですが、これはアンチパターンです

フロントはDBの検索結果を画面に表示するのでなく、solrの検索結果を表示します。

つまりフロント開発で必要になるのはsolrの検索結果なのです。

solrの検索すらできない状況だとフロント開発が一部ストップしてしまいます。

従って、solrのフィールド設計 -> solrのサーチャー実装 -> solrのインデクサ実装 -> DB設計、という順に行います。

最初は項目値がほぼ空の検索結果がsolrから返るが、DB設計が進むにつれて徐々に項目値が埋まっていく感じです。

こうする事で、フロント開発を極力ストップさせずに開発できます。

前述と同様「solrの検索ができないから実装が進みません」という状況がよく起こります。

検索すると空のDTOのListが返るだけのスタブがあるだけでも、フロントの開発が止まりにくくなります。

この点は重要で、フロントとsolrの開発が同時に始まるスケジュールだと、以下のように残念な事が起こります。

フロント開発者「solrの検索の仕方を教えて下さい。」

solr開発者「は?今から開発するから何もできてないよ?」

フロント開発者「それは困りましたね。スケジュールが遅延します。」

solr担当者「・・・(おいおい初日にできてる訳ないだろう・・どうなってんだこのPJのスケジュールは・・)」

このやりとりは、プロジェクトの実装開始の初期段階に起こる事が多いです。

先にsolrの開発が始まるスケジュールだと、これを回避できます。

これを回避しないと、solr担当者が卒倒したり疾走したり突然絶叫しだしたり大変な事になるので注意しましょう。

◯ 広告