データ処理
本記事では、Milvusにおけるデータ挿入、インデックス構築、データクエリの実装について詳細に説明する。
データ挿入
Milvusでは、各コレクションに対してシャードの数を指定することができ、各シャードは仮想チャネル(vchannel)に対応しています。次の図が示すように、Milvusはログブローカ内の各vchannelに物理チャネル(pchannel)を割り当てます。受信した挿入/削除リクエストは、プライマリキーのハッシュ値に基づいてシャードにルーティングされます。
Milvusは複雑なトランザクションを持たないため、DMLリクエストの検証はプロキシに移される。プロキシはTSO(Timestamp Oracle)に各挿入/削除リクエストのタイムスタンプを要求する。古いタイムスタンプは新しいタイムスタンプで上書きされるため、タイムスタンプは処理されるデータ要求の順序を決定するために使用される。プロキシは、全体のスループットを向上させ、中央ノードに過度の負担をかけないように、エンティティのセグメントとプライマリキーを含むデータコーデイネータからバッチで情報を取得する。
チャネル1
DML(データ操作言語)操作とDDL(データ定義言語)操作の両方がログシーケンスに書き込まれますが、DDL操作は発生頻度が低いため、1つのチャネルしか割り当てられていません。
チャンネル2
Vチャンネルは、基礎となるログブローカーノードで管理されます。各チャンネルは物理的に不可分であり、どのノードでも利用可能ですが、1つのノードでのみ利用可能です。データ取り込み速度がボトルネックに達した場合、2つのことを考慮する:ログブローカノードが過負荷でスケーリングが必要かどうか、各ノードのロードバランスを確保するのに十分なシャードがあるかどうか。
ログの書き込みシーケンス
プロキシ、ログブローカー、データノード、オブジェクトストレージ。このプロセスには、DML要求の検証、ログシーケンスの公開-購読、ストリーミングログからログスナップショットへの変換、ログスナップショットの永続化という4つのタスクが含まれる。各タスクが対応するノードタイプによって処理されるように、4つのタスクは互いに切り離されている。同じタイプのノードは同等に作られ、様々なデータ負荷、特に大量で変動が激しいストリーミングデータに対応するために、弾力的かつ独立にスケールすることができる。
インデックス構築
インデックス構築はインデックスノードによって行われる。データ更新のための頻繁なインデックス構築を避けるため、Milvusのコレクションはさらにセグメントに分割され、それぞれが独自のインデックスを持つ。
インデックス構築
Milvusは各ベクトルフィールド、スカラーフィールド、プライマリフィールドのインデックス構築をサポートします。インデックス構築の入力と出力の両方がオブジェクトストレージに関与します:インデックスノードは(オブジェクトストレージにある)セグメントからメモリにインデックスを作成するログのスナップショットをロードし、インデックスを作成するために対応するデータとメタデータをデシリアライズし、インデックス作成が完了するとインデックスをシリアライズし、オブジェクトストレージに書き戻します。
インデックス構築は主にベクトルと行列の演算を伴うため、計算量とメモリ使用量が多くなります。ベクトルは、その高次元の性質から、伝統的なツリーベースのインデックスでは効率的にインデックスを作成することができませんが、クラスタベースやグラフベースのインデックスなど、この分野でより成熟した技術を使用することで、インデックスを作成することができます。その種類にかかわらず、インデックスの構築には、Kmeansやグラフトラバースなど、大規模なベクトルに対する大規模な反復計算が必要となる。
スカラーデータのインデックスとは異なり、ベクトルインデックスの構築にはSIMD(単一命令、複数データ)アクセラレーションをフルに活用する必要があります。Milvusは、SSE、AVX2、AVX512などのSIMD命令セットを生得的にサポートしている。Milvusは、SSE、AVX2、AVX512などのSIMD命令セットを生得的にサポートしています。ベクトルインデックス構築の「しゃっくり」とリソース集約的な性質を考えると、Milvusにとって弾力性は経済的に極めて重要になります。Milvusの今後のリリースでは、ヘテロジニアス・コンピューティングとサーバーレス計算をさらに追求し、関連コストを下げる予定である。
Milvusはスカラーフィルタリングとプライマリフィールドクエリもサポートしている。Milvusには、ブルームフィルターインデックス、ハッシュインデックス、ツリーベースインデックス、転置インデックスなど、クエリの効率を向上させるためのインデックスが組み込まれており、ビットマップインデックスやラフインデックスなど、より多くの外部インデックスを導入する予定である。
データクエリー
データクエリとは、対象となるベクトルに最も近いk個のベクトル、または指定された距離範囲内のすべてのベクトルについて、指定されたコレクションを検索するプロセスを指す。ベクトルは、対応する主キーとフィールドとともに返されます。
データクエリ
Milvusのコレクションは複数のセグメントに分割され、クエリノードはセグメントごとにインデックスをロードします。検索要求が到着すると、同時検索のためにすべてのクエリノードにブロードキャストされる。その後、各ノードはローカルセグメントを刈り込み、条件を満たすベクトルを検索し、検索結果を縮小して返します。
クエリノードはデータクエリにおいて互いに独立している。各ノードは2つのタスクのみを担当する:クエリコーダーの指示に従ってセグメントをロードまたは解放する。そしてプロキシは、各クエリノードからの検索結果を削減し、最終結果をクライアントに返す責任を負う。
ハンドオフ
セグメントには、成長するセグメント(増分データ用)と、封印されたセグメント(履歴データ用)の 2 種類がある。クエリノードは vchannel を購読し、最近の更新(増分データ)を growing セグメントとして受信する。成長中のセグメントが事前に定義されたしきい値に達すると、データコーデックはそのセグメントを封印し、インデックスの構築を開始する。その後、クエリーコーデ ィネートによって開始されるハンドオフ操作によって、増分データが履歴データに変換される。クエリコーデックは、メモリ使用量、CPUオーバーヘッド、セグメント数に応じて、封印されたセグメントをすべてのクエリノードに均等に分配する。
次のページ
- Milvusベクトルデータベースをリアルタイムクエリに使用する方法について学ぶ。
- Milvusにおけるデータ挿入とデータ永続化について学びます。
- Milvusでのデータ処理方法について学びます。