GitHub概要
qdrant/qdrant
Qdrant - High-performance, massive-scale Vector Database and Vector Search Engine for the next generation of AI. Also available in the cloud https://cloud.qdrant.io/
ホームページ:https://qdrant.tech
スター24,978
ウォッチ138
フォーク1,722
作成日:2020年5月30日
言語:Rust
ライセンス:Apache License 2.0
トピックス
ai-searchai-search-engineembeddings-similarityhnswimage-searchknn-algorithmmachine-learningmlopsnearest-neighbor-searchneural-networkneural-searchrecommender-systemsearchsearch-enginesearch-enginessimilarity-searchvector-databasevector-searchvector-search-engine
スター履歴
データ取得日時: 2025/7/30 00:10
データベース
Qdrant
概要
QdrantはRustで開発された高性能ベクトル検索エンジン・ベクトルデータベースです。高次元ベクトルとそれに付随するJSONペイロードの効率的な格納、検索、管理に特化して設計されています。2025年のベンチマークで最高のRPS(リクエスト毎秒)と最低レイテンシを達成し、パフォーマンスリーダーとして評価されています。ニューラルネットワークベースのマッチング、意味検索、推薦システムなどに最適化されています。
詳細
Qdrantは、Rustの高速性、メモリ安全性、並行性の特徴を最大限に活用し、高負荷下でも安定した動作を実現します。複雑なフィルタリング機能を拡張サポートし、動的クエリプランニングとペイロードインデックスにより、メタデータフィルタリングが必要なアプリケーションに最適です。
Qdrantの主な特徴:
- Rust実装による高性能: メモリ安全性と低レベル制御により最高速度を実現
- ベクトル類似性検索: HNSWアルゴリズムによる効率的な最近傍探索
- ペイロードフィルタリング: JSONメタデータに対する複雑なフィルタリング(キーワード、全文検索、数値範囲、地理的位置)
- ハイブリッド検索: 密ベクトルと疎ベクトルの両方をサポート
- 分散アーキテクチャ: シャーディングとレプリケーションによる水平スケーリング
- 複数インターフェース: REST APIとgRPC APIの両方を提供
- ベクトル量子化: RAMを最大97%削減し、検索速度と精度のトレードオフを管理
- オンディスクストレージ: 大規模データセット対応
- Write-Ahead Logging: データの永続性と更新の確認を保証
- SIMD最適化: x86-x64とNeonアーキテクチャでのハードウェアアクセラレーション
- 非同期I/O: io_uringを使用したディスクスループットの最大化
- バイナリ量子化: 高次元ベクトルの検索パフォーマンスを40倍向上
アーキテクチャ
Qdrantは以下の階層的アーキテクチャを採用:
- APIレイヤー: actix-web(REST)とtonic(gRPC)によるエンドポイント
- アプリケーションコア: リクエストディスパッチャーとRaftコンセンサス
- コレクション管理: メタデータ管理と分散ロジック
- データレイヤー: シャードレプリケーションとローカル/リモートシャード
- ストレージ&インデックス: セグメント単位のベクトル・ペイロード格納
- 永続化レイヤー: WriteAheadLog、RocksDB、メモリマップファイル
2025年の最新動向
- エッジデバイス向け軽量版の開発
- カスタムRust製Gridstoreキーバリューストアの導入(RocksDBからの移行)
- パフォーマンスベンチマークでの業界リーダーシップ
- 3500万以上の埋め込みを1秒以下でクエリ可能
メリット・デメリット
メリット
- 最高性能: 2025年ベンチマークで最高RPS・最低レイテンシを達成
- Rust実装: メモリ安全性と並行性により高速かつ安定
- 高度なフィルタリング: ペイロードインデックスによる複雑なメタデータフィルタ
- メモリ効率: ベクトル量子化により最大97%のRAM削減
- スケーラビリティ: 分散アーキテクチャで大規模展開に対応
- 開発者体験: シンプルなAPIと豊富なSDK(Python、Go、Java、Node.js、Rust)
- ハードウェア最適化: SIMD命令による高速ベクトル演算
- 柔軟な検索: 密・疎ベクトルの両方をサポート
- オープンソース: Apache 2.0ライセンス
デメリット
- 学習曲線: ベクトル検索の概念理解が必要
- Rust専門知識: カスタマイズには Rustの知識が必要
- リソース消費: 大規模インデックスはメモリを大量消費
- 限定的なエコシステム: Milvusと比べて統合ツールが少ない
- エンタープライズ機能: マネージドサービスの選択肢が限定的
主要リンク
書き方の例
インストール・セットアップ
# Docker での実行
docker pull qdrant/qdrant
docker run -p 6333:6333 -p 6334:6334 \
-v $(pwd)/qdrant_storage:/qdrant/storage:z \
qdrant/qdrant
# Docker Compose での実行
cat > docker-compose.yml << EOF
version: '3.4'
services:
qdrant:
image: qdrant/qdrant
restart: always
ports:
- 6333:6333
- 6334:6334
volumes:
- ./qdrant_storage:/qdrant/storage:z
EOF
docker-compose up -d
# Rustでソースからビルド
git clone https://github.com/qdrant/qdrant.git
cd qdrant
cargo build --release
./target/release/qdrant
# Python クライアントインストール
pip install qdrant-client
# Node.js クライアントインストール
npm install @qdrant/js-client-rest
# Go クライアントインストール
go get -u github.com/qdrant/go-client
基本操作(Python SDK)
from qdrant_client import QdrantClient
from qdrant_client.models import Distance, VectorParams, PointStruct
import numpy as np
# クライアント初期化
client = QdrantClient("localhost", port=6333)
# または Qdrant Cloud
# client = QdrantClient(url="https://xxx.qdrant.io", api_key="your-api-key")
# コレクション作成
client.create_collection(
collection_name="my_collection",
vectors_config=VectorParams(size=768, distance=Distance.COSINE),
)
# ポイント挿入
points = [
PointStruct(
id=1,
vector=np.random.rand(768).tolist(),
payload={"text": "Qdrantは高性能ベクトルデータベース", "category": "database"}
),
PointStruct(
id=2,
vector=np.random.rand(768).tolist(),
payload={"text": "Rustで実装された検索エンジン", "category": "search"}
),
PointStruct(
id=3,
vector=np.random.rand(768).tolist(),
payload={"text": "2025年パフォーマンスリーダー", "category": "benchmark"}
)
]
client.upsert(
collection_name="my_collection",
points=points
)
# ベクトル検索
query_vector = np.random.rand(768).tolist()
search_result = client.search(
collection_name="my_collection",
query_vector=query_vector,
limit=3
)
for hit in search_result:
print(f"ID: {hit.id}, Score: {hit.score}, Payload: {hit.payload}")
高度な検索機能
from qdrant_client.models import Filter, FieldCondition, MatchValue, Range
# フィルタリング付き検索
search_result = client.search(
collection_name="my_collection",
query_vector=query_vector,
query_filter=Filter(
must=[
FieldCondition(
key="category",
match=MatchValue(value="database")
)
]
),
limit=5
)
# 範囲フィルタリング
search_result = client.search(
collection_name="my_collection",
query_vector=query_vector,
query_filter=Filter(
must=[
FieldCondition(
key="price",
range=Range(
gte=100,
lte=1000
)
)
]
),
limit=10
)
# 複数条件の組み合わせ
from qdrant_client.models import MatchAny
search_result = client.search(
collection_name="products",
query_vector=query_vector,
query_filter=Filter(
must=[
FieldCondition(
key="category",
match=MatchAny(any=["electronics", "computers"])
)
],
must_not=[
FieldCondition(
key="discontinued",
match=MatchValue(value=True)
)
]
),
limit=20
)
# スコアしきい値付き検索
search_result = client.search(
collection_name="my_collection",
query_vector=query_vector,
score_threshold=0.8,
limit=10
)
ペイロードインデックスの作成
from qdrant_client.models import PayloadSchemaType
# テキストフィールドのインデックス作成
client.create_payload_index(
collection_name="my_collection",
field_name="text",
field_schema=PayloadSchemaType.TEXT
)
# 数値フィールドのインデックス作成
client.create_payload_index(
collection_name="my_collection",
field_name="price",
field_schema=PayloadSchemaType.FLOAT
)
# キーワードフィールドのインデックス作成
client.create_payload_index(
collection_name="my_collection",
field_name="category",
field_schema=PayloadSchemaType.KEYWORD
)
# 地理的フィールドのインデックス作成
client.create_payload_index(
collection_name="locations",
field_name="location",
field_schema=PayloadSchemaType.GEO
)
バッチ操作と最適化
# バッチ挿入(大量データの効率的な挿入)
batch_size = 100
all_points = []
for i in range(10000):
point = PointStruct(
id=i,
vector=np.random.rand(768).tolist(),
payload={
"text": f"Document {i}",
"category": f"cat_{i % 10}",
"timestamp": i * 1000
}
)
all_points.append(point)
if len(all_points) >= batch_size:
client.upsert(
collection_name="my_collection",
points=all_points
)
all_points = []
# 残りのポイントを挿入
if all_points:
client.upsert(
collection_name="my_collection",
points=all_points
)
# コレクションの最適化
client.update_collection(
collection_name="my_collection",
optimizer_config={
"deleted_threshold": 0.2,
"vacuum_min_vector_number": 1000,
"default_segment_number": 2,
"max_segment_size": 200000,
"memmap_threshold": 50000,
"indexing_threshold": 10000,
"flush_interval_sec": 5,
"max_optimization_threads": 2
}
)
埋め込みモデルとの統合
from sentence_transformers import SentenceTransformer
from qdrant_client.models import Batch
# 埋め込みモデルの初期化
model = SentenceTransformer('all-MiniLM-L6-v2')
# テキストデータ
texts = [
"Qdrantは高速なベクトル検索エンジンです",
"Rustで実装されており、高いパフォーマンスを誇ります",
"複雑なフィルタリングとペイロード管理が可能です"
]
# 埋め込みベクトルの生成
embeddings = model.encode(texts)
# Qdrantへの挿入
points = []
for idx, (text, embedding) in enumerate(zip(texts, embeddings)):
points.append(
PointStruct(
id=idx,
vector=embedding.tolist(),
payload={"text": text}
)
)
client.upsert(
collection_name="text_collection",
points=points
)
# セマンティック検索
query_text = "ベクトルデータベースの性能"
query_embedding = model.encode(query_text)
results = client.search(
collection_name="text_collection",
query_vector=query_embedding.tolist(),
limit=3,
with_payload=True
)
for result in results:
print(f"Score: {result.score:.4f}, Text: {result.payload['text']}")
スナップショットとバックアップ
# スナップショットの作成
client.create_snapshot(collection_name="my_collection")
# スナップショット一覧の取得
snapshots = client.list_snapshots(collection_name="my_collection")
for snapshot in snapshots:
print(f"Snapshot: {snapshot.name}, Created: {snapshot.creation_time}")
# フルバックアップの作成
client.create_full_snapshot()
# スナップショットからの復元
client.recover_snapshot(
collection_name="my_collection",
location="http://localhost:6333/collections/my_collection/snapshots/snapshot_2024.snapshot"
)
gRPC APIの使用
from qdrant_client import QdrantClient
from qdrant_client.models import Distance, VectorParams
# gRPCクライアントの初期化(より高速)
client = QdrantClient(
host="localhost",
port=6334, # gRPCポート
grpc_port=6334,
prefer_grpc=True
)
# 以降の操作は同じ
client.create_collection(
collection_name="grpc_collection",
vectors_config=VectorParams(size=384, distance=Distance.DOT),
)
マルチベクトル検索
from qdrant_client.models import NamedVector, VectorParams
# 複数のベクトルを持つコレクション作成
client.create_collection(
collection_name="multi_vector_collection",
vectors_config={
"text": VectorParams(size=768, distance=Distance.COSINE),
"image": VectorParams(size=512, distance=Distance.EUCLID)
}
)
# マルチベクトルポイントの挿入
client.upsert(
collection_name="multi_vector_collection",
points=[
PointStruct(
id=1,
vector={
"text": np.random.rand(768).tolist(),
"image": np.random.rand(512).tolist()
},
payload={"description": "製品1"}
)
]
)
# 特定のベクトルで検索
text_results = client.search(
collection_name="multi_vector_collection",
query_vector=np.random.rand(768).tolist(),
using="text",
limit=5
)
image_results = client.search(
collection_name="multi_vector_collection",
query_vector=np.random.rand(512).tolist(),
using="image",
limit=5
)
パフォーマンスチューニング
from qdrant_client.models import OptimizersConfigDiff, HnswConfigDiff
# HNSWパラメータの調整
client.update_collection(
collection_name="my_collection",
hnsw_config=HnswConfigDiff(
m=32, # より多くの接続でより高精度
ef_construct=200, # 構築時の精度
full_scan_threshold=20000 # フルスキャンのしきい値
)
)
# 検索時のパラメータ
search_result = client.search(
collection_name="my_collection",
query_vector=query_vector,
search_params={
"hnsw_ef": 128, # 検索時の精度パラメータ
"exact": False # 近似検索を使用
},
limit=10
)
# 量子化の設定
from qdrant_client.models import ScalarQuantization, QuantizationSearchParams
client.update_collection(
collection_name="my_collection",
quantization_config=ScalarQuantization(
scalar={
"type": "int8",
"quantile": 0.99,
"always_ram": True
}
)
)
# 量子化を使用した検索
search_result = client.search(
collection_name="my_collection",
query_vector=query_vector,
search_params={
"quantization": QuantizationSearchParams(
ignore=False,
rescore=True,
oversampling=2.0
)
},
limit=10
)