使用快照备份和恢复 Qdrant 集合
| 时间:20 分钟 | 级别:新手 |
|---|
集合是 Qdrant 中数据存储的基本单位。它包含向量、它们的 ID 和有效负载。然而,为了保持搜索效率,需要在数据之上构建额外的数据结构。构建这些数据结构可能需要一段时间,特别是对于大型集合。这就是为什么使用快照是导出和导入 Qdrant 集合的最佳方式,因为它们包含恢复整个集合所需的所有零碎数据,并且效率很高。
本教程将向您展示如何创建集合的快照并进行恢复。由于在分布式环境中处理快照可能会被认为有点复杂,我们将使用一个 3 节点 Qdrant 集群。但是,同样的方法也适用于单节点设置。
您可以使用本页面描述的技术来迁移集群。按照本教程中的说明创建和下载快照。当您从快照恢复时,将数据恢复到新集群。
先决条件
假设您已经有一个正在运行的 Qdrant 实例或集群。如果没有,您可以按照安装指南设置本地 Qdrant 实例,或使用Qdrant Cloud通过几次点击创建一个集群。
集群运行后,我们来安装所需的依赖项
pip install qdrant-client datasets
建立与 Qdrant 的连接
我们将使用 Python SDK 和原始 HTTP 调用与 Qdrant 进行交互。由于我们将使用一个 3 节点集群,我们需要知道所有节点的 URL。为了简单起见,让我们将它们与 API 密钥一起保存在常量中,以便以后可以引用它们。
QDRANT_MAIN_URL = "https://my-cluster.com:6333"
QDRANT_NODES = (
"https://node-0.my-cluster.com:6333",
"https://node-1.my-cluster.com:6333",
"https://node-2.my-cluster.com:6333",
)
QDRANT_API_KEY = "my-api-key"
现在我们可以创建客户端实例了
from qdrant_client import QdrantClient
client = QdrantClient(QDRANT_MAIN_URL, api_key=QDRANT_API_KEY)
首先,我们将从预计算的数据集创建一个集合。如果您已经有一个集合,您可以跳过此步骤,从创建快照开始。
(可选)创建集合并导入数据
加载数据集
我们将使用一个预先计算了嵌入的数据集,可在 Hugging Face Hub 上找到。该数据集名为Qdrant/arxiv-titles-instructorxl-embeddings,并使用InstructorXL模型创建。它包含来自arXiv数据集的论文标题的 225 万个嵌入。
加载数据集就像这样简单
from datasets import load_dataset
dataset = load_dataset(
"Qdrant/arxiv-titles-instructorxl-embeddings", split="train", streaming=True
)
我们使用了流模式,因此数据集不会加载到内存中。相反,我们可以遍历它并提取 ID 和向量嵌入
for payload in dataset:
id_ = payload.pop("id")
vector = payload.pop("vector")
print(id_, vector, payload)
单个有效负载看起来像这样
{
'title': 'Dynamics of partially localized brane systems',
'DOI': '1109.1415'
}
创建一个集合
首先,我们需要创建我们的集合。我们不打算修改它的配置,但现在这样做是合理的。配置也是集合快照的一部分。
from qdrant_client import models
if not client.collection_exists("test_collection"):
client.create_collection(
collection_name="test_collection",
vectors_config=models.VectorParams(
size=768, # Size of the embedding vector generated by the InstructorXL model
distance=models.Distance.COSINE
),
)
上传数据集
计算嵌入通常是向量搜索管道的瓶颈,但我们很高兴它们已经就位。由于本教程的目标是展示如何创建快照,**我们将只上传数据集的一小部分**。
ids, vectors, payloads = [], [], []
for payload in dataset:
id_ = payload.pop("id")
vector = payload.pop("vector")
ids.append(id_)
vectors.append(vector)
payloads.append(payload)
# We are going to upload only 1000 vectors
if len(ids) == 1000:
break
client.upsert(
collection_name="test_collection",
points=models.Batch(
ids=ids,
vectors=vectors,
payloads=payloads,
),
)
我们的集合现在已准备好用于搜索。让我们为其创建一个快照。
如果您已经有了一个集合,您可以跳过上一步,从创建快照开始。
创建并下载快照
Qdrant 暴露了一个 HTTP 端点来请求创建快照,但我们也可以用 Python SDK 调用它。我们的设置由 3 个节点组成,因此我们需要**在每个节点上**调用该端点并创建快照。在使用 Python SDK 时,这意味着为每个节点创建一个单独的客户端实例。
snapshot_urls = []
for node_url in QDRANT_NODES:
node_client = QdrantClient(node_url, api_key=QDRANT_API_KEY)
snapshot_info = node_client.create_snapshot(collection_name="test_collection")
snapshot_url = f"{node_url}/collections/test_collection/snapshots/{snapshot_info.name}"
snapshot_urls.append(snapshot_url)
// for `https://node-0.my-cluster.com:6333`
POST /collections/test_collection/snapshots
// for `https://node-1.my-cluster.com:6333`
POST /collections/test_collection/snapshots
// for `https://node-2.my-cluster.com:6333`
POST /collections/test_collection/snapshots
响应
{
"result": {
"name": "test_collection-559032209313046-2024-01-03-13-20-11.snapshot",
"creation_time": "2024-01-03T13:20:11",
"size": 18956800
},
"status": "ok",
"time": 0.307644965
}
一旦我们有了快照 URL,我们就可以下载它们。请确保在请求头中包含 API 密钥。下载快照**只能通过 HTTP API 进行**,因此我们将使用 `requests` 库。
import requests
import os
# Create a directory to store snapshots
os.makedirs("snapshots", exist_ok=True)
local_snapshot_paths = []
for snapshot_url in snapshot_urls:
snapshot_name = os.path.basename(snapshot_url)
local_snapshot_path = os.path.join("snapshots", snapshot_name)
response = requests.get(
snapshot_url, headers={"api-key": QDRANT_API_KEY}
)
with open(local_snapshot_path, "wb") as f:
response.raise_for_status()
f.write(response.content)
local_snapshot_paths.append(local_snapshot_path)
或者,您可以使用 `wget` 命令
wget https://node-0.my-cluster.com:6333/collections/test_collection/snapshots/test_collection-559032209313046-2024-01-03-13-20-11.snapshot \
--header="api-key: ${QDRANT_API_KEY}" \
-O node-0-shapshot.snapshot
wget https://node-1.my-cluster.com:6333/collections/test_collection/snapshots/test_collection-559032209313047-2024-01-03-13-20-12.snapshot \
--header="api-key: ${QDRANT_API_KEY}" \
-O node-1-shapshot.snapshot
wget https://node-2.my-cluster.com:6333/collections/test_collection/snapshots/test_collection-559032209313048-2024-01-03-13-20-13.snapshot \
--header="api-key: ${QDRANT_API_KEY}" \
-O node-2-shapshot.snapshot
快照现在已本地存储。我们可以使用它们将集合恢复到不同的 Qdrant 实例,或者将它们视为备份。我们将在同一集群上使用相同数据创建另一个集合。
从快照恢复
我们全新的快照已准备好恢复。通常,它用于将集合移动到不同的 Qdrant 实例,但我们将使用它在同一集群上创建一个新集合。它只会有一个不同的名称,`test_collection_import`。我们不需要先创建集合,因为它会自动创建。
集合恢复也是在每个节点上单独完成的,但我们的 Python SDK 尚不支持。我们将改用 HTTP API,并使用 `requests` 库向每个节点发送请求。
for node_url, snapshot_path in zip(QDRANT_NODES, local_snapshot_paths):
snapshot_name = os.path.basename(snapshot_path)
requests.post(
f"{node_url}/collections/test_collection_import/snapshots/upload?priority=snapshot",
headers={
"api-key": QDRANT_API_KEY,
},
files={"snapshot": (snapshot_name, open(snapshot_path, "rb"))},
)
或者,您可以使用 `curl` 命令
curl -X POST 'https://node-0.my-cluster.com:6333/collections/test_collection_import/snapshots/upload?priority=snapshot' \
-H 'api-key: ${QDRANT_API_KEY}' \
-H 'Content-Type:multipart/form-data' \
-F 'snapshot=@node-0-shapshot.snapshot'
curl -X POST 'https://node-1.my-cluster.com:6333/collections/test_collection_import/snapshots/upload?priority=snapshot' \
-H 'api-key: ${QDRANT_API_KEY}' \
-H 'Content-Type:multipart/form-data' \
-F 'snapshot=@node-1-shapshot.snapshot'
curl -X POST 'https://node-2.my-cluster.com:6333/collections/test_collection_import/snapshots/upload?priority=snapshot' \
-H 'api-key: ${QDRANT_API_KEY}' \
-H 'Content-Type:multipart/form-data' \
-F 'snapshot=@node-2-shapshot.snapshot'
重要:我们选择了 `priority=snapshot` 以确保快照优先于节点上存储的数据。您可以在文档中阅读有关优先级的更多信息。
除了快照,Qdrant 还提供了Qdrant 迁移工具,它支持
- Qdrant Cloud 实例之间的迁移。
- 将向量从其他提供商迁移到 Qdrant。
- 从 Qdrant OSS 迁移到 Qdrant Cloud。
请遵循我们的迁移指南,了解如何有效使用 Qdrant 迁移工具。