Link
Embed
Share
Beginning
This slide
Copy link URL
Copy link URL
Copy iframe embed code
Copy iframe embed code
Copy javascript embed code
Copy javascript embed code
Share
Tweet
Share
Tweet
Slide 1
Slide 1 text
elasticsearchで ランキングを作ろう iwag 2016/06/27 elasticsearch勉強会 #16
Slide 2
Slide 2 text
誰よ ● iwag ● Scala/finagler/elasticsearch
Slide 3
Slide 3 text
スクリプト ● 検索、更新、取得時にスクリプト(groovy 等) でな んでもできる ● Scripting ● 言語:groovyなど ○ Ruby っぽい ○ 他にも lucence script, native(Java) ○ import して Java の関数呼んだりできる
Slide 4
Slide 4 text
更新 ● insert, update ○ リンク ● ドキュメントの値(ctx._source) を読み書き加工
Slide 5
Slide 5 text
検索 ● スコア計算 ○ ドキュメントの値を読んでスコアを算出する ● スクリプト付きフィルタ ● 値の取得(スクリプトフィールド) ○
Slide 6
Slide 6 text
ランキング
Slide 7
Slide 7 text
ランキングとは ● 現在時刻から24時間のお気に入り増減数の順 ● 1時間ごとに更新
Slide 8
Slide 8 text
作り方:例 ● apache ログを時間で aggregation ○ 重い… ● バッチで1時間ごとに計算 ○ 秘伝の技術になりがち ● 1時間ごとの増減値(配列)をドキュメントに持たせ る (今日のお話) ●
Slide 9
Slide 9 text
データ構造 ● お気に入り数の配列とその時刻(時)の配列 time_array: [ 160624T16, 160624T15, 160624T10, 160624T08 ... ] fav_array: [160624T16's fav数, 160624T15's fav数, 160624T10's fav数, …, 160624T08's fav数, ... ]
Slide 10
Slide 10 text
スクリプトと検索クエリ fav_array=doc['fav_array'].values; time_array=doc['time_array'].values; // from, to はパラメータで来ます。 from〜to to = new DateTime().getMillis; from = to - 24時間前; sum = 0; for (i=0; i
Slide 11
Slide 11 text
ヒント
Slide 12
Slide 12 text
スクリプトめっっっっちゃ重い ● フィールド >>> プラグイン(Native) >>>>>>>>>>>>> スクリプト(groovy) ● プラグイン ○ 結構簡単に作れる ○ 更新に再起動がいるので今回は断念
Slide 13
Slide 13 text
フィルタを使ってスクリプト実行を減らす ● デフォルト ○ 全ドキュメントに対して スクリプトが実行され る→重い ● フィルタ ○ script_scoreにはフィ ルタを付けれる ○ フィルタされた要素だ けスクリプトを実行す "fuction_score":{ "functions":{ "filter":{ "exists":"fav_array" }, "script_score":{ "script":"fav_array=doc['fav_array'].values; ... " } } }
Slide 14
Slide 14 text
スクリプト中では絶対 doc を使う ● doc は fielddata 、ヒープにキャッシュされる ○ 設定で制御できるらしいがデフォルトで使っている ● _fields, _source も使えるがインデックスから読ん でくるので遅い ○ ドキュメントでも使うなって言ってる ● ただ doc は制限多い ○ オブジェクトが使えない、number or string のみ
Slide 15
Slide 15 text
更新
Slide 16
Slide 16 text
前提 ● クリック時にスクリプト付き(+1) updateが飛ぶ
Slide 17
Slide 17 text
更新のスクリプト if(ctx._source['fav_array']==null || ctx._source['time_array']) = ... now = new DateTime().getMillis()/3600; if (ctx._source.time_array[0] == now) { ctx._source.fav_array[0] += 1; } else { ctx._source.time_array.add(0, now); ctx._source.fav_array[0].add(0, 1); }
Slide 18
Slide 18 text
ヒント
Slide 19
Slide 19 text
コンフリクトを気にしない ● ESはドキュメント単位でのロック ● 正直大雑把だけどめちゃくちゃ楽… ● コンフリクトした場合→ retry ● バズった時大変なことにならないのか? ○ ESへのメッセージはすべてその前にキューで直列化して いるのでほぼコンフリクトは発生しない ○ 遅延は発生するが。。。
Slide 20
Slide 20 text
パフォーマンス ● 更新時のスクリプトはパフォーマンスを気にしなく て良い ○ せいぜい更新1回 ● スクリプトの計算よりインデックスへのストアのほ うが重い
Slide 21
Slide 21 text
古いデータどうするのか? ● バッチで48時間以上前のデータは消している ● クエリ付き update があるとうれしいなという要望
Slide 22
Slide 22 text
デバッグどうするのか ● スクリプトでloggerが使える ○ https://www.elastic.co/blog/elasticsearch-logging-secrets ● デバッグ用フィールド ○ スクリプト中で ctx._source.debug = “....”;
Slide 23
Slide 23 text
まとめ
Slide 24
Slide 24 text
まとめ ● elasticsearch のスクリプトの話をしました ● ランキングの作り方を紹介しました ● スクリプトを活用する上でのヒントを紹介しました
Slide 25
Slide 25 text
おまけ
Slide 26
Slide 26 text
ホットエントリ(みたいなもの) もつくれます ● スクリプト付きフィルタを使う ● 例 ○ 直近1時間のお気入り数が10以上でフィルタ ○ 適当に並べる ● あってるかは不明…