Cookpadの検索システムに痺れたので語りたい
この記事に感動した
TL;DR
- SolrにはSolrCloudという分散化する仕組みがあるけれどそれは使用していないと思われる
- 代わりに同じ結果を返す(同じセグメントファイルを持たせた)Solrインスタンスを複数起動してALBでバランシングしている
- オンプレ時代にSolrを使っていた私にはこの発想ができず、まさにクラウドならでは!という構成に感動した
- (歴史あるレシピ投稿サイトのトータルインデクスサイズが6GBという点にも驚いた)
SolrCloudつかっていない
Solrで検索エンジンの負荷分散したいよねーっとなると、最初に思いつくのがSolrCloudだと思います。自分もてっきりSolrCloudをつかっているのだろうと思って読んでいたのですが、ただ記事の構成を見る限りSolrCloudは使っていなさそうです。(つかっていたらごめんなさい)
SolrCloudがどんなものかは、この記事がわかりやすかったです。
Solrには分散処理・分散管理機能がなかったのですが、Hadoopによる分散処理ブームが巻き起こったり、分散に特化したElasticsearchの登場に後押しされるかたちで、SolrCloudが誕生したと記憶しています。
ただしSolrCloudはSolrを無理やり分散化させた感じがあり、初めから分散化を想定して作らたElasticsearchにくらべて初期セットアップが面倒で、サーバーの構成管理するためにzookeeperを導入しないといけないのもイマイチだった点です。
インデクスの分散管理
ログ解析ではセグメントファイルが肥大化していくため、どうしても分散構成が必要になりますが、セグメントファイルの分散管理は、WEBサービスなど実務的な検索要件と相性があまり良くありません。
たとえば10台構成で2000件の結果を取得しようとすると、10x2000=20000件の結果をマージ&ソートしなければなりません。これは、どこのノードに1件目の結果があり、どこのノードに2000件目の結果が全くあるかわからないため全ノードから上位2000を返してもらって探す必要があるためんです。2万件くらいなら力技でなんとかなりそうですが、データ量がふえて、100台、200台となるれば、メモリ不足で落ちるか、マージ&ソートを工夫するかわりにレスポンス速度を犠牲にしないといけません。
一般的に検索結果は、ユーザーが欲している情報が上位に来るはずなので、1000件目まで見る人は少数派です。なのでたいていサービスは最大件数に制限を設けているはずです。Googleの検索結果が最大上位1000件までしか取得できないのはそのためでしょう。(昔は2000件とれました)
Cookpadの構成
SolrCloudではSolrClientがロードバランサの役目をはたし、Masterノードがインデクスを更新し、Slaveノードでセグメントファイルの管理します。ノード情報はzookeeperに保存しますが、Cookpadでは以下のような構成にしてAWSをフル活用し、SolrCloudを使わず(インデクスを分散管理せずに)にスケールアウトしているようです。インデクスの分散管理による検索速度の劣化も防げるはずです。
- SolrClientのロードバランシングはAWSのALBに任せる
- Masterノード(Write)もECSで更新用のコンテナを立ち上げreindexし、成果物のセグメントファイルをS3にアップロードする
- Slaveノード(Read)はECSのコンテナ起動してS3からセグメントファイルをDLすることで、動的に減らしたり増やしたりする
- 構成管理はECSに任せる
これは全ドキュメントのセグメントファイルのサイズが6GBという点と、それをS3に高速にUL/DLできる技術力があってはじめてなしえる構成です。
ただ、オンプレ時代に検索システムを作っていた身としては、セグメントファイルはストレージに保存するもので、この発想にはいたらず、まさに青天の霹靂でした。(青天の霹靂ってことばを使いたかった)
感想
10年前は、メモリは常にたりないし、クラウド環境も充実していなかったのですが、いまやコンテナでサーバーをポンポン立てたり落としたりする時代です。
そして僕らが読み書きする文字の量は、10年たっても大して変化していませんが、メモリのサイズも各段に増え、しかも値段も安くなっています。これはつまりメモリサイズが人間のI/O量を追い越したということかもしれません。
今後、アクティブユーザー数が多いサービスの実務向けの検索システムは、今回紹介された構成が主流の一つになるなと感心しました。
すごいすごい。ひびさに痺れてしまったので勢いで書きました。
Discussion