快照

v0.8.4 版本起可用

快照是 tar 归档文件,包含特定时间点、特定节点上特定集合的数据和配置。在分布式部署中,当集群拥有多个节点时,处理单个集合必须分别为每个节点创建快照。

此功能可用于归档数据或轻松复制现有部署。对于灾难恢复,Qdrant Cloud 用户可能更倾向于使用 备份 (Backups),即对数据进行物理磁盘级的备份。

集合级快照仅包含该集合内的数据,包括集合配置、所有点 (points) 和负载 (payloads)。集合别名 (aliases) 不包含在内,可以单独迁移或恢复。

有关如何使用快照的分步指南,请参阅我们的教程

创建快照

为现有集合创建新快照

POST /collections/{collection_name}/snapshots
from qdrant_client import QdrantClient

client = QdrantClient(url="https://:6333")

client.create_snapshot(collection_name="{collection_name}")
import { QdrantClient } from "@qdrant/js-client-rest";

const client = new QdrantClient({ host: "localhost", port: 6333 });

client.createSnapshot("{collection_name}");
use qdrant_client::Qdrant;

let client = Qdrant::from_url("https://:6334").build()?;

client.create_snapshot("{collection_name}").await?;
import io.qdrant.client.QdrantClient;
import io.qdrant.client.QdrantGrpcClient;

QdrantClient client =
      new QdrantClient(QdrantGrpcClient.newBuilder("localhost", 6334, false).build());

client.createSnapshotAsync("{collection_name}").get();
using Qdrant.Client;

var client = new QdrantClient("localhost", 6334);

await client.CreateSnapshotAsync("{collection_name}");
import (
	"context"

	"github.com/qdrant/go-client/qdrant"
)

client, err := qdrant.NewClient(&qdrant.Config{
	Host: "localhost",
	Port: 6334,
})

client.CreateSnapshot(context.Background(), "{collection_name}")

这是一个同步操作,系统会生成一个 tar 归档文件并存入 snapshot_path

删除快照

v1.0.0 版本起可用

DELETE /collections/{collection_name}/snapshots/{snapshot_name}
from qdrant_client import QdrantClient

client = QdrantClient(url="https://:6333")

client.delete_snapshot(
    collection_name="{collection_name}", snapshot_name="{snapshot_name}"
)
import { QdrantClient } from "@qdrant/js-client-rest";

const client = new QdrantClient({ host: "localhost", port: 6333 });

client.deleteSnapshot("{collection_name}", "{snapshot_name}");
use qdrant_client::qdrant::DeleteSnapshotRequestBuilder;
use qdrant_client::Qdrant;

let client = Qdrant::from_url("https://:6334").build()?;

client
    .delete_snapshot(DeleteSnapshotRequestBuilder::new(
        "{collection_name}",
        "{snapshot_name}",
    ))
    .await?;
import io.qdrant.client.QdrantClient;
import io.qdrant.client.QdrantGrpcClient;

QdrantClient client =
    new QdrantClient(QdrantGrpcClient.newBuilder("localhost", 6334, false).build());

client.deleteSnapshotAsync("{collection_name}", "{snapshot_name}").get();
using Qdrant.Client;

var client = new QdrantClient("localhost", 6334);

await client.DeleteSnapshotAsync(collectionName: "{collection_name}", snapshotName: "{snapshot_name}");
import (
	"context"

	"github.com/qdrant/go-client/qdrant"
)

client, err := qdrant.NewClient(&qdrant.Config{
	Host: "localhost",
	Port: 6334,
})

client.DeleteSnapshot(context.Background(), "{collection_name}", "{snapshot_name}")

列出快照

列出某个集合的快照

GET /collections/{collection_name}/snapshots
from qdrant_client import QdrantClient

client = QdrantClient(url="https://:6333")

client.list_snapshots(collection_name="{collection_name}")
import { QdrantClient } from "@qdrant/js-client-rest";

const client = new QdrantClient({ host: "localhost", port: 6333 });

client.listSnapshots("{collection_name}");
use qdrant_client::Qdrant;

let client = Qdrant::from_url("https://:6334").build()?;

client.list_snapshots("{collection_name}").await?;
import io.qdrant.client.QdrantClient;
import io.qdrant.client.QdrantGrpcClient;

