1. ドキュメント追加時の内部処理
1.1 ZooKeeperウォッチャーの登録
SolrCloud環境では、クライアントがCloudSolrServer経由でドキュメントを追加または更新する際、まずZooKeeperからクラスタ状態(/clusterstate.jsonおよび/live_nodes)を取得し、これらのノードにウォッチャーを登録する。
この仕組みにより以下が実現される:
- リーダー(Leader)ノードを直接特定し、中継なしでリクエストを送信可能になるため、ネットワークオーバーヘッドが削減される。
- リーダーの障害や切り替わりを即座に検知し、無効なノードへの送信を回避できる。
1.2 ドキュメントのルーティング
SolrCloudは、各ドキュメントを適切なシャード(Shard)に振り分けるためにルーティング機構を用いる。この処理は、ドキュメントのハッシュ値に基づいて対応するシャードのハッシュ範囲とマッチングさせることで行われる。
1.2.1 ルーティングアルゴリズムの種類
コレクション作成時にrouter.nameパラメータで指定可能なルーティング方式は以下の2種類:
- compositeId(デフォルト):
- 一貫性ハッシュ(consistent hashing)を採用し、ハッシュ空間は
0x80000000~0x7fffffff。 numShardsを事前に固定する必要があり、後からのシャード数変更は非推奨(データ検索不能リスクあり)。- ドキュメントが均等に分散される。
- 一貫性ハッシュ(consistent hashing)を採用し、ハッシュ空間は
- implicit:
- ドキュメントごとに明示的にシャードを指定可能(例:
_route_フィールドでshard1など)。 - 負荷の均等分散は保証されないが、動的なシャード追加・削除が可能。
- ドキュメントごとに明示的にシャードを指定可能(例:
1.2.2 ルーティング実装クラス
ルーティングの基底クラスはDocRouterで、標準実装としてCompositeIdRouterとImplicitDocRouterが提供されている。独自ルーティングロジックが必要な場合は、このクラスを継承して実装できる。
1.2.3 implicitルーティングの利用方法
ドキュメントに_route_フィールドを含めてシャード名を指定する:
doc.addField("_route_", "shard2");
また、コレクション作成時のURL例:
http://host:8983/solr/admin/collections?action=CREATE&name=mycoll&router.name=implicit&shards=shard1,shard2
スキーマ定義には以下を追加する必要がある:
<field name="_route_" type="string" indexed="true" stored="false"/>
1.2.4 ハッシュ値の要件
ルーティングに使用されるハッシュ関数は以下の条件を満たす必要がある:
- 高速に計算できること(スケーラビリティのため)。
- シャード間で均等に分散されること(遅延のボトルネックを防ぐため)。
SolrはLuceneの実装としてMurmurHashを採用しており、高速かつ均一な分布特性を持つ。
2. インデックス追加フロー
ドキュメント追加リクエストは以下のステップで処理される:
- クライアントが任意のレプリカ(LeaderまたはReplica)にリクエストを送信。
- 受信ノードがLeaderでない場合、同一シャード内のLeaderに転送。
- Leaderがドキュメントのルーティング先を判定:
- 自シャードに属する場合:全レプリカに並列で転送。
- 他シャードに属する場合:該当シャードのLeaderに転送。
- 最終的な宛先シャードのLeaderが、そのシャード内の全レプリカにドキュメントを配信し、インデックス化を完了。
バッチ処理時は、複数ドキュメントを宛先シャードごとにグルーピングし、並列送信することで効率化している。
3. インデックス更新フロー
- Leaderは更新リクエストを受け取ると、まず
update log (ulog)に記録し、ドキュメントに新しいバージョン番号を付与。古いバージョンの更新は破棄される。 - 更新されたドキュメントは、オンライン状態の全レプリカに並列で送信される。オフライン中のレプリカは後続のRecoveryプロセスで同期される。
- Leaderは全アクティブレプリカからの成功応答を待って、クライアントに成功レスポンスを返す。
- コミット方式には2種類ある:
- softCommit:メモリ上にセグメントを生成し、即時検索可能だが、耐障害性は低い。
- hardCommit:ディスクへの永続化後に検索可能となり、データ安全性が高い。
注:シャード内にアクティブなレプリカが1つでも存在すれば、Solrは書き込みを許可する(可用性優先)。ただし、leaderVoteWait期間中にLeaderが復帰しない場合、単一レプリカが新Leaderとなる可能性があり、一部データ損失リスクがある。これを避けるには、過半数(majority quorum)に基づく書き込み承認戦略が推奨される。
4. インデックス操作のまとめ
4.1 Leaderの転送ルール
- Leader経由のリクエスト:ローカルulogに記録し、他のレプリカへの転送は不要。
- 自分自身がLeaderで、直接リクエストを受けた場合:ローカルに書き込み、全レプリカに転送。
- 非Leaderが直接リクエストを受けた場合:ローカルulogに記録し、Leaderに転送。
- 各コミット時にulogがローテーションされ、障害発生時にはこのログからデータを復元可能。
4.2 効率的な運用のための推奨事項
CloudSolrServerを使用して、クライアント側でLeaderを直接ターゲットにする。- 大量ドキュメントの追加時は、クライアント側で事前にルーティングを行い、SolrCloud内部でのルーティング処理コストを削減する。