データの各コレクションはセグメントに分割されます。それぞれのセグメントには独立したベクトルの保存領域、ペイロードの保存領域、およびインデックスがあります。

通常、セグメント内のデータは重複しません。ただし、異なるセグメント内で同じポイントを保存しても問題は発生しません。なぜなら、検索には重複排除メカニズムが含まれているためです。

セグメントには、ベクトルの保存領域、ペイロードの保存領域、ベクトルのインデックス、ペイロードのインデックス、および内部と外部のIDの関係を保存するためのIDマッパーが含まれています。

セグメントは、「追加可能」または「追加不可能」のいずれかに分類されます。これは使用される保存領域やインデックスの種類によって異なります。「追加可能」セグメントでは、データの追加、削除、およびクエリを自由に行うことができますが、「追加不可能」セグメントではデータの読み取りと削除のみが可能です。

コレクション内のセグメントの構成は異なることができ、互いに独立していますが、少なくとも1つの「追加可能」セグメントが必要です。

ベクトルの保存領域

アプリケーションのニーズに応じて、Qdrantは以下のデータ保存オプションのいずれかを使用することができます。選択は検索速度とRAM使用量のバランスを取る必要があります。

メモリ保存 - すべてのベクトルをRAMに保存し、パフォーマンスが最も高いです。ディスクへのアクセスが持続性中にのみ必要です。

メモリマップ保存 - ディスク上のファイルに関連付けられた仮想アドレス空間を作成します。マップされたファイルは直接RAMにロードされず、ページキャッシュを使用してアクセスされます。この方法により、利用可能なメモリを柔軟に使用することができます。十分なRAMがあれば、その速度はほぼメモリ保存と同じくらい速くなります。

メモリマップ保存の構成

メモリマップ(またはディスク上の保存)の使用は、次の2つの方法で構成することができます。

  • コレクションの作成APIでベクトルのon_diskオプションを設定します。

バージョンv1.2.0以降適用

PUT /collections/{collection_name}

{
    "vectors": {
      "size": 768,
      "distance": "Cosine",
      "on_disk": true
    }
}

これにより、すべてのベクトルが即座にメモリマップ保存されるコレクションが作成されます。これは、Qdrantインスタンスが高速なディスクを使用し、大規模なコレクションを処理する必要がある場合に推奨されるアプローチです。

  • memmap_threshold_kbオプションを設定します。このオプションは、セグメントをメモリマップ保存に変換するための閾値を設定します。

以下の2つの方法で実装することができます。

  1. 構成ファイルで閾値をグローバルに設定します。パラメータ名はmemmap_threshold_kbです。
  2. 作成または更新中に各コレクションごとに閾値を個別に設定します。
PUT /collections/{collection_name}

{
    "vectors": {
      "size": 768,
      "distance": "Cosine"
    },
    "optimizers_config": {
        "memmap_threshold": 20000
    }
}

メモリマップの閾値パラメータを設定するための基本的なルールは以下の通りです。

  • シナリオのバランスが取れている場合、memmap_thresholdindexing_thresholdと同じに設定します(デフォルトは20000)。この場合、オプティマイザは追加の実行を行わず、すべての閾値を一度に最適化します。
  • 書き込み負荷が高く、RAMが少ない場合、memmap_thresholdindexing_thresholdよりも低く設定します。例えば、10000です。この場合、オプティマイザはまずセグメントをメモリマップ保存に変換し、次にインデックスを適用します。

さらに、ベクトルだけでなく、HNSWインデックスに対してもメモリマップ保存を使用することができます。この機能を有効にするには、コレクションを作成する際にhnsw_config.on_diskパラメータをtrueに設定します。

PUT /collections/{collection_name}

{
    "vectors": {
      "size": 768,
      "distance": "Cosine"
    },
    "optimizers_config": {
        "memmap_threshold": 20000
    },
    "hnsw_config": {
        "on_disk": true
    }
}

ペイロードストレージ

Qdrantは2種類のペイロードストレージをサポートしています: InMemory および OnDisk。

InMemory ペイロードストレージは、ペイロードデータをインメモリベクトルと同様に整理します。サービス起動時にペイロードデータがメモリにロードされ、ディスクとRocksDBは永続化のみに使用されます。このタイプのストレージは非常に高速ですが、テキストの要約や画像などの大きな値を含むペイロードを格納するために大量のメモリスペースが必要になる可能性があります。

大きなペイロード値の場合は、OnDisk ペイロードストレージを使用することを推奨します。このタイプのストレージは、ペイロードを直接RocksDBに読み書きし、ストレージに大量のメモリが必要ないという利点があります。ただし、アクセスの待ち時間が欠点です。ペイロード条件に基づいてベクトルをクエリする必要がある場合は、ディスク上に格納されている値を確認すると時間がかかる可能性があります。この場合は、ディスクアクセスを避けるために、フィルタリング条件に使用される各フィールドのためにペイロードインデックスを作成することをお勧めします。フィールドインデックスが作成されると、Qdrantはインデックス化されたフィールドのすべての値をペイロードストレージの種類に関係なく常にメモリに保持します。

コレクションを作成する際に、構成ファイルを使用するか、on_disk_payloadコレクションパラメータを使用して、希望のペイロードストレージタイプを指定できます。

バージョン管理

データの整合性を確保するために、Qdrantはすべてのデータ変更を2段階で行います。まず、データはWrite-ahead-log(WAL)に書き込まれ、すべての操作に順序付けられた連続した番号が割り当てられます。

変更がWALに追加されると、電源が落ちた場合でも失われることはありません。その後、変更はセグメントに入ります。各セグメントは、それに適用された変更の最新バージョンと、個々のポイントのバージョンを保存します。新しい変更の連続番号がポイントの現在のバージョンよりも小さい場合、アップデータはその変更を無視します。このメカニズムにより、Qdrantは異常なシャットダウンの場合に効率的にWALからストレージを回復することができます。