Your SlideShare is downloading. ×
SunspotではじめるSolr入門
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

SunspotではじめるSolr入門

6,089
views

Published on

社内勉強会でSunspotとSolrについて開催したときの資料です。 …

社内勉強会でSunspotとSolrについて開催したときの資料です。
Sunspotを初めて本番運用にのせる人向けに、Solrの基本的な機能や設定について紹介しました。
Railsは3.2と4.0を想定しています。

http://techracho.bpsinc.jp/baba/2013_08_17/12787

Published in: Technology

0 Comments
19 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
6,089
On Slideshare
0
From Embeds
0
Number of Embeds
10
Actions
Shares
0
Downloads
21
Comments
0
Likes
19
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. Sunspotではじめる Solr入門 2013/08/15 baba@bps 1
  • 2. はじめに • 本資料は社内勉強会で使った資料です • 一部ページや解説を追加しています • Rails 4.0をベースに書いていますが、Rails 3.1 / 3.2でも動作確認 をしています • 再配布等のご相談はbaba@bpsinc.jpまでお願いします 2
  • 3. はじめに • Railsは分かるけどSolrは全然分からない人向けです • 対象 • Railsの検索を高速化したい!Sunspotが良いと聞いたけど何これ? • Sunspotは試したことあるけどSolr分からないから設定を知りたい • Sunspot使ったサービスを公開したいけど、サーバ設定が分からん • 対象外 • Rails何それおいしいの • データは30件しかありません • 5億件のデータを分散処理する方法を探している • 全文検索エンジンの比較データが欲しい 3
  • 4. これは何? • Sunspot • SolrをRailsで使いやすくするgem • Solr • Luceneに管理画面やキャッシュなどのフロントエンドを追加したもの • Lucene • Apache Projectで開発されている全文検索エンジン → 大量データの検索を速くするやつ 4 これは違います
  • 5. 「Solrで始めるSunspot入門」 じゃないの? • Railsの人にとっては、理屈よりさっさとSunspot動かす方が簡単 • その後にSolrを直接触ってみよう 5
  • 6. Sunspotを使ってみる 6
  • 7. Gemfile # これが本体 gem ‘sunspot_rails’ # 自分でSolr入れるのめんどくさい # これを入れておくとrakeコマンドでSolrを起動できる gem ‘sunspot_solr’ 7
  • 8. app/models/user.rb class User < ActiveRecord::Base searchable do text :email text :fullname do “#{first_name} #{last_name}” end boolean :is_admin integer :age # 他にもdateとかlatlonとか # multiple: trueで配列も使える end end 8
  • 9. app/controllers/users_controller.rb def search @search = User.search do with(:is_admin, false) with(:age).greater_than_or_equal_to 20 fulltext “太郎” end end 9
  • 10. app/views/users/search.html.erb <% @search.results.each do |user| %> <%= user.email %> <br> <% end %> 10
  • 11. Run bundle rails g sunspot_rails install # => config/sunspot.ymlが生成されるだけ rake sunspot:solr:start rake sunspot:solr:reindex 11
  • 12. 速い? 12
  • 13. どのくらい速い? 0 2000 4000 6000 8000 10000 12000 100件 1万件 100万件 1億件 MySQL Solr 13 100件なら意味ない 1万件だと意味ある 100万件だと無いと死ぬ
  • 14. なんで速い? MySQL Where LIKE • 先頭から順番に探す • O(n) Solr • 転置インデックスで探す • 索引 • O(log n) 14
  • 15. Sunspotの動作 15
  • 16. Sunspotの動作 save ① INSERT INTO users (email, age) VALUES (‘test@example.com’, 30); rails sunspot ② POST /solr/mycore/update ここでインデックス作る Commitまですると結構重い 16
  • 17. Sunspotの動作 search ② SELECT * FROM user WHERE id IN (1,3); rails sunspot ① GET /solr/mycore/select 超速い IDがとれる 17 実際に使うデータはDBから ※Storedを使うと、①のみで終わらせることもできる
  • 18. About Solr 18
  • 19. Solr • Web API • Web管理画面 • Javaサーブレットコンテナで動く • dist/solr-4.4.0.war • Tomcat, Jetty, … 19
  • 20. Solrのバージョン • 1.3 • マルチコア • 分散検索 • 1.4 • Javaベースレプリケーション • 3.1 • Luceneと統合されたのでバージョン飛んだ • 4.0 • 管理画面が格好良く • インデクシング高速化 • 4.4 • 現在の最新版 MANGA REBORN 1.3 この前やった某案件 4.3 20
  • 21. 3つの起動方法 • sunspot_solr • お手軽 • version 1.3 (sunspot_solr 1.3) • version 3.5 (sunspot_solr 2.0) • パッケージインストール • 管理しやすい • root必要 • version 1.4 • apache.orgからダウンロード • 自由度高い • version 4.4.0 21 schema.xmlをSunspot用に書き換える必要あり
  • 22. sunspot_solr bundle install rake sunspot:solr:start => default port: 8981(test), 8982(development), 8983(production) => config/data directory: ${RAILS_ROOT}/solr/conf ${RAILS_ROOT}/solr/data 実体はstart.jarを実行しているだけ jettyが起動する 22
  • 23. Ubuntu Package sudo apt-get install solr-tomcat sudo service tomcat6 start => default port: 8080 => config/data directory: /etc/solr/conf /var/lib/solr/data 23
  • 24. Download Archive wget ftp://ftp.riken.jp/net/apache/lucene/solr/4.4.0/solr-4.4.0.tgz tar xzf solr-4.4.0.tgz cd solr-4.4.0/example java –jar start.jar => default port: 8983 => config/data directory: solr-4.4.0/example/solr/conf solr-4.4.0/example/solr/data jettyが起動する 24
  • 25. Download Archive # 別の設定を使う java –Dsolr.solr.home=multicore –jar start.jar # 自分でちゃんとセットアップする solr-4.4.0/dist/solr-4.4.0.war 25
  • 26. 管理画面 26
  • 27. 27
  • 28. 28
  • 29. 29
  • 30. 30
  • 31. 31
  • 32. Ping ステータスチェック(nagiosに便 利) Query 検索を試せる Analysis 保存されたデータの統計 Schema Browser 動的フィールドを含め確認 32
  • 33. 検索してみる 33
  • 34. 検索してみる 34
  • 35. 検索してみる • すべてのAdminユーザを取得 • http://localhost:8983/solr/mytest/ select?q=*%3A*&fq=type%3AUser &fq=is_admin_b%3A1&wt=json&i ndent=true • q • *:* • fq • type:User • is_admin_b:1 35
  • 36. 検索してみる • 20歳未満 • q=*:* • fq=type:User • fq=age_i:{* TO 20} • 名前検索「太郎」 • q=太郎 • fq=type:User • df=fullname_text 36 Solr上ではすべてのモデルのデータがフラットに格納されている Sunspotが”type”フィールドを追加して、検索時に絞り込んでいる
  • 37. Solrの設定 37
  • 38. フォルダ構成 • solr • solr.xml • myproject1 • core.properties • conf • schema.xml • solrconfig.xml • … • data • … • myproject2 • core.properties • conf • schema.xml • solrconfig.xml • … • data • … 38
  • 39. 重要な設定ファイル • solr.xml • 全体設定 • あまり変更しない • 4.3まではここにcore一覧を定義した • schema.xml • データ型 • TokenizerやFilterもここで設定 • Sunspot用のdynamicFieldを正しく設定しないと動かないので注意 • solrconfig.xml • ログ設定 • autoCommit設定 39
  • 40. MultiCore 40 これじゃないです → 1つのサーバで複数プロジェクトのデータを扱えるようにする機 能。 • RDBMSでいう「データベース」 • コアごとに設定を変えられる
  • 41. MultiCore • 初期のSolr • プロジェクトA • production:8983, development: 8982, test: 8981 • プロジェクトB • production: 8984, development: 8985, test: 8986 • 管理めんどくさい、リソースもったいない • マルチコア • 1つのポートでOK • localhost:8983/solr/projecta-production • localhost:8983/solr/projecta-development • localhost:8983/solr/projecta-test • わかりやすい、省メモリ • 1個に負荷かけると他にも影響する • 本番運用は注意 41
  • 42. マルチコアのときのsunspot.yml development: solr: hostname: localhost port: 8983 path: /solr/myproject-development production: solr: hostname: localhost port: 8983 path: /solr/myproject-production 42
  • 43. coreを増やす • solr • solr.xml • mycore • core.properties • conf • schema.xml • solrconfig.xml • …. • collection1 • core.properties • conf • … cd example/solr mkdir mycore cat “name=mycore” > mycore/core.properties cp –r collection1/conf mycore/conf # dataディレクトリはコピーしない! solr 4.4未満では core.propertiesではなくsolr.xmlの<cores>に定義する 増えていなければ、管理画面のCoreAdmin→Addで登録してやる 43 フォルダコピーで増やせる
  • 44. solrconfig.xml • http://wiki.apache.org/solr/SolrConfigXml • キャッシュ設定 • ログ設定 • autoCommit設定 <autoCommit> <maxDocs>10000</maxDocs> <maxTime>1000</maxTime> </autoCommit> 明示的にcommitしなくても、10000更新または1000msごとに自動commit 44
  • 45. schema.xml <schema> <types> <fieldType name="text" class="solr.TextField" omitNorms="false"> <analyzer> <tokenizer class="solr.WhitespaceTokenizerFactory"/> <filter class="solr.StandardFilterFactory"/> <filter class="solr.LowerCaseFilterFactory"/> <filter class="solr.NGramFilterFactory" minGramSize="1" maxGramSize="1"/> </analyzer> </fieldType> <fieldType name="boolean" class="solr.BoolField" omitNorms="true"/> <fieldType name="date" class="solr.DateField" omitNorms="true"/> <fieldType name="sint" class="solr.SortableIntField" omitNorms="true"/> <fieldType name="sfloat" class="solr.SortableFloatField" omitNorms="true"/> </types> 45
  • 46. schema.xml (つづき) <fields> <field name="id" stored="true" type="string" multiValued="false" indexed="true"/> <field name="type" stored="false" type="string" multiValued="true" indexed="true"/> <field name="class_name" stored="false" type="string" multiValued="false" indexed="true"/> <field name="text" stored="false" type="string" multiValued="true" indexed="true" /> <field name="lat" stored="true" type="tdouble" multiValued="false" indexed="true" /> <field name="lng" stored="true" type="tdouble" multiValued="false" indexed="true" /> <dynamicField name="*_text" stored="false" type="text" multiValued="true" indexed="true"/> <dynamicField name="*_texts" stored="true" type="text" multiValued="true" indexed="true"/> <dynamicField name="*_b" stored="false" type="boolean" multiValued="false" indexed="true"/> <dynamicField name="*_bm" stored="false" type="boolean" multiValued="true" indexed="true"/> <dynamicField name="*_bs" stored="true" type="boolean" multiValued="false" indexed="true"/> <dynamicField name="*_bms" stored="true" type="boolean" multiValued="true" indexed="true"/> <dynamicField name="*_i" stored="false" type="sint" multiValued="false" indexed="true"/> </fields> 46
  • 47. schema.xml (つづき) <uniqueKey>id</uniqueKey> <defaultSearchField>text</defaultSearchField> <solrQueryParser defaultOperator="AND"/> </schema> 47
  • 48. schema.xml • tokenizerを設定できる • KeywordTokenizer • 文字列を分割しない • LetterTokenizer • 非文字で分割 • WhitespaceTokenizer • 空白文字で分割 • StandardTokenizer • UAX#29に従って分割 • UAX29URLEmailTokenizer • URLやemailを認識 • JapaneseTokenizer • 日本語を分かち書き 48
  • 49. schema.xml • filterを設定できる • LowerCaseFilter • 大文字を小文字に • TrimFilter • 前後の空白を除去 • StopFilter • ストップワードを除去 • EdgeNGramTokenFilter • 指定文字数のN-Gramを生成 • JapaneseBaseFormFilter • 「走れ」を「走る」のように基本形に変換 • JapaneseReadingFormFilter • 「日本」を「ニホン」のように読みに変換 49
  • 50. dynamicField • フィールドを事前に定義しなくても、dynamicFieldの定義に一致 すれば自動的に作ってくれる • Sunspotが大量に定義 • 自前SolrでSunspotを運用するときは、dynamicFieldの整合性が保たれて いることが必須 • デフォルトのexampleにあるものとは衝突するので注意 • *_dはdate?double? • これがないと、検索対象フィールド増やすたびにschema.xmlの 変更が必要になる 50
  • 51. Sunspot Note 51
  • 52. index系メソッド • @user.solr_index • このユーザのsolr indexを更新 • after_saveで自動で呼ばれるが、関連テーブルは手動で呼んでやる必要がある • User.solr_index • 全ユーザのsolr indexを更新 • 非常に重い(データ量によっては1日で終わらない) • 検索対象(searchable)フィールドを増やしたときなど • User.solr_reindex • 全ユーザのsolr indexをいったん全削除してからindex • 検索対象(searchable)フィールドの意味を変更して互換性が失われたときなど • 処理中、検索がほとんどヒットしなくなるので注意 • rake sunspot:solr:reindex • 全モデルに対してsolr_reindex → インデックスを全部作り直す • solr_indexとindex • 単なるalias • indexとindex! • index!は、即座にSolr Commitを行う 52
  • 53. 動かない、壊れた • ERROR: unknown field “type” • schema.xmlが間違っている可能性大 • sunspot_solrのものを使う • dataディレクトリを丸ごと消してみる • 当然インデックスは全部消えます • Connection refused • Solrは起動しているか • config/sunspot.ymlのport設定は正しいか • 404 Not Found • config/sunspot.ymlのpath設定は正しいか • No field configured for User with ‘name’ • searchのコードが間違っている • 一度もindexされていない • 全然ヒットしない • reindexしてみる • 管理画面で検索してみる 53
  • 54. 更新中の検索 • dynamicFieldは、indexする際に自動的にスキーマが追加される • 一度もindexする前に検索すると • No field configuredなエラー • index処理中に検索すると • 最初の1件ですでにスキーマは生成されているので、エラーにならない • index済みのものしか検索にヒットしない • 検索するたびにヒット数が増えていく • 検索対象(searchable)フィールドを増やすとき • 順番が大事 • searchableを追加 → 最低1件indexしてスキーマ更新 → search部分デプロイ • 逆にすると検索がエラーになる • 検索対象(searchable)フィールドを減らすとき • 余分なスキーマがあっても(データ量以外)問題ない • 検索対象(searchable)フィールドの型を変更するとき • 型を変えるとSunspotが別名をつけてSolrでは別フィールドとして扱われる 54
  • 55. まとめ 55
  • 56. まとめ • Sunspotを使うとすぐにSolr検索を始められる • サーバで公開するなら最低限チェックしよう • どのSolrを使うか(sunspot_solr, パッケージ, マニュアルダウンロード) • アップデートや将来的なスケールにも影響する • バージョンが古いと一部機能が制限される • 設定ファイルはどれを使うか • 適当に選ぶとSunspotに不適切だったり検索結果で日本語がヒットしにくかったり • dataディレクトリはかなり膨らむので、ディスクスペースとIO負荷に注意 • ログはデフォルトだと非常に肥大化する • ポートは何番で、coreのパスはどうするか • この辺決めないと死活監視もアップデートもできない • 管理画面を使えるようになろう • デバッグには必須です • もっと色々調べてみよう • スケール、可用性、Tokenizer/Filter、パフォーマンスチューニング • とっても奥が深い 56

×