データ処理
本記事では、Milvusにおけるデータ挿入、インデックス構築、データクエリの実装について詳細に説明する。
データ挿入
Milvusではコレクションが使用するシャードの数を選択することができ、各シャードは仮想チャネル(vchannel)にマッピングされます。下図のように、Milvusはすべてのvchannelを物理チャネル(pchannel)に割り当て、各pchannelは特定のStreaming Nodeにバインドされます。
Vチャネル PCチャネルとStreamingNode
データ検証の後、プロキシは書き込まれたメッセージを、指定されたシャードルーティングルールに従って、さまざまなデータパッケージのシャードに分割する。
チャネル1
そして、1つのシャード(vchannel)の書き込まれたデータは、pchannelの対応するStreaming Nodeに送信される。
書き込みフロー
Streaming Nodeは各データパケットにタイムスタンプオラクル(TSO)を割り当て、操作の全順序を確立する。ペイロードをライトアヘッド・ログ(WAL)に書き込む前に、ペイロードの一貫性チェックを行う。いったんデータがWALに永続的にコミットされると、それが失われないことが保証される。たとえクラッシュが発生しても、Streaming NodeはWALを再生して、保留中のオペレーションをすべて完全に回復することができる。
一方、StreamingNodeはコミットされたWALエントリを非同期に個別のセグメントに切り分けます。セグメントには2種類ある:
- Growing segment: オブジェクトストレージにプリステートされていないデータ。
- Sealed segment: すべてのデータがオブジェクトストレージに永続化されている。
成長セグメントから密封セグメントへの移行はフラッシュと呼ばれます。Streaming Node は、そのセグメントで利用可能なすべての WAL エントリを取り込み、書き込むとすぐに、つまり、ライトアヘッドログに保留中のレコードがなくなるとすぐに、フラッシュをトリガーする。
インデックスの構築
インデックス構築はデータノードによって実行される。データ更新のための頻繁なインデックス構築を避けるため、Milvusのコレクションはさらにセグメントに分割され、それぞれが独自のインデックスを持つ。
インデックス構築
Milvusは各ベクトルフィールド、スカラーフィールド、プライマリフィールドのインデックス構築をサポートしています。インデックス構築の入力と出力の両方がオブジェクトストレージに関与します:データノードはセグメント(オブジェクトストレージにある)からインデックスを作成するログのスナップショットをメモリにロードし、対応するデータとメタデータをデシリアライズしてインデックスを作成し、インデックス作成が完了するとインデックスをシリアライズしてオブジェクトストレージに書き戻します。
インデックス構築は主にベクトルと行列の演算を伴うため、計算とメモリに負荷がかかります。ベクトルは、その高次元の性質から、伝統的なツリーベースのインデックスでは効率的にインデックスを作成することができませんが、クラスタベースやグラフベースのインデックスなど、この分野でより成熟した技術を使用することで、インデックスを作成することができます。その種類にかかわらず、インデックスの構築には、Kmeansやグラフトラバースなど、大規模なベクトルに対する大規模な反復計算が必要となる。
スカラーデータのインデックスとは異なり、ベクトルインデックスの構築にはSIMD(単一命令、複数データ)アクセラレーションをフルに活用する必要があります。Milvusは、SSE、AVX2、AVX512などのSIMD命令セットを生得的にサポートしている。Milvusは、SSE、AVX2、AVX512などのSIMD命令セットを生得的にサポートしています。ベクトル・インデックス構築の "しゃっくり "とリソース集約的な性質を考えると、Milvusにとって弾力性は経済的に極めて重要になります。Milvusの今後のリリースでは、ヘテロジニアス・コンピューティングとサーバーレス計算をさらに追求し、関連コストを下げる予定である。
Milvusはスカラーフィルタリングとプライマリフィールドクエリもサポートしている。Milvusには、ブルームフィルターインデックス、ハッシュインデックス、ツリーベースインデックス、転置インデックスなど、クエリの効率を向上させるためのインデックスが組み込まれており、ビットマップインデックスやラフインデックスなど、より多くの外部インデックスを導入する予定である。
データクエリー
データクエリとは、対象となるベクトルに最も近いk個のベクトル、または指定された距離範囲内のすべてのベクトルについて、指定されたコレクションを検索するプロセスを指す。ベクトルは、対応する主キーとフィールドとともに返されます。
データクエリ
Milvusのコレクションは複数のセグメントに分割されます。ストリーミングノードは成長しているセグメントをロードし、リアルタイムのデータを維持し、クエリノードは封印されたセグメントをロードします。
クエリ/検索リクエストが到着すると、プロキシは関連シャードを担当するすべての Streaming Node にリクエストをブロードキャストし、同時検索を行います。
クエリーリクエストが到着すると、プロキシは対応するシャードを保持する Streaming Node に検索を実行するよう同時にリクエストする。
各Streaming Nodeはクエリプランを生成し、そのローカルで成長しているデータを検索し、同時にリモートのQuery Nodeにコンタクトして過去の結果を取得し、それらを1つのシャードの結果に集約する。
最後に、プロキシはすべてのシャード結果を収集し、最終結果にマージしてクライアントに返す。
ハンドオフ
Streaming Node上の成長中のセグメントが密封されたセグメントにフラッシュされるとき、 またはData Nodeがコンパクションを完了するとき、Coordinatorはハンドオフ操作を開始し、 成長中のデータを履歴データに変換します。その後、Coordinator は封印されたセグメントをすべての Query Node に均等に分散し、メモリ使用量、CPU オーバーヘッド、セグメント数のバランスをとり、冗長なセグメントを解放します。
次のページ
- Milvusベクトルデータベースをリアルタイムクエリに使用する方法について学びます。
- Milvusにおけるデータ挿入とデータ永続化について学びます。
- Milvusでのデータ処理方法について学びます。