QdrantClient client =
    new QdrantClient(QdrantGrpcClient.newBuilder("localhost", 6334, false).build());

client.listSnapshotAsync("{collection_name}").get();
using Qdrant.Client;

var client = new QdrantClient("localhost", 6334);

await client.ListSnapshotsAsync("{collection_name}");
import (
	"context"

	"github.com/qdrant/go-client/qdrant"
)

client, err := qdrant.NewClient(&qdrant.Config{
	Host: "localhost",
	Port: 6334,
})

client.ListSnapshots(context.Background(), "{collection_name}")

获取快照

从集合中下载指定快照作为文件

GET /collections/{collection_name}/snapshots/{snapshot_name}
curl 'http://{qdrant-url}:6333/collections/{collection_name}/snapshots/snapshot-2022-10-10.snapshot' \
    -H 'api-key: ********' \
    --output 'filename.snapshot'
curl 'http://{qdrant-url}:6333/collections/{collection_name}/snapshots/snapshot-2022-10-10.snapshot' \
    -H 'api-key: ********' \
    --output 'filename.snapshot'

恢复快照

快照可以通过三种方式恢复

  1. 从 URL 或本地文件恢复(适用于恢复远程服务器上或已存储在节点上的快照文件)
  2. 从上传的文件恢复(适用于将数据迁移到新集群)
  3. 在启动时恢复(适用于运行自托管的单节点 Qdrant 实例)

无论使用哪种方法,Qdrant 都会从快照中提取分片 (shard) 数据,并在集群中正确注册这些分片。如果集群中存在已恢复分片的其他活动副本,Qdrant 默认会将它们复制到新恢复的节点以保持数据一致性。

从 URL 或本地文件恢复

v0.11.3 版本起可用

此恢复方法要求快照文件可通过 URL 下载,或作为本地文件存在于节点上(例如,如果您之前在该节点上创建了快照)。如果您需要上传快照文件,请参见下一节。

要从 URL 或本地文件恢复,请使用 快照恢复接口。该接口接受诸如 https://example.com 的 URL,或诸如 file:///tmp/snapshot-2022-10-10.snapshot文件 URI。如果目标集合不存在,系统会自动创建它。

PUT /collections/{collection_name}/snapshots/recover
{
  "location": "http://qdrant-node-1:6333/collections/{collection_name}/snapshots/snapshot-2022-10-10.snapshot"
}
from qdrant_client import QdrantClient

client = QdrantClient(url="http://qdrant-node-2:6333")

client.recover_snapshot(
    "{collection_name}",
    "http://qdrant-node-1:6333/collections/collection_name/snapshots/snapshot-2022-10-10.snapshot",
)
import { QdrantClient } from "@qdrant/js-client-rest";

const client = new QdrantClient({ host: "localhost", port: 6333 });

client.recoverSnapshot("{collection_name}", {
  location: "http://qdrant-node-1:6333/collections/{collection_name}/snapshots/snapshot-2022-10-10.snapshot",
});

从上传的文件恢复

快照文件也可以作为文件上传,并使用 从上传的快照恢复 接口进行恢复。该接口在请求体中接受原始快照数据。如果目标集合不存在,系统会自动创建它。

curl -X POST 'http://{qdrant-url}:6333/collections/{collection_name}/snapshots/upload?priority=snapshot' \
    -H 'api-key: ********' \
    -H 'Content-Type:multipart/form-data' \
    -F 'snapshot=@/path/to/snapshot-2022-10-10.snapshot'

此方法通常用于将数据从一个集群迁移到另一个集群,因此我们建议针对该用例将优先级 (priority) 设置为 “snapshot”。

在启动时恢复

如果您有单节点部署,则可以在启动时恢复任何集合,并且它将立即可用。快照恢复通过启动时的 Qdrant CLI 使用 --snapshot 参数完成,该参数接受一对一对的列表,例如 <snapshot_file_path>:<target_collection_name>

例如

./qdrant --snapshot /snapshots/test-collection-archive.snapshot:test-collection --snapshot /snapshots/test-collection-archive.snapshot:test-copy-collection

目标集合必须不存在,否则程序将报错退出。

如果您希望覆盖现有集合,请谨慎使用 --force_snapshot 标志。

快照优先级

