SolrはApache Foundationが管理するオープンソース検索エンジンであり、大規模なデータ処理やリアルタイム検索を実現するための強力なツールとして知られています。本記事では、Solrを用いた高スケーラビリティなクラスタ設計、性能チューニング戦略、および極限的な分類処理の実現方法について解説します。特に、大規模なレストランデータベースを運用する際の課題と解決策を焦點に、実踐的な技術的アプローチを紹介します。
本プロジェクトでは、約50萬のレストラン、5萬のブランド、4萬のメニュー、2萬の特殊プロセス、13言語をサポートする大規模なデータベースを構築しています。ピーク時(晝食・夕食)には3,000件/秒のリクエストが発生し、夜間は流量が低下します。この規模に対応するため、Solrのクラスタ設計と性能チューニングが不可欠です。
初期段階では、標準的なSolrマスター-スレーブアーキテクチャを採用しました。マスターノードは更新処理を擔當し、スレーブノードは読み取り処理を擔當しました。2時間ごとのローリングアップデートを実施し、SLAを2時間に設定しました。コスト削減の観點からAWS Spotインスタンスを活用し、EC2コストを80%削減しましたが、Spotインスタンスの回収によるネットワーク負荷の問題を解決する必要があります。
毎日3回のインクリメンタルバックアップをElastic File Storage(EFS)に保存し、新規スレーブノードの起動時にEFSからバックアップをダウンロードし、その後マスターからインクリメンタルデータを取得する方式を採用しました。これにより、マスターノードの負荷を軽減しています。
マスターノードに更新処理を集中させ、スレーブノードに読み取り処理を委譲することで、データバッファの競合を迴避しました。Solrのバッファ戦略を調整し、2時間ごとの複製を採用することで、遅延とSLAのバランスを取っています。
Graal VMを採用し、起動時間とコスト効率のバランスを取るため、さまざまなJVMのパフォーマンスをテストしました。Graal VMは起動時間の短縮とメモリ効率の向上を実現しました。
高流量環境において接続プールの設定を最適化し、リクエスト処理効率を向上させました。
動的フィールドにドック値を追加し、逆インデックスを構築することで、ファセットクエリのパフォーマンスを向上させました。
初期のインデックスサイズが50GBであり、新規ノードの起動に15分かかるため、ピーク時における流量処理に影響が出ました。この課題を解決するため、言語ごとにクラスタを分割しました。英語専用クラスタ(85%の流量)と多言語クラスタ(飲食検索)を分離し、インデックスサイズを1/3に削減しました。
元のマスターノードはOn-Demandインスタンスであり、保守作業中に予期せぬ停止が発生し、読み取り専用モードに移行してサービス中斷を引き起こしました。これを解決するため、予約スケジュールでのAMIスナップショットを活用し、マスターノードの迅速な復舊を実現しました。さらにSolr Cloudアーキテクチャを導入し、耐障害性を向上させました。
インドを4つの地域に分割し、レストランの密度に応じてシャーディングサイズを調整しました。これにより、インデックスサイズの均等化を実現しました。NRT(Near Real-Time)複製とTLog(Transaction Log)複製を組み合わせて運用しました。
NRT複製によりリーダー選挙が失敗し、新しいリーダーがインデックスバージョンの不一致により復舊モードに移行し、1時間の全システム停止を引き起こしました。これを解決するため、TLog複製とPull複製のハイブリッドアーキテクチャを採用しました。TLog複製はトランザクションログを保持し、Pull複製はリーダー選挙に參加しないように設定しました。33%のOn-Demandインスタンスと67%のSpotインスタンスでクラスタを構築し、リーダー障害時の迅速な切り替えを実現しました。
TLog複製でトランザクションログを管理し、Pull複製で読み取りを専門化することで、リーダー選挙の競合を迴避しました。Pull複製はリーダー選挙に參加しないように設定し、システム負荷を軽減しました。
リーダー障害発生時、TLog複製が即座に接続し、読み取りサービスの中斷を防ぎました。Pull複製の拡張性を制限し、突発的な流量に対応するための予算を確保しました。
NRT機能は必須ではなく、TLogとPull複製の組み合わせで高可用性を実現できます。動的フィールドのインデックスとJVMチューニングは、業務ニーズに応じてパフォーマンスとコストのバランスを取る必要があります。