Elasticsearchを毎月式年遷宮している
https://scrapbox.io/files/639b5a14b87b6b001ef4f50d.png
こんにちは。最近は毎月Elasticsearchサーバーのクラスタ環境を作り直しています。shokaiですshokai.icon
ほぼ毎月式年遷宮に相当する作業を行っているという事です この記事では、実際にどうやってクラスタ環境の移行をしているのか、解説します
昨日はデザイナーのTakeru.iconさんの記事でした
ScrapboxでのElasticsearch活用
productionと同じ構成のサーバークラスタをもう1セット作るのも簡単
最初は、ページの本文を検索するだけの普通の検索でした
1年半かけて、少しずつ機能を追加していった
検索結果を下にスクロールして、検索対象を「自分が参加している全project」に広げる機能
https://gyazo.com/abf75d03590f28018fd00ef04c697140
さらに下にスクロールして、検索対象を「最近見たpublic project」に広げる機能
検索結果のソート方法に、被リンク数などを使って計算したスコアを採用した
ページタイトルだけ検索
本文を検索対象から除外
https://gyazo.com/3bf0f7ff6370cd6fd3b24dc88cef3e5b
data nodeを複数のzoneに分けて負荷分散、耐障害性もアップ
ファイル検索
Scrapboxにアップロードされたファイルの中に書かれているテキストを検索する機能
ファイル検索の対象を「画像だけ」「PDFだけ」など絞り込む機能
などなど
合計13回、Elasticsearchのindexやshardの構成を変更しました
Elasticsearchのindexへのデータ投入
Elasticsearchで検索するには
MongoDBからElasticsearchに、検索に使うテキストデータをコピーしてやる必要がある
めんどくさいけどやるしかないshokai.icon
データを投入する前に、Elasticsearchにはデータをどんな風に持ってもらうか指示する必要がある
index-templateとかshard分割とか
13回Elasticsearchを作り直した理由
検索機能を追加・変更した時にindex-templateの構造を変更する必要がある
新しいfieldを増やしたり
tokenizerを変えたり
mappingを変えたり
pluginをインストールしたり
これらの変更を行うと、MongoDBからElasticsearchへのデータ投入をやりなおさなければならない
がんばれば運用中のサーバーに対してコマンドを送って実現できる変更もあった
しかしやらなかった
新しいコードをデプロイするだけで、いい感じに新しいindexに切り替わるようにしたかった
オンプレ版Scrapboxの管理者の視点では、docker pullするだけで全てうまくいくようにしたかった
実現しましたshokai.icon
新旧2つのElasticsearch indexを同時に更新しつつ、準備できた部分から新しいindexに乗り換える
今、最新のES index versionは13です
アクティブに誰かが使っているprojectは全て13
12のprojectも存在する
11のprojectも存在する
ES index versionが空の場合
そのprojectはまだElasticsearchにデータが投入されていない
検索の準備ができていないという事
新規作成したばかりのprojectはこれshokai.icon
検索時の挙動
バージョン13のprojectで全文検索したら
バージョン13のindexで検索する
バージョン12のprojectで全文検索したら
バージョン12のindexで検索しつつ
バックグラウンドでバージョン13のindexの作成を開始する
バージョン11のprojectで全文検索したら
「検索インデックスを作成中なので後でもう一度試してください」というメッセージを表示する
誰かがそのprojectを使おうとした時、新しいindexへの移行が自動的に開始される
ページの新規作成・編集・削除は、新旧両方のindexに反映される
新しいindexがあれば、もちろんそっちを使う
新しいindexが用意できていないprojectは、とりあえず古いindexで検索する
https://gyazo.com/974f7b7d32b30a759eaeb5ae3fa1526f
新旧2つのindexを1つのESサーバー群に持たせる事もできるし、別々のサーバー群に持たせる事もできる
使用するESサーバー群をES_URIという環境変数で指定した場合
新旧のindexが1つのESサーバー群に投入される
ES_URI_V13とES_URI_V12の様に、後ろにバージョン番号を付けて指定した場合
新旧のindexが別々のESサーバー群に投入される
もし1つのESサーバー群に同居させたら?
productionの規模だと、ピークタイムのread/write数がさらに激しくなってしまう
保持するindexのサイズも一時的に2倍近くになってしまう
簡単に3 zoneでcoordinate nodeありのクラスタを作ったり捨てたりできて、本当にすごいshokai.icon
なお、負荷の低い環境では、1つのESサーバー群に複数バージョンのindexを同居させています
まとめ
すごく便利になった
サーバーのコストを削減できた
使われていないprojectのデータをElasticsearchに持たせる必要がなくなった為
新しいindexに移行できていないprojectも、とりあえず古いindexで検索して結果を返せる
2つ以上前のES index versionのまま、しばらく使われていなかったprojectだけは「今index作ってるのでまた後で試してください」を見る事になる
productionで元気良くチャレンジできる
新しいindexの実装に問題があった時も、コードをrevertすればすぐ古いindexに戻せる
今もElasticsearch初心者ですshokai.icon
色々と自由度が高くて何をどうすれば良いのか手探りでやっています
どんどんデプロイして試してダメだったら戻せるしくみを真っ先に用意した事で、学習効率が高まった
Elasticsearchにどういう設定項目が存在するのかわかってきた
Elastic cloudの管理コンソールで1からサーバーを構築する作業を13回繰り返したおかげ
Scrapboxでは、最初はMongoDBからElasticsearchへのデータ投入をbatch処理でやっていた
70時間ぐらいかかっていた
困って社内で相談したらGyazoのエンジニアの/shokai/hiroshi.iconが教えてくれました
当時、Gyazoでもindexの移行方法を試行錯誤していた
ユーザーの検索操作をトリガーとして新しいindexに移行する、などを試していた
そのアイディアを元に実装した
現在は、Gyazoにも今回の記事で紹介しているような方式が実装済みらしいですshokai.icon
余談
これを参考にしつつ、もう少し洗練させたものがHelpfeelで使われていたりと、社内では技術交流がさかんに行われています Scrapboxに技術調査をまとめていると、いつでも誰かが突撃してくる
次回のHelpfeelアドベントカレンダーは、12/19(月)にpastak.iconが書いてくれる予定です
12/23(金)の回でbalar.iconがScrapboxのファイル検索について書いてくれました