当将快照恢复到非空节点时,快照数据与现有数据之间可能会发生冲突。“优先级”设置控制 Qdrant 如何处理这些冲突。优先级设置很重要,因为不同的优先级可能会导致截然不同的结果。默认优先级可能不适用于所有情况。

可用的快照恢复优先级有

  • replica: (默认)优先使用现有数据,而非快照数据。
  • snapshot: 优先使用快照数据,而非现有数据。
  • no_sync: 恢复快照,不进行任何额外的同步。

要从快照恢复一个新集合,您需要将优先级设置为 snapshot。使用 snapshot 优先级,快照中的所有数据都将恢复到集群中。如果使用 replica 优先级 (默认),您最终会得到一个空集合,因为集群上的集合不包含任何点,且该来源被优先考虑。

no_sync 适用于特殊用例,通常不常用。它允许手动管理分片并在集群之间传输分片,无需任何额外同步。使用不当会导致集群处于损坏状态。

要从 URL 恢复,您需要在请求体中指定一个额外参数

PUT /collections/{collection_name}/snapshots/recover
{
  "location": "http://qdrant-node-1:6333/collections/{collection_name}/snapshots/snapshot-2022-10-10.snapshot",
  "priority": "snapshot"
}
curl -X POST 'http://qdrant-node-1:6333/collections/{collection_name}/snapshots/upload?priority=snapshot' \
    -H 'api-key: ********' \
    -H 'Content-Type:multipart/form-data' \
    -F 'snapshot=@/path/to/snapshot-2022-10-10.snapshot'
from qdrant_client import QdrantClient, models

client = QdrantClient(url="http://qdrant-node-2:6333")

client.recover_snapshot(
    "{collection_name}",
    "http://qdrant-node-1:6333/collections/{collection_name}/snapshots/snapshot-2022-10-10.snapshot",
    priority=models.SnapshotPriority.SNAPSHOT,
)
import { QdrantClient } from "@qdrant/js-client-rest";

const client = new QdrantClient({ host: "localhost", port: 6333 });

client.recoverSnapshot("{collection_name}", {
  location: "http://qdrant-node-1:6333/collections/{collection_name}/snapshots/snapshot-2022-10-10.snapshot",
  priority: "snapshot"
});

全存储快照

v0.8.5 版本起可用

有时不仅为单个集合创建快照,而且为整个存储(包括集合别名)创建快照会很方便。Qdrant 也为此提供了专门的 API。它类似于集合级快照,但不需要 collection_name

创建全存储快照

POST /snapshots
from qdrant_client import QdrantClient

client = QdrantClient(url="https://:6333")

client.create_full_snapshot()
import { QdrantClient } from "@qdrant/js-client-rest";

const client = new QdrantClient({ host: "localhost", port: 6333 });

client.createFullSnapshot();
use qdrant_client::Qdrant;

let client = Qdrant::from_url("https://:6334").build()?;

client.create_full_snapshot().await?;
import io.qdrant.client.QdrantClient;
import io.qdrant.client.QdrantGrpcClient;

QdrantClient client =
    new QdrantClient(QdrantGrpcClient.newBuilder("localhost", 6334, false).build());

client.createFullSnapshotAsync().get();
using Qdrant.Client;

var client = new QdrantClient("localhost", 6334);

await client.CreateFullSnapshotAsync();
import (
	"context"

	"github.com/qdrant/go-client/qdrant"
)

client, err := qdrant.NewClient(&qdrant.Config{
	Host: "localhost",
	Port: 6334,
})

client.CreateFullSnapshot(context.Background())

删除全存储快照

v1.0.0 版本起可用

DELETE /snapshots/{snapshot_name}
from qdrant_client import QdrantClient

client = QdrantClient(url="https://:6333")

client.delete_full_snapshot(snapshot_name="{snapshot_name}")
import { QdrantClient } from "@qdrant/js-client-rest";

const client = new QdrantClient({ host: "localhost", port: 6333 });

client.deleteFullSnapshot("{snapshot_name}");
use qdrant_client::Qdrant;

let client = Qdrant::from_url("https://:6334").build()?;

client.delete_full_snapshot("{snapshot_name}").await?;
import io.qdrant.client.QdrantClient;
import io.qdrant.client.QdrantGrpcClient;

QdrantClient client =
    new QdrantClient(QdrantGrpcClient.newBuilder("localhost", 6334, false).build());

client.deleteFullSnapshotAsync("{snapshot_name}").get();
using Qdrant.Client;

