Redis 向量存储
本笔记本介绍如何开始使用 Redis 向量存储。
Redis 是一个流行的开源内存数据结构存储,可用作数据库、缓存、消息代理和队列。它现在包含了向量相似性搜索功能,使其适合用作向量存储。
Redis 是什么?
大多数开发者都熟悉 Redis。其核心是一个属于键值对家族的 NoSQL 数据库,可以作为缓存、消息队列、流处理和主数据库使用。开发者选择 Redis 是因为它速度快,拥有大量的客户端库生态系统,并且已被大型企业部署多年。
除了这些传统用例之外,Redis 还提供了诸如搜索和查询等附加功能,允许用户在 Redis 中创建二级索引结构。这使得 Redis 能够成为一个向量数据库,并拥有缓存般的速度。
Redis 作为向量数据库
Redis 使用压缩的倒排索引,以便以低的内存占用快速索引。它还支持许多高级功能,例如:
- 索引 Redis 哈希和
JSON中的多个字段 - 向量相似性搜索(使用
HNSW(ANN) 或FLAT(KNN)) - 向量范围搜索(例如,查找查询向量半径内的所有向量)
- 在不损失性能的情况下进行增量索引
- 文档排名(使用 tf-idf,可选用户提供的权重)
- 字段加权
- 使用
AND、OR和NOT操作符的复杂布尔查询 - 前缀匹配、模糊匹配和精确短语查询
- 支持 double-metaphone 音译匹配
- 自动完成建议(支持模糊前缀建议)
- 基于词干的查询扩展(支持 多种语言)(使用 Snowball)
- 支持中文分词和查询(使用 Friso)
- 数字过滤器和范围
- 使用 Redis 地理空间索引进行地理空间搜索
- 功能强大的聚合引擎
- 支持所有
utf-8编码的文本 - 检索完整文档、选定字段或仅文档 ID
- 结果排序(例如,按创建日期)
客户端
由于 Redis 不仅仅是一个向量数据库,因此经常会有一些用例需要使用 LangChain 集成之外的 Redis 客户端。您可以使用任何标准的 Redis 客户端库来运行搜索和查询命令,但最简单的方法是使用封装了搜索和查询 API 的库。以下是一些示例,您可以在 此处 找到更多客户端库。
| 项目 | 语言 | 许可证 | 作者 | 星标 |
|---|---|---|---|---|
| jedis | Java | MIT | Redis | |
| redisvl | Python | MIT | Redis | |
| redis-py | Python | MIT | Redis | |
| node-redis | Node.js | MIT | Redis | |
| nredisstack | .NET | MIT | Redis |
部署选项
有许多方法可以部署带有 RediSearch 的 Redis。最简单的入门方法是使用 Docker,但还有许多其他的部署选项,例如:
- Redis Cloud
- Docker (Redis Stack)
- 云市场:AWS Marketplace, Google Marketplace, 或 Azure Marketplace
- 本地部署:Redis Enterprise Software
- Kubernetes:Redis Enterprise Software on Kubernetes
Redis 连接 URL 模式
有效的 Redis URL 模式为:
redis://- 连接到独立的 Redis,未加密rediss://- 连接到独立的 Redis,使用 TLS 加密redis+sentinel://- 通过 Redis Sentinel 连接到 Redis 服务器,未加密rediss+sentinel://- 通过 Redis Sentinel 连接到 Redis 服务器,两种连接均使用 TLS 加密
有关其他连接参数的更多信息,请参阅 redis-py 文档。
设置
要使用 RedisVectorStore,您需要安装 langchain-redis 合作包,以及本 notebook 中使用的其他包。
%pip install -qU langchain-redis langchain-huggingface sentence-transformers scikit-learn
Note: you may need to restart the kernel to use updated packages.
凭证
Redis 连接凭证作为 Redis 连接 URL 的一部分传递。Redis 连接 URL 非常灵活,可以适应各种 Redis 服务器的拓扑结构和身份验证方法。这些 URL 遵循特定的格式,其中包括连接协议、身份验证详细信息、主机、端口和数据库信息。 Redis 连接 URL 的基本结构是:
[protocol]://[auth]@[host]:[port]/[database]
其中:
- protocol 可以是
redis(用于标准连接)、rediss(用于 SSL/TLS 连接)或redis+sentinel(用于 Sentinel 连接)。 - auth 包括用户名和密码(如果适用)。
- host 是 Redis 服务器的主机名或 IP 地址。
- port 是 Redis 服务器的端口。
- database 是 Redis 数据库编号。
Redis 连接 URL 支持各种配置,包括:
- 独立的 Redis 服务器(有或无身份验证)
- Redis Sentinel 设置
- SSL/TLS 加密连接
- 不同的身份验证方法(仅密码或用户名-密码)
以下是不同配置的 Redis 连接 URL 示例:
# connection to redis standalone at localhost, db 0, no password
redis_url = "redis://localhost:6379"
# connection to host "redis" port 7379 with db 2 and password "secret" (old style authentication scheme without username / pre 6.x)
redis_url = "redis://:secret@redis:7379/2"
# connection to host redis on default port with user "joe", pass "secret" using redis version 6+ ACLs
redis_url = "redis://joe:secret@redis/0"
# connection to sentinel at localhost with default group mymaster and db 0, no password
redis_url = "redis+sentinel://localhost:26379"
# connection to sentinel at host redis with default port 26379 and user "joe" with password "secret" with default group mymaster and db 0
redis_url = "redis+sentinel://joe:secret@redis"
# connection to sentinel, no auth with sentinel monitoring group "zone-1" and database 2
redis_url = "redis+sentinel://redis:26379/zone-1/2"
# connection to redis standalone at localhost, db 0, no password but with TLS support
redis_url = "rediss://localhost:6379"
# connection to redis sentinel at localhost and default port, db 0, no password
# but with TLS support for both Sentinel and Redis server
redis_url = "rediss+sentinel://localhost"
使用 Docker 启动 Redis 实例
要将 Redis 与 LangChain 结合使用,您需要一个正在运行的 Redis 实例。您可以使用 Docker 启动一个,命令如下:
docker run -d -p 6379:6379 redis/redis-stack:latest
在本示例中,我们将使用本地 Redis 实例。如果您使用的是远程实例,则需要相应地修改 Redis URL。
import os
REDIS_URL = os.getenv("REDIS_URL", "redis://localhost:6379")
print(f"Connecting to Redis at: {REDIS_URL}")
Connecting to Redis at: redis://redis:6379
要启用模型调用的自动跟踪,请设置您的 LangSmith API 密钥:
# os.environ["LANGSMITH_API_KEY"] = getpass.getpass("Enter your LangSmith API key: ")
# os.environ["LANGSMITH_TRACING"] = "true"
让我们通过 ping 通 Redis 来检查它是否已启动并正在运行:
import redis
redis_client = redis.from_url(REDIS_URL)
redis_client.ping()
True
示例数据
20 newsgroups 数据集包含大约 18000 篇关于 20 个主题的新闻帖子。本次演示我们将使用其中一部分,并专注于两个类别:“alt.atheism”(非神论)和“sci.space”(空间科学):
from langchain.docstore.document import Document
from sklearn.datasets import fetch_20newsgroups
categories = ["alt.atheism", "sci.space"]
newsgroups = fetch_20newsgroups(
subset="train", categories=categories, shuffle=True, random_state=42
)
# Use only the first 250 documents
texts = newsgroups.data[:250]
metadata = [
{"category": newsgroups.target_names[target]} for target in newsgroups.target[:250]
]
len(texts)
250
初始化
RedisVectorStore 实例可以通过几种方式进行初始化:
RedisVectorStore.__init__- 直接初始化RedisVectorStore.from_texts- 从文本列表(可选含元数据)初始化RedisVectorStore.from_documents- 从langchain_core.documents.Document对象列表初始化RedisVectorStore.from_existing_index- 从现有的 Redis 索引初始化
下面我们将使用 RedisConfig 实例通过 RedisVectorStore.__init__ 方法进行初始化。
pip install -qU langchain-openai
import getpass
import os
if not os.environ.get("OPENAI_API_KEY"):
os.environ["OPENAI_API_KEY"] = getpass.getpass("Enter API key for OpenAI: ")
from langchain_openai import OpenAIEmbeddings
embeddings = OpenAIEmbeddings(model="text-embedding-3-large")
我们将使用 SentenceTransformer 模型来创建嵌入。此模型在本地运行,无需 API 密钥。
from langchain_redis import RedisConfig, RedisVectorStore
config = RedisConfig(
index_name="newsgroups",
redis_url=REDIS_URL,
metadata_schema=[
{"name": "category", "type": "tag"},
],
)
vector_store = RedisVectorStore(embeddings, config=config)