さようならElasticsearch、よろしくElastic Cloud
2022/5/19 20:25 - 20:40
(明らかに15分で収まる内容の資料ではないですが、資料はモリモリで発表はスカスカでもScrapboxで盛り上がれるか、という仮説の検証を兼ねています)
yuisekiですyuiseki.icon
Gyazoのプロジェクトマネージャー兼ソフトウェアエンジニアです
本日お集まりいただいたみなさん、ありがとうございます
https://gyazo.com/503119ac54a9b908e4f54a683279133c
本日お集まりいただいたみなさん
12年間運用を続けているB2C SaaSの検索インフラの実態(14分まで、1分間) 一応動いてるんだけどなんで動いてるのか誰もわかっていない状態
新しい検索の機能追加やアイデアを試行錯誤したいけど、変更方法が不明のため、諦める
いやそれはダメでしょということで、検索インフラ刷新を検討し、いろいろと模索はしていた
偉業👏👏👏akix.icon
検索インフラ移行のゴール(13分まで、1分間)
これまで通りのことができるようにする
高速な検索
オンデマンドなindexing
無料ユーザーの画像は検索を試そうとした時だけindexingすることでコスト節約
追加で実現したいこと
正確な検索
index mappingsを再定義・再構築できるようにする
移行におけるダウンタイムはゼロ
謎のロストテクノロジーにしない
これ全部話すと一時間になるので面白い話とお得な話だけします
やったー!akix.icon
概要を聞いてるだけでもすごく大変な作業をしたというのが伝わるMijinko_SD.icon
失敗から学ぶElastic Cloud(10分まで、3分間) Elastic Cloudに移行しようとしていた間、ハチャメチャに失敗していました
(科学においても、工学においても、医学においても、経営・事業においても、政治においても、etc)
Anyone who has never made a mistake has never tried anything new.
まず落ちるテストを書く=まず失敗する
とはいえガンガンシステム壊しちゃいました!では困る
ググったらCFOがいる企業は実在する模様
最高財務責任者(Chief Financial Officer)では
おもしろいakix.icontakeru.icon
「失敗に関する本も読んでいる」
ここでNotaの本の購買支援(?)が生きるのかMijinko_SD.icon
影響範囲が限定されている
すばやく失敗前の状態に戻せる
発生条件がコントロールされている
失敗から得た情報を元に再発を防止し、さらに改善できる コスパの良い失敗?yosider.icon
Gyazoユーザーが検索できなくなってしまいましたみたいな事態は絶対に避ける
Elastic Cloudに立ち上げたクラスタへ、旧Elasticsearchクラスタと同じリクエストを送って、負荷に耐えられるか検証 失敗:index mappings更新時にハチャメチャに負荷が跳ね上がってしまう
最高に過酷だった時
CPU Usage 200%超え!
Search Response Times 60k ms超え!
キロミリセック熱いmtane0412.icon
Index Response Times 60k ms超え!
https://gyazo.com/b5854840832f851c840ffe0f354918e0
だいぶ過酷だった時
CPU Usage 100%超え!
Search Respones Times 10k ms超え!
https://gyazo.com/e3ab80d825c59552afba3198035769e3
Elastic Cloudにこれよりも負荷かけたことあるぞという人がいたら是非ご連絡ください
失敗その1(9分30秒まで、30秒間)
仮説:number_of_shardsを増やせば増やすほど速くなるのでは
結果:そんなことはない。小さいshardsを増やすと最高に過酷になる(後述)
失敗その2(9分まで、30秒間)
?refresh=true
仮説:オンデマンドなindexingのためには?refresh=trueにしなければならないのでは
結果:そんなことはない。そしてずっとだいぶ過酷だったのは、おそらくこれが原因だった(後述)
複数のdata nodeでクラスタを構成する
検索indexをshardで分割して各data nodeで分散して持つ
shardはさらにreplicaごとにdata nodeに冗長化される
shardの実体はsegmentである
Luceneの概念
indexをファイルシステム上の小さいファイルとして持つ
ファイルなのか〜akix.icon
リクエスト時に何が起きるか……
searchリクエスト時
全shardでindexを検索して、結果を統合する
indexingリクエスト時
メモリ上のIndexing Bufferから、指定したタイミングで、shardごとに、ファイルシステム上のsegmentに反映する
この処理がめちゃくちゃ重いので、可能な限り先延ばししたほうが良い
Elastic Cloudにおいて、Elasticsearchクラスタは、Deploymentと呼ばれる
1つのDeploymentで、data nodeは最大でも3台まで
たいていのクラウドインフラはAZはregionごとに3つ
data node超大量に立てて負荷分散させるみたいな力技はできない
Elastic Cloudとしてはdata nodeの性能を最大限引き出して3台のクラスタでスケールインすることを推奨
小さいdata nodeを大量に立ち上げるのは実は非推奨
data nodeのCPUとメモリがElasticsearchのパフォーマンスに大きく影響するため
----- ----- ここからは index settings お得情報です ----- -----
(index settingsとは、Elasticsearchがindexをどのように扱うかというindexに関するメタ的な設定項目です)
これはありがたいakix.icon
定番テクニック(6分まで、1分間)
(公式ドキュメントに書いてある)
number_of_shardsのデフォルト値は1
number_of_shardsの値が1だと、shardの数って1つになるんですよ(進次郎構文) wakix.iconnishio.iconMijinko_SD.icontakano32.icon
data nodeが3台あっても、number_of_shardsの値が1だと、1台しか使われない
ひぇ〜〜〜〜akix.icon
なにそれこわいtetsuya-k.icon
data nodeが3台あるなら、少なくとも3に変更しないと、意味がない
shardのサイズが50GBを超えそうだったら、6, 9, 12, 15...にする
後から変更不可能なので、見積もって設計する必要がある
indexingもsearchも、shardごとに実行される
data nodeの台数が少ないのに、小さいshardsが大量にあると、処理がメッチャ遅くなる
number_of_replicasのデフォルト値は1
number_of_replicasの値が1だと、replicaの数って1つになるんですよ(進次郎構文) number_of_shardsが3でnumber_of_replicasが1だと、indexing時に6つのshardに書き込む必要がある
indexing時は0にしておくとパフォーマンスが向上する
bulk APIでindexingのリクエスト数を減らす
余談:bulk APIのリクエストボディが巨大すぎるとそれはそれでElasticsearchがご機嫌斜めになる
重要テクニック(5分まで、1分間)
(!!!公式ドキュメントに書いてない!!!)
refresh_intervalを30sとかにする
?refresh=trueのようなリクエストをするとrefresh_intervalは無視されて即座にrefreshされるので注意!
?refresh=trueというリクエストをするとrefresh_intervalは無視されて即座にrefreshされるんですよ(進次郎構文) つまりメモリ上のIndexing Bufferからファイルシステム上のsegmentへの書き込みが即座に発生する
ワォakix.icon
罠だ…Mijinko_SD.icon
一方で、テストの際には?refresh=trueにする必要がある
GyazoではCircleCI上でElasticsearchを立ち上げて実際にindexingやsearchをリクエストしてテストしている
?refresh=trueしないと、テストで30秒待つとか確率的に落ちるとかいった厳しい感じになる
index settings改善後(4分30秒まで、30秒間)
https://gyazo.com/d5c19d9aa1118dae0a0c437e9e7a6b59
Indexingリクエストが殺到していても検索レスポンスが150ms以下
👏ナイススクショwakix.icon
開発者のGyazoにこういう画像沢山眠ってそうMijinko_SD.icon
----- ----- ここからは index mappings お得情報です ----- -----
(index mappingsとは、検索対象のドキュメントを実際にどのようなデータ型とデータ構造でindexingするかという設定項目です)
検索の高速化のためのindex mappings(3分まで、1分間)
(公式ドキュメントに書いてある)
全文検索したいフィールドが多数ある場合、copy_toで一つのフィールドにぶち込んで、それのみを検索対象にすると、速くなる Elasticsearchの気持ちになって考えてみてください
たくさんのフィールドを検索するより、一つにまとめられたフィールドを検索したほうが、検索の回数が減って速いんですよ(進次郎構文) everythingフィールドを用意する(名前は何でも良い)
code:ruby
everything: {
type: 'text',
analyzer: 'ngram_analyzer',
}
ネーミング良すぎるakix.icon
全文検索したいすべてのフィールドでcopy_to: 'everything'する
code:ruby
title: {
type: 'text',
analyzer: 'ngram_analyzer',
copy_to: 'everything',
},
desc: {
type: 'text',
analyzer: 'ngram_analyzer',
copy_to: 'everything',
},
ocr: {
type: 'text',
analyzer: 'ngram_analyzer',
copy_to: 'everything',
},
everythingフィールドに対して検索すると速い
code:ruby
{
match_phrase: {
everything: term
}
}
逆にこれをやらないですべてのフィールド内の文字列を全文検索しようとするとどうなる…?
code:ruby
{
multi_match: {
query: term,
}
}
この検索クエリはElasticsearchにおいて内部的には各fieldsをそれぞれ検索して結果を結合してソートするのと変わらない
フィールド数が多い場合はこのテクニックは重要
Gyazoは様々な画像のメタデータを持っているため、この場合にあたる
Gyazoの全文検索はこれで実現されている
(公式ドキュメントに書いてある)
公式ドキュメントだいじMijinko_SD.icon
へえ両方のインデックスを使えるの熱い daiiz.icon
旧Elasticsearchでは、全て、kuromojiインデックスによる全文検索だった
実は検索できない単語があった
Elastic Cloudではn-gramインデックスで、1文字単位で全文検索できるようになった
意図しないTokenizeが行われてしまったり辞書に無い単語では検索できないという問題が解決できた
(使えるけど精度が微妙)
Elasticsearchのnested fieldsという概念を使うと、別のanalyzerによるtokenizeの結果を保持できる n-gramとは別にkuromojiのインデックスを持つことで、いいとこ取りできる
code:ruby
everything: {
type: 'text',
analyzer: 'ngram_analyzer',
fields: {
kuromoji: {
type: 'text',
analyzer: 'kuromoji_analyzer',
}
}
}
もちろんこのフィールドに対して任意の検索クエリが実行できる
code:ruby
{
more_like_this: {
like: [
{
_index: "index-name",
_id: "document-id"
}
]
}
}
まとめ(0分まで、1分間)
Elastic Cloudに移行して良かった点
Elastic Cloudでハチャメチャな失敗をしたことで、ElasticsearchやLuceneについての理解が深まってよかった
ゼロダウンタイムでElasticsearchからElastic Cloudへ移行できた
すごいakix.icon
ElasticsearchのマイナーバージョンアップはElastic Cloudで管理画面でボタンを押すだけで可能になった
Elastic Cloudで困っている点
Kuromojiの辞書を簡単にカスタマイズできない
新語に対応できない
Elastic Cloudの方と話をしたら仕様的には頑張れば辞書カスタマイズできるらしいです
追加できるカスタムプラグインの形式や容量が制限されている
(Elastic Cloudが機械学習による自然言語処理に対応したらしいけど全然大変)
/icons/いい話だ.iconakix.icon
オトク情報いっぱいあって嬉しいakix.icon
type:gif
Gif画像を検索
app:"Google Chrome"
これ「同じアプリの画像を表示」から出てくるから極秘情報ではないと思うtakker.icon
site:scrapbox.io
Scrapbox経由で貼り付けた画像を検索
title:typescript
ocr:Gyazo
camera:もある
極秘情報たすかるmtane0412.icon
NANI!?yosider.icon
なるほど、極秘情報で検索をかけるとこういった情報が出てくるのかwMijinko_SD.icon https://gyazo.com/f445820427f5379bc570c38d31bd923a
拡散しようと思ったらなんかショートカットが追加されてたmtane0412.icon
真面目な話ですが、本来は機能追加やUI変更をしたら、ちゃんとユーザーさんに何が変わったのか言わずとも気づいてもらえなければならない/あるいは言葉で伝えなければならないのですが、Gyazoは日々メッチャ改善や機能追加をしているのにそれをお伝えできていません…!極秘情報というのは半分自虐です…!!yuiseki.icon
草takker.icon
まあscrapboxもそんな感じですし
専門的な分野過ぎて伝えにくいというのもありそうMijinko_SD.icon
関連リンク
https://gyazo.com/a68a9407024069c9592c2349aa5d1b08 https://amzn.to/3lmGLRq