Files
2026-07-13 21:37:11 +08:00

12 KiB
Raw Permalink Blame History

Qdrant 故障排查指南

安装问题

Docker 问题

错误Cannot connect to Docker daemon

修复

# 启动 Docker 守护进程
sudo systemctl start docker

# 或在 Mac/Windows 上使用 Docker Desktop
open -a Docker

错误Port 6333 already in use

修复

# 查找占用端口的进程
lsof -i :6333

# 终止进程或使用其他端口
docker run -p 6334:6333 qdrant/qdrant

Python 客户端问题

错误ModuleNotFoundError: No module named 'qdrant_client'

修复

pip install qdrant-client

# 指定版本
pip install qdrant-client>=1.12.0

错误grpc._channel._InactiveRpcError

修复

# 安装带 gRPC 支持的版本
pip install 'qdrant-client[grpc]'

# 或禁用 gRPC
client = QdrantClient(host="localhost", port=6333, prefer_grpc=False)

连接问题

无法连接到服务器

错误ConnectionRefusedError: [Errno 111] Connection refused

解决方案

  1. 检查服务器是否在运行
docker ps | grep qdrant
curl http://localhost:6333/healthz
  1. 验证端口绑定
# 检查监听端口
netstat -tlnp | grep 6333

# Docker 端口映射
docker port <container_id>
  1. 使用正确的主机地址
# Linux 上的 Docker
client = QdrantClient(host="localhost", port=6333)

# Mac/Windows 上有网络问题的 Docker
client = QdrantClient(host="127.0.0.1", port=6333)

# Docker 网络内部
client = QdrantClient(host="qdrant", port=6333)

超时错误

错误TimeoutError: Connection timed out

修复

# 增加超时时间
client = QdrantClient(
    host="localhost",
    port=6333,
    timeout=60  # 秒
)

# 对于大型操作
client.upsert(
    collection_name="documents",
    points=large_batch,
    wait=False  # 不等待索引完成
)

SSL/TLS 错误

错误ssl.SSLCertVerificationError

修复

# Qdrant Cloud
client = QdrantClient(
    url="https://cluster.cloud.qdrant.io",
    api_key="your-api-key"
)

# 自签名证书
client = QdrantClient(
    host="localhost",
    port=6333,
    https=True,
    verify=False  # 禁用验证(不推荐用于生产环境)
)

集合问题

集合已存在

错误ValueError: Collection 'documents' already exists

修复

# 创建前先检查
collections = client.get_collections().collections
names = [c.name for c in collections]

if "documents" not in names:
    client.create_collection(...)

# 或重新创建
client.recreate_collection(
    collection_name="documents",
    vectors_config=VectorParams(size=384, distance=Distance.COSINE)
)

集合未找到

错误NotFoundException: Collection 'docs' not found

修复

# 列出可用集合
collections = client.get_collections()
print([c.name for c in collections.collections])

# 检查确切名称(区分大小写)
try:
    info = client.get_collection("documents")
except Exception as e:
    print(f"未找到集合:{e}")

向量维度不匹配

错误ValueError: Vector dimension mismatch. Expected 384, got 768

修复

# 检查集合配置
info = client.get_collection("documents")
print(f"期望维度:{info.config.params.vectors.size}")

# 使用正确维度重新创建
client.recreate_collection(
    collection_name="documents",
    vectors_config=VectorParams(size=768, distance=Distance.COSINE)  # 匹配你的嵌入向量
)

搜索问题

搜索结果为空

问题:搜索返回空结果。

解决方案

  1. 验证数据是否存在
info = client.get_collection("documents")
print(f"点数:{info.points_count}")

# 滚动查看数据
points, _ = client.scroll(
    collection_name="documents",
    limit=10,
    with_payload=True
)
print(points)
  1. 检查向量格式
# 必须为浮点数列表
query_vector = embedding.tolist()  # 将 numpy 转换为列表

# 检查维度
print(f"查询维度:{len(query_vector)}")
  1. 验证过滤条件
# 先不使用过滤器进行测试
results = client.search(
    collection_name="documents",
    query_vector=query,
    limit=10
    # 无过滤器
)

