让 Redis 成为你 AI 应用的向量数据库 ------ 原理、实践与最佳实践
一、RedisVL
在现代 AI 应用中,向量(embedding)已经成为连接非结构化数据(文本、图像、音频)与机器学习模型的桥梁。无论是推荐系统、语义搜索还是异常检测,你都需要高效地存储和检索高维向量。RedisVL(Redis Vector Library)正是为此而生------它是一个专为 Redis 打造的 Python 客户端,将 Redis 强大的内存数据库能力与向量相似性搜索(VSS)无缝结合,让你能够在已有的 Redis 基础设施上快速构建 AI 驱动的实时应用。
RedisVL 的核心价值:
- 开箱即用的向量搜索:基于 HNSW、FLAT 等算法,在亿万级向量中毫秒级返回最近邻。
- 与 AI 生态深度集成:原生支持 OpenAI、Cohere、HuggingFace 等主流嵌入模型,一键生成向量。
- 低延迟、高并发:依托 Redis 的内存架构,即使在大规模数据集下也能保持亚毫秒响应。
- 敏捷的 schema 管理:通过声明式索引定义,轻松调整字段类型和索引策略,无需停机迁移。
简单来说,RedisVL 让你像操作普通 Redis 键值对一样自然地处理向量数据,同时又保留了 Redis Search 模块的全部查询能力(标签、全文、数值范围等),实现了"混合搜索"的灵活性。
二、概述
在动手之前,先建立一些必要的概念框架。这些概念贯穿 RedisVL 的整个使用流程。
🏗️ 架构概览
RedisVL 处于应用层与 Redis 服务器之间,它扮演着 "智能翻译官" 的角色:
#mermaid-svg-AmwmNbbnmyoSYB0d{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-AmwmNbbnmyoSYB0d .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-AmwmNbbnmyoSYB0d .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-AmwmNbbnmyoSYB0d .error-icon{fill:#552222;}#mermaid-svg-AmwmNbbnmyoSYB0d .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-AmwmNbbnmyoSYB0d .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-AmwmNbbnmyoSYB0d .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-AmwmNbbnmyoSYB0d .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-AmwmNbbnmyoSYB0d .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-AmwmNbbnmyoSYB0d .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-AmwmNbbnmyoSYB0d .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-AmwmNbbnmyoSYB0d .marker{fill:#333333;stroke:#333333;}#mermaid-svg-AmwmNbbnmyoSYB0d .marker.cross{stroke:#333333;}#mermaid-svg-AmwmNbbnmyoSYB0d svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-AmwmNbbnmyoSYB0d p{margin:0;}#mermaid-svg-AmwmNbbnmyoSYB0d .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-AmwmNbbnmyoSYB0d .cluster-label text{fill:#333;}#mermaid-svg-AmwmNbbnmyoSYB0d .cluster-label span{color:#333;}#mermaid-svg-AmwmNbbnmyoSYB0d .cluster-label span p{background-color:transparent;}#mermaid-svg-AmwmNbbnmyoSYB0d .label text,#mermaid-svg-AmwmNbbnmyoSYB0d span{fill:#333;color:#333;}#mermaid-svg-AmwmNbbnmyoSYB0d .node rect,#mermaid-svg-AmwmNbbnmyoSYB0d .node circle,#mermaid-svg-AmwmNbbnmyoSYB0d .node ellipse,#mermaid-svg-AmwmNbbnmyoSYB0d .node polygon,#mermaid-svg-AmwmNbbnmyoSYB0d .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-AmwmNbbnmyoSYB0d .rough-node .label text,#mermaid-svg-AmwmNbbnmyoSYB0d .node .label text,#mermaid-svg-AmwmNbbnmyoSYB0d .image-shape .label,#mermaid-svg-AmwmNbbnmyoSYB0d .icon-shape .label{text-anchor:middle;}#mermaid-svg-AmwmNbbnmyoSYB0d .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-AmwmNbbnmyoSYB0d .rough-node .label,#mermaid-svg-AmwmNbbnmyoSYB0d .node .label,#mermaid-svg-AmwmNbbnmyoSYB0d .image-shape .label,#mermaid-svg-AmwmNbbnmyoSYB0d .icon-shape .label{text-align:center;}#mermaid-svg-AmwmNbbnmyoSYB0d .node.clickable{cursor:pointer;}#mermaid-svg-AmwmNbbnmyoSYB0d .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-AmwmNbbnmyoSYB0d .arrowheadPath{fill:#333333;}#mermaid-svg-AmwmNbbnmyoSYB0d .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-AmwmNbbnmyoSYB0d .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-AmwmNbbnmyoSYB0d .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-AmwmNbbnmyoSYB0d .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-AmwmNbbnmyoSYB0d .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-AmwmNbbnmyoSYB0d .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-AmwmNbbnmyoSYB0d .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-AmwmNbbnmyoSYB0d .cluster text{fill:#333;}#mermaid-svg-AmwmNbbnmyoSYB0d .cluster span{color:#333;}#mermaid-svg-AmwmNbbnmyoSYB0d div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-AmwmNbbnmyoSYB0d .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-AmwmNbbnmyoSYB0d rect.text{fill:none;stroke-width:0;}#mermaid-svg-AmwmNbbnmyoSYB0d .icon-shape,#mermaid-svg-AmwmNbbnmyoSYB0d .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-AmwmNbbnmyoSYB0d .icon-shape p,#mermaid-svg-AmwmNbbnmyoSYB0d .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-AmwmNbbnmyoSYB0d .icon-shape .label rect,#mermaid-svg-AmwmNbbnmyoSYB0d .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-AmwmNbbnmyoSYB0d .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-AmwmNbbnmyoSYB0d .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-AmwmNbbnmyoSYB0d :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} RedisVL 核心组件
Schema 定义
SearchIndex 控制器
Query 构建器
Vectorizer 工具
你的 Python 应用
Redis Stack
(含 RediSearch 模块)
内存中的向量索引
(HNSW / FLAT)
结构化字段
(Tag / Text / Numeric)
- Schema:定义索引的"骨架"------包括索引名称、键前缀、每个字段的名称、类型及属性(如向量的维度、距离度量)。
- SearchIndex:核心操作类,负责创建/删除索引、加载数据、执行查询、管理记录。
- Query:构建查询条件,支持纯向量搜索、过滤(标签/数值/全文)以及混合搜索。
- Vectorizer:可选工具,用于将原始文本直接转换为向量,免去手动调用外部 API 的麻烦。
🔍 搜索与索引
RedisVL 的索引基于 Redis 的 二级索引 机制,每个文档对应一个 Redis Hash(或 JSON)对象,字段被分别索引。对于向量字段,Redis 会额外构建一个独立的向量索引(HNSW 或 FLAT),实现高速最近邻检索。
字段类型:
tag:枚举型标签,适合分类过滤(如gender: male)。text:全文搜索字段,支持分词和相关性排序。numeric:数值范围过滤(如age > 18)。vector:向量字段,需指定维度、距离度量(余弦、内积、欧氏)和算法(FLAT 或 HNSW)。
存储类型:默认使用 Hash 存储,未来将支持 JSON,以处理更复杂的嵌套结构。
🔄 索引迁移(更新)
业务需求不断变化,你可能需要添加新字段、修改向量算法或调整距离度量。RedisVL 允许你以最小代价更新索引:
- 使用
index.create(overwrite=True, drop=False)可以在保留原有数据的同时重建索引结构。 - 背后的原理是:Redis 会在后台重新索引已有数据,期间查询仍然可用(最终一致性)。这种"零停机迁移"能力对于生产环境至关重要。
🏷️ 字段属性
每个字段可以附加属性来精细控制索引行为:
sortable:使该字段可排序(用于ORDER BY)。no_index:不对该字段建立索引,仅存储(节省内存)。index_missing:是否索引缺失值(用于查询"字段不存在"的记录)。
🔎 查询类型
RedisVL 支持多种查询模式,满足不同场景:
- 纯向量搜索:给定一个向量,返回最相似的 K 个结果。
- 过滤搜索:先通过标签/数值/全文条件筛选,再在候选集内进行向量检索(预过滤)或后过滤(根据性能权衡)。
- 混合搜索:将向量相似度与文本相关性(BM25)等分数加权组合,实现"语义 + 关键字"的排序。
- 多向量查询:允许一次查询中传入多个向量,分别计算距离(例如多模态检索)。
🧠 MCP(模型上下文协议)
RedisVL 支持将已有索引暴露给 MCP 客户端,通过标准化的工具合约,让外部 AI 代理能够直接与 Redis 交互,无需编写额外代码。这为构建 Agent 应用提供了坚实的数据层基础。
🧩 扩展组件
RedisVL 内置了几个实用模式,加速常见 AI 场景的开发:
- 缓存(LangCache):用 Redis 作为 LLM 响应的缓存层,减少 API 调用成本和延迟。
- 消息历史:存储对话历史,支持上下文窗口管理。
- 语义路由:根据查询的语义自动选择不同的下游处理流程。
三、安装与配置
基础安装
RedisVL 要求 Python 3.10+,推荐使用 pip 安装:
bash
pip install -U redisvl
默认安装只包含核心依赖。如果你需要使用特定的嵌入模型或高级功能,可按需安装额外组件:
bash
# 嵌入提供方
pip install redisvl[openai] # OpenAI
pip install redisvl[cohere] # Cohere(含重排序)
pip install redisvl[mistralai]
pip install redisvl[voyageai]
pip install redisvl[sentence-transformers] # 本地 HuggingFace 模型
pip install redisvl[vertexai] # Google Vertex
pip install redisvl[bedrock] # AWS Bedrock
# 其他特性
pip install redisvl[mcp] # MCP 服务器支持
pip install redisvl[langcache] # LangCache 托管服务
pip install redisvl[sql-redis] # SQL 风格查询
# 一次性安装全部
pip install redisvl[all]
ZSH 用户注意 :由于方括号在 ZSH 中有特殊含义,需要转义:
pip install redisvl\[openai\]
源码安装(开发者模式)
如果你希望贡献代码或获取最新特性,可以克隆仓库并安装:
bash
git clone https://github.com/redis/redis-vl-python.git && cd redis-vl-python
pip install -e . # 可编辑安装
使用 uv 管理全部依赖(含开发工具):
bash
pip install uv
uv sync
启动 Redis 实例
RedisVL 需要 Redis Stack(包含 RediSearch 模块)。推荐以下方式:
-
Redis Cloud(免费托管):注册即用,无需运维。
-
Docker 本地开发 :
bashdocker run -d --name redis -p 6379:6379 -p 8001:8001 redis/redis-stack:latest其中
8001端口提供 Redis Insight 图形化管理界面,方便调试。 -
Redis 8+ 精简版 (仅核心搜索):
bashdocker run -d --name redis -p 6379:6379 redis:8.4 -
Redis Software 企业版:适用于 Kubernetes 环境,通过 Operator 部署。
高可用连接 :RedisVL 支持通过 Sentinel 连接,使用 redis+sentinel:// URL 格式:
python
from redisvl.index import SearchIndex
index = SearchIndex.from_yaml(
"schema.yaml",
redis_url="redis+sentinel://sentinel1:26379,sentinel2:26379/mymaster/0"
)
四、快速上手:一个完整的向量搜索示例
下面我们通过一个"用户画像"数据集,逐步演示 RedisVL 的核心工作流。
1. 定义索引模式(Schema)
我们有一个用户集合,包含姓名、职业、年龄、信用评分和一个 3 维的用户嵌入向量(此处仅为演示,实际场景可能用 768 维或更高)。
方式一:YAML 文件(推荐,便于版本控制和复用)
yaml
# schema.yaml
version: '0.1.0'
index:
name: user_simple # 索引名称
prefix: user_simple_docs # 所有键的前缀
fields:
- name: user
type: tag # 标签,用于精确过滤
- name: credit_score
type: tag
- name: job
type: text # 全文搜索
- name: age
type: numeric
- name: user_embedding
type: vector
attrs:
algorithm: flat # 也可用 hnsw
dims: 3
distance_metric: cosine
datatype: float32
方式二:Python 字典(适合动态构建)
python
schema = {
"index": {"name": "user_simple", "prefix": "user_simple_docs"},
"fields": [
{"name": "user", "type": "tag"},
{"name": "credit_score", "type": "tag"},
{"name": "job", "type": "text"},
{"name": "age", "type": "numeric"},
{
"name": "user_embedding",
"type": "vector",
"attrs": {
"dims": 3,
"distance_metric": "cosine",
"algorithm": "flat",
"datatype": "float32"
}
}
]
}
2. 准备示例数据
我们构造三条用户记录,并将向量转换为 Redis 可存储的字节格式(使用 numpy):
python
import numpy as np
data = [
{
'user': 'john',
'age': 1,
'job': 'engineer',
'credit_score': 'high',
'user_embedding': np.array([0.1, 0.1, 0.5], dtype=np.float32).tobytes()
},
{
'user': 'mary',
'age': 2,
'job': 'doctor',
'credit_score': 'low',
'user_embedding': np.array([0.1, 0.1, 0.5], dtype=np.float32).tobytes()
},
{
'user': 'joe',
'age': 3,
'job': 'dentist',
'credit_score': 'medium',
'user_embedding': np.array([0.9, 0.9, 0.1], dtype=np.float32).tobytes()
}
]
在生产中,向量通常由预训练模型(如 Sentence-BERT)或 API(如
text-embedding-ada-002)生成,你只需将原始文本传入Vectorizer即可自动转换。
3. 创建 SearchIndex 并连接 Redis
python
from redisvl.index import SearchIndex
# 方式一:让 SearchIndex 自动管理连接
index = SearchIndex.from_dict(schema, redis_url="redis://localhost:6379")
# 方式二:使用已有的 Redis 客户端(可共享连接池)
# from redis import Redis
# client = Redis.from_url("redis://localhost:6379")
# index = SearchIndex.from_dict(schema, redis_client=client)
# 创建索引(如果存在则覆盖)
index.create(overwrite=True)
创建后,你可以用命令行工具 rvl 查看索引信息:
bash
rvl index info -i user_simple
4. 加载数据
将数据批量插入 Redis:
python
keys = index.load(data) # 默认自动生成唯一 ID(前缀 + ULID)
print(keys)
输出类似:
['user_simple_docs:01KHKHQYX95EDQN18FG8FRMRQ5', ...]
你也可以指定一个字段作为文档 ID(例如 user 字段):
python
index.load(data, id_field="user") # 此时键为 user_simple_docs:john
数据校验:RedisVL 内置 Pydantic 校验,若数据不符合 schema(如向量类型错误),会抛出明确的异常,防止脏数据污染索引。
5. 执行向量相似性搜索
假设我们有一个查询向量 [0.1, 0.1, 0.5],想找出最相似的 3 个用户:
python
from redisvl.query import VectorQuery
query = VectorQuery(
vector=[0.1, 0.1, 0.5],
vector_field_name="user_embedding",
return_fields=["user", "age", "job", "credit_score", "vector_distance"],
num_results=3
)
results = index.query(query)
for res in results:
print(res)
结果会包含每个文档的字段以及 vector_distance(此处为余弦距离,0 表示完全相同)。
#mermaid-svg-tIesxyAslH1XS2rg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-tIesxyAslH1XS2rg .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-tIesxyAslH1XS2rg .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-tIesxyAslH1XS2rg .error-icon{fill:#552222;}#mermaid-svg-tIesxyAslH1XS2rg .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-tIesxyAslH1XS2rg .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-tIesxyAslH1XS2rg .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-tIesxyAslH1XS2rg .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-tIesxyAslH1XS2rg .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-tIesxyAslH1XS2rg .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-tIesxyAslH1XS2rg .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-tIesxyAslH1XS2rg .marker{fill:#333333;stroke:#333333;}#mermaid-svg-tIesxyAslH1XS2rg .marker.cross{stroke:#333333;}#mermaid-svg-tIesxyAslH1XS2rg svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-tIesxyAslH1XS2rg p{margin:0;}#mermaid-svg-tIesxyAslH1XS2rg .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-tIesxyAslH1XS2rg .cluster-label text{fill:#333;}#mermaid-svg-tIesxyAslH1XS2rg .cluster-label span{color:#333;}#mermaid-svg-tIesxyAslH1XS2rg .cluster-label span p{background-color:transparent;}#mermaid-svg-tIesxyAslH1XS2rg .label text,#mermaid-svg-tIesxyAslH1XS2rg span{fill:#333;color:#333;}#mermaid-svg-tIesxyAslH1XS2rg .node rect,#mermaid-svg-tIesxyAslH1XS2rg .node circle,#mermaid-svg-tIesxyAslH1XS2rg .node ellipse,#mermaid-svg-tIesxyAslH1XS2rg .node polygon,#mermaid-svg-tIesxyAslH1XS2rg .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-tIesxyAslH1XS2rg .rough-node .label text,#mermaid-svg-tIesxyAslH1XS2rg .node .label text,#mermaid-svg-tIesxyAslH1XS2rg .image-shape .label,#mermaid-svg-tIesxyAslH1XS2rg .icon-shape .label{text-anchor:middle;}#mermaid-svg-tIesxyAslH1XS2rg .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-tIesxyAslH1XS2rg .rough-node .label,#mermaid-svg-tIesxyAslH1XS2rg .node .label,#mermaid-svg-tIesxyAslH1XS2rg .image-shape .label,#mermaid-svg-tIesxyAslH1XS2rg .icon-shape .label{text-align:center;}#mermaid-svg-tIesxyAslH1XS2rg .node.clickable{cursor:pointer;}#mermaid-svg-tIesxyAslH1XS2rg .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-tIesxyAslH1XS2rg .arrowheadPath{fill:#333333;}#mermaid-svg-tIesxyAslH1XS2rg .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-tIesxyAslH1XS2rg .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-tIesxyAslH1XS2rg .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-tIesxyAslH1XS2rg .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-tIesxyAslH1XS2rg .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-tIesxyAslH1XS2rg .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-tIesxyAslH1XS2rg .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-tIesxyAslH1XS2rg .cluster text{fill:#333;}#mermaid-svg-tIesxyAslH1XS2rg .cluster span{color:#333;}#mermaid-svg-tIesxyAslH1XS2rg div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-tIesxyAslH1XS2rg .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-tIesxyAslH1XS2rg rect.text{fill:none;stroke-width:0;}#mermaid-svg-tIesxyAslH1XS2rg .icon-shape,#mermaid-svg-tIesxyAslH1XS2rg .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-tIesxyAslH1XS2rg .icon-shape p,#mermaid-svg-tIesxyAslH1XS2rg .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-tIesxyAslH1XS2rg .icon-shape .label rect,#mermaid-svg-tIesxyAslH1XS2rg .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-tIesxyAslH1XS2rg .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-tIesxyAslH1XS2rg .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-tIesxyAslH1XS2rg :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 查询向量
VectorQuery
SearchIndex.query
Redis 执行向量检索
返回 K 个最近邻
你的应用
性能调优 :对于 HNSW 索引,可以设置运行时参数 ef_runtime 来平衡召回率与速度:
python
query = VectorQuery(
...,
ef_runtime=100 # 值越大,召回率越高但耗时增加
)
6. 记录管理
- 获取单个文档 :
index.fetch("john") - 列出所有键 :使用
paginate()分页遍历 - 删除文档 :
index.drop_documents("mary")(按 ID)或index.drop_keys("user_simple_docs:mary")(按完整键)
7. 更新索引模式
业务演进后,你可能希望将 job 从全文改为标签,并将向量算法从 FLAT 升级为 HNSW。RedisVL 支持原地更新:
python
# 移除旧字段,添加新字段
index.schema.remove_field("job")
index.schema.remove_field("user_embedding")
index.schema.add_fields([
{"name": "job", "type": "tag"},
{
"name": "user_embedding",
"type": "vector",
"attrs": {
"dims": 3,
"distance_metric": "cosine",
"algorithm": "hnsw",
"datatype": "float32"
}
}
])
# 重建索引,但保留已有数据(drop=False)
index.create(overwrite=True, drop=False)
此时,Redis 会利用现有数据重新构建索引,整个过程无需停机。
五、异步编程支持
在高并发场景下,建议使用异步客户端以最大化性能。RedisVL 提供了 AsyncSearchIndex:
python
from redisvl.index import AsyncSearchIndex
from redis.asyncio import Redis
client = Redis.from_url("redis://localhost:6379")
async_index = AsyncSearchIndex.from_dict(schema, redis_client=client)
# 异步加载数据
await async_index.load(data)
# 异步查询
results = await async_index.query(query)
异步模式与同步模式 API 基本一致,适合与 FastAPI、aiohttp 等框架配合。
六、集成 Vectorizer:让向量生成更简单
手动将文本转为向量再转为字节流有些繁琐。RedisVL 内置了针对各大 AI 提供商的 Vectorizer,帮你一键完成:
python
from redisvl.utils.vectorize import OpenAITextVectorizer
vectorizer = OpenAITextVectorizer(
model="text-embedding-ada-002",
api_key="your-api-key"
)
text = "I love Redis!"
embedding = vectorizer.embed(text) # 返回 numpy 数组,可直接用于查询
你还可以在加载数据时,通过 preprocess 钩子自动向量化字段,实现"原始文本入库,向量自动生成"的流畅体验。
七、CLI 工具:运维好帮手
RedisVL 提供了强大的命令行界面 rvl,让你无需编写 Python 代码即可管理索引:
bash
# 查看所有索引
rvl index list
# 显示索引详情
rvl index info -i user_simple
# 查看索引统计(文档数、内存占用等)
rvl stats -i user_simple
# 删除索引
rvl index delete -i user_simple
这对于 DBA 和运维人员极为友好,可以快速定位问题。
八、最佳实践与注意事项
- 向量维度选择:并非越高越好,高维度会增大内存和计算开销。通常 256~768 维在多数任务中表现良好。
- 距离度量:余弦距离适合归一化向量;内积适合非归一化但要求速度的场景;欧氏距离适合物理空间相似性。
- 索引算法 :
FLAT:暴力搜索,精确但慢,适合小数据集(<10万)。HNSW:基于图的近似搜索,速度快,适合百万级以上,但构建和内存开销较大。
- 内存规划 :向量索引占用内存约为
向量维度 × 4字节 × 文档数 × (1 + HNSW额外开销),务必提前评估。 - 批量加载 :使用
load方法时尽量批量(如每次 1000 条)以减少网络往返。 - 监控 :定期使用
rvl stats查看索引健康度,结合 Redis 的INFO命令监控内存和 CPU。
九、总结
RedisVL 不仅是一个向量库,更是一个将 Redis 转变为 AI 原生数据库的桥梁。通过其简洁的 API、灵活的 schema 管理、丰富的生态集成以及强大的性能,它让开发者能够专注在业务逻辑而非基础设施上,无论你是构建下一代推荐系统、智能客服还是多模态搜索。
下一步:
- 访问官方文档获取更高级的查询语法(如混合搜索、聚合)。
- 尝试将 RedisVL 与 LangChain 或 LlamaIndex 结合,快速搭建 RAG 应用。