MySQLユーザ視点での小さく始めるElasticsearch

13,296 views

Published on

第3回Elasticsearch勉強会での発表資料です

Published in: Technology

MySQLユーザ視点での小さく始めるElasticsearch

  1. 1. 07th Feb, 2014 MySQLユーザ視点での 小さく始めるElasticsearch Kentaro Yoshida in 第3回 Elasticsearch勉強会 page 1
  2. 2. 1. はじめに 2. 自己紹介 3. 今回のテーマ 本日の流れ 4. Yamabikoの紹介 5. 検索ことはじめ 6. Elasticsearch雑感 7. まとめ page 2
  3. 3. 1. はじめに page 3
  4. 4. こんなお悩みを抱えていませんか? page 4
  5. 5. MySQLを利用している page 5
  6. 6. だけれども、 page 6
  7. 7. 検索漏れが少ない日本語全文検索 “Kuromoji”を使いたい! Searchモード・Extendedモードが秀逸 page 7
  8. 8. つまり page 8
  9. 9. “Solr” or “Elasticsearch” が必要 page 9
  10. 10. APIをRESTfulに扱える “Elasticsearch” がアツい page 10
  11. 11. 【課題】 異種RDB間のデータ同期 page 11
  12. 12. 2. 自己紹介 page 12
  13. 13. 自己紹介 • よしけんさん • (株)リブセンス • Web系インフラの 研究開発エンジニア • Elasticsearch歴: 2013年 初夏∼ 好きなプロダクト page 13
  14. 14. お知らせ
  15. 15. 3.今回のテーマ page 16
  16. 16. 今回のテーマ 実データを用いて手軽にElasticsearchと連携した検索を行いたい Elasticsearchをスモールスタートで使い始めたい 既存プログラムの更新系処理に触れずに小さく始めたい メインRDBはMySQLではあるが、検索のみElasticsearchを使う構成 Amazon RDS for MySQLにも応用できる手離れの良い構成にしたい MySQLサーバの管理無しに冗長化構成を実現できる (Multi-AZ) page 17
  17. 17. MySQLのレコードを Elasticsearchへ同期したい page 18
  18. 18. つまり 異種RDB間のデータ同期 page 19
  19. 19. 既存製品はElasticsearch非対応 Attunity Replicate / Tungsten Replicator page 20
  20. 20. そこに... Riverプラグインを発見 page 21
  21. 21. elasticsearch-river-jdbc 概要 ElasticsearchのRiverプラグインとして動作する JDBCドライバを指定することで各種RDBからレコードを流し込める SQLを一定間隔で実行し、その結果を基に取り込みを行う 実テーブルだけでなくVIEWテーブルからも取り込める page 22
  22. 22. elasticsearch-river-jdbc 不都合な点 動作が安定せずElasticsearchサーバを再起動する必要がある しばらく動いていたがいつの間にか止まっている現象 Elasticsearchサーバ側の役割が増え、単機能ではなくなる 同期する度にElasticsearch側のドキュメントが空になる挙動 page 23
  23. 23. MySQL BinlogAPIが役立つのでは? page 24
  24. 24. 試してみたものの・・・ page 25
  25. 25. 安定稼働への道が遠く、挫折... page 26
  26. 26. そこで! page 27
  27. 27. 欲しいものが無いので作りました page 28
  28. 28. 4. Yamabiko page 29
  29. 29. Yamabiko https://github.com/y-ken/yamabiko page 30
  30. 30. Yamabiko 概要 MySQLからElasticsearchへデータを非同期に逐次反映 Amazon RDS・MariaDB・PerconaServer等の互換DBにも対応 Elasticsearchとは別の単体ミドルウェアとして動作 CentOS 6.x向けのRPMパッケージとして配布中 任意のSQL文の結果の差分から、insert/update/deleteイベントを検知 SELECT * FROM contents WHERE DATE_ADD(updated_at, INTERVAL 5 MINUTE) > NOW(); といったクエリで差分同期も可能 page 31
  31. 31. Yamabiko ユニークな特徴:delete検知が出来る PrimaryKeyのギャップ判定を行うことで実現 行が物理削除されてしまうケースでも追従可能 数十万行単位でも動作します なぜ更新ログ(BinaryLog)ではなくSQLの結果を同期するのか? JOIN無しで検索するnoSQL的概念に対応させるため 非正規化VIEWテーブルを作ることを想定 page 32
  32. 32. Yamabikoシステム構成例 mysql_replicator_multi を利用する場合 Yamabikoが使うメタデータを INSERT/SELECT 格納するためのMySQLを指定 同期情報管理テーブル 全文検索 更新/削除判定用のハッシュテーブル 同期する行数がさほど無ければ データ参照元に相乗りしても良い page 33
  33. 33. 5. 検索ことはじめ page 34
  34. 34. データ投入 かねてから無償配布されているライブドアグルメのCSVデータを利用 MySQLをGUI管理できるMacアプリ”Sequel Pro"を用いてDBへ流し込む Yamabikoを利用し、MySQLからデータの同期を始める 登録クエリ:SELECT * FROM restaurants WHERE closed = 0; 次のトピックは後ほど解説 mapping:緯度経度を扱えるgeo_point型を使うため analyzer:高機能な全文検索を扱えるKuromojiを使うため page 35
  35. 35. page 36
  36. 36. 検索クエリ curl -X POST 'http://localhost:9200/livedoor-gourmet/_search?pretty' -d '{ "query":{ "query_string":{ "query":"name:ワイン AND pref_id:13" Luceneクエリで条件指定 } いわゆるWHERE句 }, "sort" : [ 並び替え条件を指定 { "access_count" : "desc" }, ORDER BY access_count DESC ... "fan_count", "_score" ], 範囲選択 LIMIT 0, 10 "from" : 0, "size" : 10 }' page 37
  37. 37. 意外と簡単! page 38
  38. 38. 緯度経度検索 MySQLでのGeo検索はイケてないのです SPATIALインデックスを使えるのはMyISAMだけ 最近はInnoDBでGeohashを用いればある程度のことは出来る Geohashにも対応しているElasticsearchであれば、Z曲線のグループ毎に facet検索できるので、地域毎に何件ヒットしたかの検索も(多分)可能 MySQL側で緯度と経度が別カラムに格納されているテーブルを Yamabikoを使ってElasticsearchに流し込む場合には、 SELECT文に CONCAT(lat, ",", lon) AS location という列を追加し、 次ページのmapping定義をすれば緯度経度や近傍検索が出来る page 39
  39. 39. 緯度経度検索 # mapping定義を行った後にデータを流し込む $ curl -XPUT "http://localhost:9200/livedoor/restaurants/_mapping" -d ' { "restaurants" : { "properties" : { "location": { "type": "geo_point", "lat_lon": "true" } } } }' page 40
  40. 40. 緯度経度検索 # 検索例 渋谷近辺で店名に「ワイン」を含むお店を10件リストアップします $ curl -XGET "http://localhost:9200/livedoor/restaurants/_search?pretty" -d ' { "query" : { "filtered" : { "query":{ "query_string":{ "query":"name:ワイン" } }, "filter" : { "geo_distance" : { "distance" : "1km", "location" : { "lat" : 35.3924, "lon" : 139.4157 } } } } }, "from" : 0, "size" : 10 }' page 41
  41. 41. 意外と簡単! page 42
  42. 42. Mapping 個別指定したい場合には全てのフィールドを定義しなくとも、 個別指定したいカラムのみのmappingをPOSTすることでも動く indexやtypeの動的生成をする場合の注意 フィールドの型を推論してくれるのは便利だが、意図せぬ挙動を 防ぐためにも、実運用時はきちんと定義しておきたい 初回に投入されたドキュメントの内容でカラムが決まるため MySQLと違い、後でMappingの定義の変更は不可 パフォーマンス的観点からも、not_analyzedも含めて指定すると良い デフォルトではString型の文字は全てngramで分解するため page 43
  43. 43. Analyzer Kuromojiの利用方法 環境:Elasticsearch 1.0.0 RC2 RPM 注意点 次のような手順でプラグインをインストール indexを作る前に登録する必要がある(既にある場合は作り直し) プラグインを入れた後はelasticsearchを再起動する $ cd /usr/share/elasticsearch $ sudo ./bin/plugin --install elasticsearch/elasticsearch-analysis-kuromoji/2.0.0.RC1 $ sudo /etc/init.d/elasticsearch restart page 44
  44. 44. Analyzer $ curl -XPUT 'http://localhost:9200/livedoor/' -d' { "index":{ "analysis":{ "tokenizer" : { "kuromoji" : { "type" : "kuromoji_tokenizer", "mode" : "extended" } }, "analyzer" : { "analyzer" : { "type" : "custom", "tokenizer" : "kuromoji" } } } } }' page 45
  45. 45. 6. Elasticsearch雑感 page 46
  46. 46. MySQL脳から見たElasticsearch page 47
  47. 47. Elasticsearch ステキな所 MySQL同様にRPMパッケージを利用して手軽に構築できる Solrと異なり、完全RestAPIで操作できる Facet検索は大変便利 配列型はタグ検索にも大変便利 Luceneクエリは学習コストが低く直感的 複数カラムに渡る検索条件を指定しても速い MySQLと異なり1テーブル1インデックスという制約が無いため 複数のソートキーを重み付けしながら使える (boost) 緯度経度周りの検索がMySQLのそれよりも高機能である page 48
  48. 48. Elasticsearch ハマり所 Query DSLは奥が深く実に複雑なため、未だに自在に操れません... mapping定義を更新するためには、index/typeごと消す必要があること 列はinsertAPIやbulkAPIでは自動追加されないため、updateAPIを用いる noSQL的な概念の理解 GROUP BYに相当する機能は無い GitHubの Field Collapsing/Combining · Issue #256 の今後に期待 MySQLでは正規化さえしておけばSQL言語で自在に扱えるが、JOINが 出来ないElasticsearchでは厳しい。そのため、取り出したい形式に合 わせた非正規化データ構造を入念に準備する必要があること page 49
  49. 49. Elasticsearch ハマり所 noSQL故にJOIN出来ないということは、結果として各typeに同じデータ を複製された状態で持たせることになり、一貫性が失われるという懸念 mappingやデータ登録時の_parentや_childを使うと類似の事は可能 ただし、1:Nとしての紐付け、つまりLEFT JOIN的な事は不可能 こちらのページの「Parent & child」が分かりやすいのでオススメ Fun with elasticsearch's children and nested documents - Space Vatican http://www.spacevatican.org/2012/6/3/fun-with-elasticsearch-schildren-and-nested-documents/ page 50
  50. 50. 7. まとめ page 51
  51. 51. まとめ Elasticsearchの手軽さは革命的 ElasticsearchはKibanaの為だけのプロダクトではない Yamabikoを使えば、並行運用しつつスモールスタートが可能 page 52
  52. 52. お知らせ
  53. 53. お知らせ
  54. 54. Air Intern にてオフィス動画を公開中 http://airintern.com/company/detail/livesense LIVESENSE made* にてエンジニア求人掲載中 http://made.livesense.co.jp/
  55. 55. Thanks! ご清聴ありがとうございました。 page 59

×