# 然后逐步添加过滤器

搜索性能缓慢

问题:搜索耗时过长。

解决方案

  1. 创建载荷索引
# 为过滤器中使用的字段建立索引
client.create_payload_index(
    collection_name="documents",
    field_name="category",
    field_schema="keyword"
)
  1. 启用量化
client.update_collection(
    collection_name="documents",
    quantization_config=ScalarQuantization(
        scalar=ScalarQuantizationConfig(type=ScalarType.INT8)
    )
)
  1. 调整 HNSW 参数
# 更快搜索(精度较低)
client.update_collection(
    collection_name="documents",
    hnsw_config=HnswConfigDiff(ef_construct=64, m=8)
)

# 使用 ef 搜索参数
results = client.search(
    collection_name="documents",
    query_vector=query,
    search_params={"hnsw_ef": 64},  # 值越小越快
    limit=10
)
  1. 使用 gRPC
client = QdrantClient(
    host="localhost",
    port=6333,
    grpc_port=6334,
    prefer_grpc=True
)

结果不一致

问题:相同查询返回不同结果。

解决方案

  1. 等待索引完成
client.upsert(
    collection_name="documents",
    points=points,
    wait=True  # 等待索引更新
)
  1. 检查副本一致性
# 强一致性读取
results = client.search(
    collection_name="documents",
    query_vector=query,
    consistency="all"  # 从所有副本读取
)

数据写入问题

批量写入失败

错误PayloadError: Payload too large

修复

# 拆分为更小的批次
def batch_upsert(client, collection, points, batch_size=100):
    for i in range(0, len(points), batch_size):
        batch = points[i:i + batch_size]
        client.upsert(
            collection_name=collection,
            points=batch,
            wait=True
        )

batch_upsert(client, "documents", large_points_list)

无效的 Point ID

错误ValueError: Invalid point ID

修复

# 有效的 ID 类型:int 或 UUID 字符串
from uuid import uuid4

# 整数 ID
PointStruct(id=123, vector=vec, payload={})

# UUID 字符串
PointStruct(id=str(uuid4()), vector=vec, payload={})

# 无效的 ID
PointStruct(id="custom-string-123", ...)  # 请使用 UUID 格式

载荷验证错误

错误ValidationError: Invalid payload

修复

# 确保载荷是 JSON 可序列化的
import json

payload = {
    "title": "Document",
    "count": 42,
    "tags": ["a", "b"],
    "nested": {"key": "value"}
}

# 写入前进行验证
json.dumps(payload)  # 不应抛出异常

# 避免不可序列化的类型
# 无效:datetime、numpy 数组、自定义对象
payload = {
    "timestamp": datetime.now().isoformat(),  # 转换为字符串
    "vector": embedding.tolist()  # 将 numpy 转换为列表
}

内存问题

内存不足

错误MemoryError 或容器被终止

解决方案

  1. 启用磁盘存储
client.create_collection(
    collection_name="large_collection",
    vectors_config=VectorParams(size=384, distance=Distance.COSINE),
    on_disk_payload=True,  # 将载荷存储在磁盘上
    hnsw_config=HnswConfigDiff(on_disk=True)  # 将 HNSW 存储在磁盘上
)
  1. 使用量化
# 减少 4 倍内存
client.update_collection(
    collection_name="large_collection",
    quantization_config=ScalarQuantization(
        scalar=ScalarQuantizationConfig(
            type=ScalarType.INT8,
            always_ram=False  # 保留在磁盘上
        )
    )
)
  1. 增加 Docker 内存限制
docker run -m 8g -p 6333:6333 qdrant/qdrant
  1. 配置 Qdrant 存储
# config.yaml
storage:
  performance:
    max_search_threads: 2
  optimizers:
    memmap_threshold_kb: 20000

索引期间内存占用高

修复

# 增加批量加载的索引阈值
client.update_collection(
    collection_name="documents",
    optimizer_config={
        "indexing_threshold": 50000  # 延迟索引
    }
)

# 批量插入
client.upsert(collection_name="documents", points=all_points, wait=False)