var client = new QdrantClient("localhost", 6334);

await client.DeleteFullSnapshotAsync("{snapshot_name}");
import (
	"context"

	"github.com/qdrant/go-client/qdrant"
)

client, err := qdrant.NewClient(&qdrant.Config{
	Host: "localhost",
	Port: 6334,
})

client.DeleteFullSnapshot(context.Background(), "{snapshot_name}")

列出全存储快照

GET /snapshots
from qdrant_client import QdrantClient

client = QdrantClient("localhost", port=6333)

client.list_full_snapshots()
import { QdrantClient } from "@qdrant/js-client-rest";

const client = new QdrantClient({ host: "localhost", port: 6333 });

client.listFullSnapshots();
use qdrant_client::Qdrant;

let client = Qdrant::from_url("https://:6334").build()?;

client.list_full_snapshots().await?;
import io.qdrant.client.QdrantClient;
import io.qdrant.client.QdrantGrpcClient;

QdrantClient client =
    new QdrantClient(QdrantGrpcClient.newBuilder("localhost", 6334, false).build());

client.listFullSnapshotAsync().get();
using Qdrant.Client;

var client = new QdrantClient("localhost", 6334);

await client.ListFullSnapshotsAsync();
import (
	"context"

	"github.com/qdrant/go-client/qdrant"
)

client, err := qdrant.NewClient(&qdrant.Config{
	Host: "localhost",
	Port: 6334,
})

client.ListFullSnapshots(context.Background())

下载全存储快照

GET /snapshots/{snapshot_name}

恢复全存储快照

恢复快照只能在启动时通过 Qdrant CLI 完成。

例如

./qdrant --storage-snapshot /snapshots/full-snapshot-2022-07-18-11-20-51.snapshot

存储

创建、上传和恢复的快照都存储为 .snapshot 文件。默认情况下,它们存储在本地文件系统上。您也可以配置使用 S3 存储服务来存放它们。

本地文件系统

默认情况下,快照存储在 ./snapshots 或使用 Docker 镜像时的 /qdrant/snapshots 中。

可以通过配置文件控制目标目录

storage:
  # Specify where you want to store snapshots.
  snapshots_path: ./snapshots

或者,您可以使用环境变量 QDRANT__STORAGE__SNAPSHOTS_PATH=./snapshots

v1.3.0 版本起可用

在创建快照时,默认会将临时文件放入配置的存储目录中。如果容量有限或使用了慢速网络附加磁盘,您可以为临时文件指定单独的位置

storage:
  # Where to store temporary files
  temp_path: /tmp

S3

自 v1.10.0 起可用

除了将快照存储在本地文件系统上,您还可以配置将快照存储在兼容 S3 的存储服务中。要启用此功能,必须在配置文件中进行配置。

例如,配置 AWS S3

storage:
  snapshots_config:
    # Use 's3' to store snapshots on S3
    snapshots_storage: s3

    s3_config:
      # Bucket name
      bucket: your_bucket_here

      # Bucket region (e.g. eu-central-1)
      region: your_bucket_region_here

      # Storage access key
      # Can be specified either here or in the `QDRANT__STORAGE__SNAPSHOTS_CONFIG__S3_CONFIG__ACCESS_KEY` environment variable.
      access_key: your_access_key_here

      # Storage secret key
      # Can be specified either here or in the `QDRANT__STORAGE__SNAPSHOTS_CONFIG__S3_CONFIG__SECRET_KEY` environment variable.
      secret_key: your_secret_key_here

      # S3-Compatible Storage URL
      # Can be specified either here or in the `QDRANT__STORAGE__SNAPSHOTS_CONFIG__S3_CONFIG__ENDPOINT_URL` environment variable.
      endpoint_url: your_url_here

除了快照,Qdrant 还提供了 Qdrant 迁移工具,支持:

  • Qdrant Cloud 实例之间的迁移。
  • 将其他提供商的向量迁移到 Qdrant。
  • 从 Qdrant OSS 迁移到 Qdrant Cloud。

请遵循我们的迁移指南,了解如何有效使用 Qdrant 迁移工具。

此页面有用吗?

感谢您的反馈!🙏

很遗憾听到这个消息。😔 您可以在 GitHub 上编辑此页面,或者创建一个 GitHub Issue。