# 然后优化
client.update_collection(
    collection_name="documents",
    optimizer_config={
        "indexing_threshold": 10000  # 恢复常规索引
    }
)

集群问题

节点无法加入集群

问题:新节点无法加入集群。

修复

# 检查网络连通性
docker exec qdrant-node-2 ping qdrant-node-1

# 验证引导 URL
docker logs qdrant-node-2 | grep bootstrap

# 检查 Raft 状态
curl http://localhost:6333/cluster

脑裂

问题:集群状态不一致。

修复

# 强制领导者选举
curl -X POST http://localhost:6333/cluster/recover

# 或重启少数节点
docker restart qdrant-node-2 qdrant-node-3

复制延迟

问题:副本落后。

修复

# 检查集合状态
info = client.get_collection("documents")
print(f"状态:{info.status}")

# 对关键写入使用强一致性
client.upsert(
    collection_name="documents",
    points=points,
    ordering=WriteOrdering.STRONG
)

性能调优

基准测试配置

import time
import numpy as np

def benchmark_search(client, collection, n_queries=100, dimension=384):
    # 生成随机查询
    queries = [np.random.rand(dimension).tolist() for _ in range(n_queries)]

    # 预热
    for q in queries[:10]:
        client.search(collection_name=collection, query_vector=q, limit=10)

    # 基准测试
    start = time.perf_counter()
    for q in queries:
        client.search(collection_name=collection, query_vector=q, limit=10)
    elapsed = time.perf_counter() - start

    print(f"QPS{n_queries / elapsed:.2f}")
    print(f"延迟:{elapsed / n_queries * 1000:.2f}ms")

benchmark_search(client, "documents")

最优 HNSW 参数

# 高召回率(较慢)
client.create_collection(
    collection_name="high_recall",
    vectors_config=VectorParams(size=384, distance=Distance.COSINE),
    hnsw_config=HnswConfigDiff(
        m=32,              # 更多连接
        ef_construct=200   # 更高构建质量
    )
)

# 高速度(较低召回率)
client.create_collection(
    collection_name="high_speed",
    vectors_config=VectorParams(size=384, distance=Distance.COSINE),
    hnsw_config=HnswConfigDiff(
        m=8,               # 更少连接
        ef_construct=64    # 较低构建质量
    )
)

# 均衡配置
client.create_collection(
    collection_name="balanced",
    vectors_config=VectorParams(size=384, distance=Distance.COSINE),
    hnsw_config=HnswConfigDiff(
        m=16,              # 默认值
        ef_construct=100   # 默认值
    )
)

调试技巧

启用详细日志

import logging

logging.basicConfig(level=logging.DEBUG)
logging.getLogger("qdrant_client").setLevel(logging.DEBUG)

查看服务器日志

# Docker 日志
docker logs -f qdrant

# 带时间戳
docker logs --timestamps qdrant

# 最后 100 行
docker logs --tail 100 qdrant

检查集合状态

# 集合信息
info = client.get_collection("documents")
print(f"状态:{info.status}")
print(f"点数:{info.points_count}")
print(f"分段数:{len(info.segments)}")
print(f"配置:{info.config}")

# 采样数据点
points, _ = client.scroll(
    collection_name="documents",
    limit=5,
    with_payload=True,
    with_vectors=True
)
for p in points:
    print(f"ID{p.id},载荷:{p.payload}")

测试连接

def test_connection(host="localhost", port=6333):
    try:
        client = QdrantClient(host=host, port=port, timeout=5)
        collections = client.get_collections()
        print(f"已连接!集合数:{len(collections.collections)}")
        return True
    except Exception as e:
        print(f"连接失败:{e}")
        return False

test_connection()

获取帮助

  1. 文档https://qdrant.tech/documentation/
  2. GitHub Issueshttps://github.com/qdrant/qdrant/issues
  3. Discordhttps://discord.gg/qdrant
  4. Stack Overflow:标签 qdrant

报告问题

请包含以下信息:

  • Qdrant 版本:curl http://localhost:6333/
  • Python 客户端版本:pip show qdrant-client
  • 完整的错误回溯信息
  • 最小可复现代码
  • 集合配置