Redis是一款功能强大的内存数据库,支持多种数据结构存储,包括字符串、哈希、列表、集合等。本文详细介绍了Redis的三大应用场景:作为内存数据结构存储、文档数据库和向量数据库。Redis不仅帮助传统键值查询,还能构建全文索引和向量索引,实现高效搜索和语义查询。此外,文章还阐述了Redis在RAG(检索增强生成)和GenAI应用中的关键作用,包括向量搜索、语义缓存和会话管理。最后

目录

一、简介

二、Redis数据类型

三、Redis 作为内存数据结构存储

3.1 在Redis中以键值对存储数据

3.2扫描键空间

四、Redis 作为文档数据库

4.1创建索引

4.2添加JSON文档

4.3 使用Redis 查询引擎进行搜索和查询

4.3.1 通配符查询

4.3.2 单项全文查询

4.3.3 精确匹配查询

五、Redis 作为向量数据库

5.1 创建Redis 向量数据库

5.1.1 获取演示数据

5.1.2 将演示数据存储在Redis中

5.1.3 选择文本嵌入模型

5.1.4 生成文本嵌入

5.2 创建索引

5.2.1 使用向量创建索引

5.2.2 检查索引状态

5.3 执行向量搜索

5.3.1 嵌入您的查询

5.3.2 K近邻(KNN)搜索

六、使用Redis的RAG

6.1 什么是检索增强生成(RAG)?

6.2 Redis 在 RAG 中的作用

6.3 使用 Redis 构建 RAG 应用程序

6.4 使用 Redis 实现 RAG 的好处

七、用于 GenAI 应用的 Redis

7.1介绍

7.2 Redis 在 GenAI 应用中的主要优势

7.3 GenAI 应用中的 Redis 用例

7.3.1 优化人工智能代理性能

7.3.2 聊天机器人开发与管理

7.3.3 将机器学习框架与 Redis 集成

7.3.4 推进自然语言处理

7.3.5 资源

八、常见问题

8.1Redis 与其他键值存储有何不同

8.2 Redis 的内存占用量是多少?

8.3 为什么 Redis 要将整个数据集保存在内存中?

8.4 Redis 可以与基于磁盘的数据库一起使用吗?

8.5 如何降低 Redis 的整体内存使用量?

8.6 如果 Redis 内存不足会发生什么?

8.7 Linux 系统下后台保存失败并出现 fork() 错误?

8.8 Redis 磁盘快照是原子性的吗?

8.9 Redis 如何利用多个 CPU 或核心?

8.10 单个 Redis 实例最多可以存储多少个键?哈希表、列表、集合和有序集合中最多可以包含多少个元素?

8.11 为什么我的副本实例的密钥数量与主实例不同?

九、连接Redis 客户端 API库

9.1 社区支持的客户端库

十、 使用 Redis 命令

10.1 命令结构

10.2 批处理命令

10.3 键和值

10.3.1 密匙内容

10.3.2 标签

10.3.3 修改和查询键空间


一、简介

Redis 可用作数据库、缓存、流式处理引擎、消息代理等等。以下快速入门指南将向您展示如何使用 Redis 实现以下特定用途:

1.数据结构存储

2.文档数据库

3.向量数据库

二、Redis数据类型

Redis 开源版 实现了一下数据类型:

string                               字符串
hash                                 哈希
List                                   列表
Set                                   集合
Sorted ser                        有序集合
Vector set                         向量集合
Stream                             流
Bitmap                             位图
Bitfield                             位域
Geospatial                       地理空间
JSON                              JSON
Probabilistic data types   概率
Time series                      时间序列

三、Redis 作为内存数据结构存储

3.1 在Redis中以键值对存储数据

Redis 代表远程字典服务器。

可以在 Redis 服务器端使用与本地编程环境相同的数据类型。

与字节数组类似,Redis 字符串存储字节序列,包括文本、序列化对象、计数器值和二进制数组。
以下示例展示了如何设置和获取字符串值:

SET bike:1 "Process 134"
GET bike:1

哈希表相当于字典(dict 或哈希映射)。哈希表可用于表示普通对象以及存储计数器分组等。
以下示例说明了如何设置和访问对象的字段值:

> HSET bike:1 model Deimos brand Ergonom type 'Enduro bikes' price 4972
(integer) 4
> HGET bike:1 model
"Deimos"
> HGET bike:1 price
"4972"
> HGETALL bike:1
1) "model"
2) "Deimos"
3) "brand"
4) "Ergonom"
5) "type"
6) "Enduro bikes"
7) "price"
8) "4972"

3.2扫描键空间

Redis 中的每个项目都有一个唯一的键。所有项目都存在于 Redis键空间中。

您可以使用SCAN 命令扫描 Redis 键空间。以下示例扫描前 100 个具有特定前缀的键bike:

SCAN 0 MATCH "bike:*" COUNT 100

四、Redis 作为文档数据库

4.1创建索引

Redis 允许您直接通过键访问数据项。虽然也可以使用其他数据结构(例如哈希表和有序集合)作为二级索引,但需要手动维护这些索引。

Redis 是一个文档数据库,允许您声明哪些字段需要自动建立索引。Redis 目前支持在哈希表JSON文档上创建二级索引。

以下示例展示了一个FT.CREATE命令,该命令创建了一个包含文本字段、数值字段(价格)和标签字段(条件)的索引。文本字段的权重为 1.0,这意味着它们在全文搜索中具有相同的相关性。字段名称遵循JSONPath规范。每个索引字段都映射到 JSON 文档中的一个属性。

> FT.CREATE idx:bicycle ON JSON PREFIX 1 bicycle: SCORE 1.0 SCHEMA $.brand AS brand TEXT WEIGHT 1.0 $.model AS model TEXT WEIGHT 1.0 $.description AS description TEXT WEIGHT 1.0 $.price AS price NUMERIC $.condition AS condition TAG SEPARATOR ,
OK

任何已存在的、具有特定键前缀的 JSON 文档bicycle:都会自动添加到索引中。此外,任何在索引创建后创建或修改的、具有该键前缀的 JSON 文档也会被添加或重新添加到索引中。

4.2添加JSON文档

示例:使用JSON.SET命令创建新的 JSON 文档

> JSON.SET "bicycle:0" "." "{\"brand\": \"Velorim\", \"model\": \"Jigger\", \"price\": 270, \"description\": \"Small and powerful, the Jigger is the best ride for the smallest of tikes! This is the tiniest kids\\u2019 pedal bike on the market available without a coaster brake, the Jigger is the vehicle of choice for the rare tenacious little rider raring to go.\", \"condition\": \"new\"}"
OK
> JSON.SET "bicycle:1" "." "{\"brand\": \"Bicyk\", \"model\": \"Hillcraft\", \"price\": 1200, \"description\": \"Kids want to ride with as little weight as possible. Especially on an incline! They may be at the age when a 27.5\\\" wheel bike is just too clumsy coming off a 24\\\" bike. The Hillcraft 26 is just the solution they need!\", \"condition\": \"used\"}"
OK
> JSON.SET "bicycle:2" "." "{\"brand\": \"Nord\", \"model\": \"Chook air 5\", \"price\": 815, \"description\": \"The Chook Air 5  gives kids aged six years and older a durable and uberlight mountain bike for their first experience on tracks and easy cruising through forests and fields. The lower  top tube makes it easy to mount and dismount in any situation, giving your kids greater safety on the trails.\", \"condition\": \"used\"}"
OK
> JSON.SET "bicycle:3" "." "{\"brand\": \"Eva\", \"model\": \"Eva 291\", \"price\": 3400, \"description\": \"The sister company to Nord, Eva launched in 2005 as the first and only women-dedicated bicycle brand. Designed by women for women, allEva bikes are optimized for the feminine physique using analytics from a body metrics database. If you like 29ers, try the Eva 291. It\\u2019s a brand new bike for 2022.. This full-suspension, cross-country ride has been designed for velocity. The 291 has 100mm of front and rear travel, a superlight aluminum frame and fast-rolling 29-inch wheels. Yippee!\", \"condition\": \"used\"}"
OK
> JSON.SET "bicycle:4" "." "{\"brand\": \"Noka Bikes\", \"model\": \"Kahuna\", \"price\": 3200, \"description\": \"Whether you want to try your hand at XC racing or are looking for a lively trail bike that's just as inspiring on the climbs as it is over rougher ground, the Wilder is one heck of a bike built specifically for short women. Both the frames and components have been tweaked to include a women\\u2019s saddle, different bars and unique colourway.\", \"condition\": \"used\"}"
OK
> JSON.SET "bicycle:5" "." "{\"brand\": \"Breakout\", \"model\": \"XBN 2.1 Alloy\", \"price\": 810, \"description\": \"The XBN 2.1 Alloy is our entry-level road bike \\u2013 but that\\u2019s not to say that it\\u2019s a basic machine. With an internal weld aluminium frame, a full carbon fork, and the slick-shifting Claris gears from Shimano\\u2019s, this is a bike which doesn\\u2019t break the bank and delivers craved performance.\", \"condition\": \"new\"}"
OK
> JSON.SET "bicycle:6" "." "{\"brand\": \"ScramBikes\", \"model\": \"WattBike\", \"price\": 2300, \"description\": \"The WattBike is the best e-bike for people who still feel young at heart. It has a Bafang 1000W mid-drive system and a 48V 17.5AH Samsung Lithium-Ion battery, allowing you to ride for more than 60 miles on one charge. It\\u2019s great for tackling hilly terrain or if you just fancy a more leisurely ride. With three working modes, you can choose between E-bike, assisted bicycle, and normal bike modes.\", \"condition\": \"new\"}"
OK
> JSON.SET "bicycle:7" "." "{\"brand\": \"Peaknetic\", \"model\": \"Secto\", \"price\": 430, \"description\": \"If you struggle with stiff fingers or a kinked neck or back after a few minutes on the road, this lightweight, aluminum bike alleviates those issues and allows you to enjoy the ride. From the ergonomic grips to the lumbar-supporting seat position, the Roll Low-Entry offers incredible comfort. The rear-inclined seat tube facilitates stability by allowing you to put a foot on the ground to balance at a stop, and the low step-over frame makes it accessible for all ability and mobility levels. The saddle is very soft, with a wide back to support your hip joints and a cutout in the center to redistribute that pressure. Rim brakes deliver satisfactory braking control, and the wide tires provide a smooth, stable ride on paved roads and gravel. Rack and fender mounts facilitate setting up the Roll Low-Entry as your preferred commuter, and the BMX-like handlebar offers space for mounting a flashlight, bell, or phone holder.\", \"condition\": \"new\"}"
OK
> JSON.SET "bicycle:8" "." "{\"brand\": \"nHill\", \"model\": \"Summit\", \"price\": 1200, \"description\": \"This budget mountain bike from nHill performs well both on bike paths and on the trail. The fork with 100mm of travel absorbs rough terrain. Fat Kenda Booster tires give you grip in corners and on wet trails. The Shimano Tourney drivetrain offered enough gears for finding a comfortable pace to ride uphill, and the Tektro hydraulic disc brakes break smoothly. Whether you want an affordable bike that you can take to work, but also take trail in mountains on the weekends or you\\u2019re just after a stable, comfortable ride for the bike path, the Summit gives a good value for money.\", \"condition\": \"new\"}"
OK
> JSON.SET "bicycle:9" "." "{\"model\": \"ThrillCycle\", \"brand\": \"BikeShind\", \"price\": 815, \"description\": \"An artsy,  retro-inspired bicycle that\\u2019s as functional as it is pretty: The ThrillCycle steel frame offers a smooth ride. A 9-speed drivetrain has enough gears for coasting in the city, but we wouldn\\u2019t suggest taking it to the mountains. Fenders protect you from mud, and a rear basket lets you transport groceries, flowers and books. The ThrillCycle comes with a limited lifetime warranty, so this little guy will last you long past graduation.\", \"condition\": \"refurbished\"}"
OK

4.3 使用Redis 查询引擎进行搜索和查询

4.3.1 通配符查询

FT.SEARCH命令检索所有已索引的文档。请注意LIMIT以下子句,它允许对结果进行分页。

> FT.SEARCH "idx:bicycle" "*" LIMIT 0 10
1) (integer) 10
 2) "bicycle:1"
 3) 1) "$"
    2) "{\"brand\":\"Bicyk\",\"model\":\"Hillcraft\",\"price\":1200,\"description\":\"Kids want to ride with as little weight as possible. Especially on an incline! They may be at the age when a 27.5\\\" wheel bike is just too clumsy coming off a 24\\\" bike. The Hillcraft 26 is just the solution they need!\",\"condition\":\"used\"}"
 4) "bicycle:2"
 5) 1) "$"
    2) "{\"brand\":\"Nord\",\"model\":\"Chook air 5\",\"price\":815,\"description\":\"The Chook Air 5  gives kids aged six years and older a durable and uberlight mountain bike for their first experience on tracks and easy cruising through forests and fields. The lower  top tube makes it easy to mount and dismount in any situation, giving your kids greater safety on the trails.\",\"condition\":\"used\"}"
 6) "bicycle:4"
 7) 1) "$"
    2) "{\"brand\":\"Noka Bikes\",\"model\":\"Kahuna\",\"price\":3200,\"description\":\"Whether you want to try your hand at XC racing or are looking for a lively trail bike that's just as inspiring on the climbs as it is over rougher ground, the Wilder is one heck of a bike built specifically for short women. Both the frames and components have been tweaked to include a women\xe2\x80\x99s saddle, different bars and unique colourway.\",\"condition\":\"used\"}"
 8) "bicycle:5"
 9) 1) "$"
    2) "{\"brand\":\"Breakout\",\"model\":\"XBN 2.1 Alloy\",\"price\":810,\"description\":\"The XBN 2.1 Alloy is our entry-level road bike \xe2\x80\x93 but that\xe2\x80\x99s not to say that it\xe2\x80\x99s a basic machine. With an internal weld aluminium frame, a full carbon fork, and the slick-shifting Claris gears from Shimano\xe2\x80\x99s, this is a bike which doesn\xe2\x80\x99t break the bank and delivers craved performance.\",\"condition\":\"new\"}"
10) "bicycle:0"
11) 1) "$"
    2) "{\"brand\":\"Velorim\",\"model\":\"Jigger\",\"price\":270,\"description\":\"Small and powerful, the Jigger is the best ride for the smallest of tikes! This is the tiniest kids\xe2\x80\x99 pedal bike on the market available without a coaster brake, the Jigger is the vehicle of choice for the rare tenacious little rider raring to go.\",\"condition\":\"new\"}"
12) "bicycle:6"
13) 1) "$"
    2) "{\"brand\":\"ScramBikes\",\"model\":\"WattBike\",\"price\":2300,\"description\":\"The WattBike is the best e-bike for people who still feel young at heart. It has a Bafang 1000W mid-drive system and a 48V 17.5AH Samsung Lithium-Ion battery, allowing you to ride for more than 60 miles on one charge. It\xe2\x80\x99s great for tackling hilly terrain or if you just fancy a more leisurely ride. With three working modes, you can choose between E-bike, assisted bicycle, and normal bike modes.\",\"condition\":\"new\"}"
14) "bicycle:7"
15) 1) "$"
    2) "{\"brand\":\"Peaknetic\",\"model\":\"Secto\",\"price\":430,\"description\":\"If you struggle with stiff fingers or a kinked neck or back after a few minutes on the road, this lightweight, aluminum bike alleviates those issues and allows you to enjoy the ride. From the ergonomic grips to the lumbar-supporting seat position, the Roll Low-Entry offers incredible comfort. The rear-inclined seat tube facilitates stability by allowing you to put a foot on the ground to balance at a stop, and the low step-over frame makes it accessible for all ability and mobility levels. The saddle is very soft, with a wide back to support your hip joints and a cutout in the center to redistribute that pressure. Rim brakes deliver satisfactory braking control, and the wide tires provide a smooth, stable ride on paved roads and gravel. Rack and fender mounts facilitate setting up the Roll Low-Entry as your preferred commuter, and the BMX-like handlebar offers space for mounting a flashlight, bell, or phone holder.\",\"condition\":\"new\"}"
16) "bicycle:9"
17) 1) "$"
    2) "{\"model\":\"ThrillCycle\",\"brand\":\"BikeShind\",\"price\":815,\"description\":\"An artsy,  retro-inspired bicycle that\xe2\x80\x99s as functional as it is pretty: The ThrillCycle steel frame offers a smooth ride. A 9-speed drivetrain has enough gears for coasting in the city, but we wouldn\xe2\x80\x99t suggest taking it to the mountains. Fenders protect you from mud, and a rear basket lets you transport groceries, flowers and books. The ThrillCycle comes with a limited lifetime warranty, so this little guy will last you long past graduation.\",\"condition\":\"refurbished\"}"
18) "bicycle:3"
19) 1) "$"
    2) "{\"brand\":\"Eva\",\"model\":\"Eva 291\",\"price\":3400,\"description\":\"The sister company to Nord, Eva launched in 2005 as the first and only women-dedicated bicycle brand. Designed by women for women, allEva bikes are optimized for the feminine physique using analytics from a body metrics database. If you like 29ers, try the Eva 291. It\xe2\x80\x99s a brand new bike for 2022.. This full-suspension, cross-country ride has been designed for velocity. The 291 has 100mm of front and rear travel, a superlight aluminum frame and fast-rolling 29-inch wheels. Yippee!\",\"condition\":\"used\"}"
20) "bicycle:8"
21) 1) "$"
    2) "{\"brand\":\"nHill\",\"model\":\"Summit\",\"price\":1200,\"description\":\"This budget mountain bike from nHill performs well both on bike paths and on the trail. The fork with 100mm of travel absorbs rough terrain. Fat Kenda Booster tires give you grip in corners and on wet trails. The Shimano Tourney drivetrain offered enough gears for finding a comfortable pace to ride uphill, and the Tektro hydraulic disc brakes break smoothly. Whether you want an affordable bike that you can take to work, but also take trail in mountains on the weekends or you\xe2\x80\x99re just after a stable, comfortable ride for the bike path, the Summit gives a good value for money.\",\"condition\":\"new\"}"

4.3.2 单项全文查询

> FT.SEARCH "idx:bicycle" "@model:Jigger" LIMIT 0 10
1) (integer) 1
2) "bicycle:0"
3) 1) "$"
   2) "{\"brand\":\"Velorim\",\"model\":\"Jigger\",\"price\":270,\"description\":\"Small and powerful, the Jigger is the best ride for the smallest of tikes! This is the tiniest kids\xe2\x80\x99 pedal bike on the market available without a coaster brake, the Jigger is the vehicle of choice for the rare tenacious little rider raring to go.\",\"condition\":\"new\"}"

4.3.3 精确匹配查询

> FT.SEARCH "idx:bicycle" "@brand:\"Noka Bikes\"" LIMIT 0 10
1) (integer) 1
2) "bicycle:4"
3) 1) "$"
   2) "{\"brand\":\"Noka Bikes\",\"model\":\"Kahuna\",\"price\":3200,\"description\":\"Whether you want to try your hand at XC racing or are looking for a lively trail bike that's just as inspiring on the climbs as it is over rougher ground, the Wilder is one heck of a bike built specifically for short women. Both the frames and components have been tweaked to include a women\xe2\x80\x99s saddle, different bars and unique colourway.\",\"condition\":\"used\"}"

五、Redis 作为向量数据库

数据通常是非结构化的,这意味着它没有明确的模式来描述。非结构化数据的例子包括文本段落、图像、视频或音频。存储和搜索非结构化数据的一种方法是使用向量嵌入。

什么是向量?在机器学习和人工智能领域,向量是表示数据的数字序列。它们是模型的输入和输出,以数值形式封装了底层信息。向量可以将非结构化数据(例如文本、图像、视频和音频)转换为机器学习模型可以处理的格式。

  • 为什么向量如此重要?向量能够捕捉数据中固有的复杂模式和语义含义,使其成为各种应用的强大工具。它们使机器学习模型能够更有效地理解和处理非结构化数据。
  • 增强传统搜索。传统的关键词或词汇搜索依赖于单词或短语的精确匹配,这存在一定的局限性。相比之下,向量搜索或语义搜索则利用了向量嵌入中蕴含的丰富信息。通过将数据映射到向量空间,可以根据词义将相似的条目排列在一起。这种方法能够提供更准确、更有意义的搜索结果,因为它不仅考虑查询中使用的确切词语,还考虑查询的上下文和语义内容。

5.1 创建Redis 向量数据库

  • 将向量及其关联的元数据存储在哈希表或JSON文档中
  • 创建和配置搜索的二级索引
  • 执行向量搜索
  • 更新向量和元数据
  • 删除和清理

示例文档

{
  "model": "Jigger",
  "brand": "Velorim",
  "price": 270,
  "type": "Kids bikes",
  "specs": {
    "material": "aluminium",
    "weight": "10"
  },
  "description": "Small and powerful, the Jigger is the best ride for the smallest of tikes! ..."
}

该description字段包含自行车的自由文本描述,并将用于创建矢量嵌入。

5.1.1 获取演示数据

需要先获取示例数据集,并将其作为 JSON 数组提供:

URL = ("https://raw.githubusercontent.com/bsbodden/redis_vss_getting_started"
       "/main/data/bikes.json"
       )
response = requests.get(URL, timeout=10)
bikes = response.json()

检查其中一个自行车JSON文档的结构:

json.dumps(bikes[0], indent=2)

5.1.2 将演示数据存储在Redis中

现在遍历数组,使用JSON.SETbikes命令 将数据以JSON文档的形式存储到 Redis 中。
以下代码使用管道来最大限度地减少网络往返时间:

pipeline = client.pipeline()
for i, bike in enumerate(bikes, start=1):
    redis_key = f"bikes:{i:03}"
    pipeline.json().set(redis_key, "$", bike)
res = pipeline.execute()
# >>> [True, True, True, True, True, True, True, True, True, True, True]

加载完成后,您可以使用JSONPath表达式从 Redis 中的某个 JSON 文档中检索特定属性:

res = client.json().get("bikes:010", "$.model")
# >>> ['Summit']

5.1.3 选择文本嵌入模型

HuggingFace拥有庞大的文本嵌入模型库,这些模型可通过该SentenceTransformers框架在本地部署。这里我们使用MS MARCO模型,该模型广泛应用于搜索引擎、聊天机器人和其他人工智能应用中。

from sentence_transformers import SentenceTransformer
embedder = SentenceTransformer('msmarco-distilbert-base-v4')

5.1.4 生成文本嵌入

遍历所有带有以下前缀的 Redis 键 bikes:

keys = sorted(client.keys("bikes:*"))
# >>> ['bikes:001', 'bikes:002', ..., 'bikes:011']

使用这些键作为JSON.MGET命令的输入,并结合$.description字段,将描述信息收集到一个列表中。然后,将该描述列表传递给该.encode()方法:

descriptions = client.json().mget(keys, "$.description")
descriptions = [item for sublist in descriptions for item in sublist]
embedder = SentenceTransformer("msmarco-distilbert-base-v4")
embeddings = embedder.encode(descriptions).astype(np.float32).tolist()
VECTOR_DIMENSION = len(embeddings[0])
# >>> 768

使用JSON.SET命令将向量化描述插入到 Redis 中的自行车文档中。以下命令会在 JSONPath 下的每个文档中插入一个新字段$.description_embeddings。同样,请使用管道执行此操作,以避免不必要的网络往返:

pipeline = client.pipeline()
for key, embedding in zip(keys, embeddings):
    pipeline.json().set(key, "$.description_embeddings", embedding)
pipeline.execute()
# >>> [True, True, True, True, True, True, True, True, True, True, True]

使用JSON.GET命令检查其中一个已更新的bike文档:

res = client.json().get("bikes:010")
# >>>
# {
#   "model": "Summit",
#   "brand": "nHill",
#   "price": 1200,
#   "type": "Mountain Bike",
#   "specs": {
#     "material": "alloy",
#     "weight": "11.3"
#   },
#   "description": "This budget mountain bike from nHill performs well..."
#   "description_embeddings": [
#     -0.538114607334137,
#     -0.49465855956077576,
#     -0.025176964700222015,
#     ...
#   ]
# }

5.2 创建索引

5.2.1 使用向量创建索引

要查询文档元数据或执行向量搜索,必须创建索引。请使用FT.CREATE命令:

FT.CREATE idx:bikes_vss ON JSON
  PREFIX 1 bikes: SCORE 1.0
  SCHEMA
    $.model TEXT WEIGHT 1.0 NOSTEM
    $.brand TEXT WEIGHT 1.0 NOSTEM
    $.price NUMERIC
    $.type TAG SEPARATOR ","
    $.description AS description TEXT WEIGHT 1.0
    $.description_embeddings AS vector VECTOR FLAT 6 TYPE FLOAT32 DIM 768 DISTANCE_METRIC COSINE

以下是字段定义的详细说明VECTOR

  • $.description_embeddings AS vector:向量字段的 JSON 路径及其字段别名vector
  • FLAT:指定索引方法,可以是扁平索引或分层可导航小世界图(HNSW)。
  • TYPE FLOAT32: 设置向量分量的浮点精度,在本例中为 32 位浮点数。
  • DIM 768:嵌入的长度或维度,由所选的嵌入模型决定。
  • DISTANCE_METRIC COSINE选择的距离函数:余弦距离

5.2.2 检查索引状态

执行FT.CREATE命令后,索引过程会在后台运行。很快,所有 JSON 文档都应该被索引,并可以进行查询。为了验证这一点,您可以使用FT.INFO命令,该命令会提供有关索引的详细信息和统计信息。尤其需要关注的是成功索引的文档数量和索引失败的文档数量

FT.INFO idx:bikes_vss

5.3 执行向量搜索

本快速入门指南重点介绍矢量搜索。不过,您可以在文档数据库快速入门指南中了解更多关于如何基于文档元数据进行查询的信息。

5.3.1 嵌入您的查询

queries = [
    "Bike for small kids",
    "Best Mountain bikes for kids",
    "Cheap Mountain bike for kids",
    "Female specific mountain bike",
    "Road bike for beginners",
    "Commuter bike for people over 60",
    "Comfortable commuter bike",
    "Good bike for college students",
    "Mountain bike for beginners",
    "Vintage bike",
    "Comfortable city bike",
]

首先,使用相同的 SentenceTransformers 模型将每个输入查询编码为向量嵌入:

encoded_queries = embedder.encode(queries)
len(encoded_queries)
# >>> 11

5.3.2 K近邻(KNN)搜索

KNN算法基于选定的距离函数计算查询向量与Redis中每个向量之间的距离。然后,它返回与查询向量距离最小的前K个元素。这些元素是语义上最相似的元素。

现在构建一个查询来实现这一点:

query = (
    Query('(*)=>[KNN 3 @vector $query_vector AS vector_score]')
     .sort_by('vector_score')
     .return_fields('vector_score', 'id', 'brand', 'model', 'description')
     .dialect(2)
)

让我们来分析一下上面的查询模板:

  • 筛选表达式的(*)含义是all:未应用任何筛选条件。换句话说,您可以将其替换为根据其他元数据进行筛选的表达式。
  • KNN查询的这一部分会搜索最近的 3 个邻居。
  • 查询向量必须作为参数传入query_vector
  • 返回到查询向量的距离vector_score
  • 结果按此排序vector_score
  • 最后,它返回每个结果的字段vector_score,,,, 和。idbrandmodeldescription

笔记:

  • 要使用该命令进行向量查询FT.SEARCH,必须指定 DIALECT 2 或更高版本。

您必须将向量化的查询作为字节数组传递,并指定参数名称query_vector。以下代码从查询向量创建一个 Python NumPy 数组,并将其转换为紧凑的字节级表示形式,以便将其作为参数传递给查询:

client.ft('idx:bikes_vss').search(
    query,
    {
      'query_vector': np.array(encoded_query, dtype=np.float32).tobytes()
    }
).docs

有了查询模板,就可以循环执行所有查询。请注意,脚本会计算vector_score每个结果的距离1 - doc.vector_score。由于使用余弦距离作为度量标准,距离最小的项距离更近,因此与查询更相似。

然后,遍历匹配的文档,并创建一个结果列表,该列表可以转换为 Pandas 表格以可视化结果:

def create_query_table(query, queries, encoded_queries, extra_params=None):
    """
    Creates a query table.
    """
    results_list = []
    for i, encoded_query in enumerate(encoded_queries):
        result_docs = (
            client.ft("idx:bikes_vss")
            .search(
                query,
                {"query_vector": np.array(encoded_query, dtype=np.float32).tobytes()}
                | (extra_params if extra_params else {}),
            )
            .docs
        )
        for doc in result_docs:
            vector_score = round(1 - float(doc.vector_score), 2)
            results_list.append(
                {
                    "query": queries[i],
                    "score": vector_score,
                    "id": doc.id,
                    "brand": doc.brand,
                    "model": doc.model,
                    "description": doc.description,
                }
            )
    # Optional: convert the table to Markdown using Pandas
    queries_table = pd.DataFrame(results_list)
    queries_table.sort_values(
        by=["query", "score"], ascending=[True, False], inplace=True
    )
    queries_table["query"] = queries_table.groupby("query")["query"].transform(
        lambda x: [x.iloc[0]] + [""] * (len(x) - 1)
    )
    queries_table["description"] = queries_table["description"].apply(
        lambda x: (x[:497] + "...") if len(x) > 500 else x
    )
    return queries_table.to_markdown(index=False)
query = (
    Query("(*)=>[KNN 3 @vector $query_vector AS vector_score]")
    .sort_by("vector_score")
    .return_fields("vector_score", "id", "brand", "model", "description")
    .dialect(2)
)
table = create_query_table(query, queries, encoded_queries)
print(table)
# >>> | Best Mountain bikes for kids     |    0.54 | bikes:003...

六、使用Redis的RAG

6.1 什么是检索增强生成(RAG)?

大型语言模型(LLM)能够生成类似人类的文本,但受限于训练所用的数据。RAG通过将LLM与存储在Redis向量数据库中的外部领域特定数据集成,从而增强LLM的性能。

RAG流程包括三个主要步骤:

  • 检索:根据用户查询,使用向量搜索和过滤器从 Redis 中获取相关信息。
  • 增强:为 LLM 创建提示,包括用户查询、相关上下文和附加说明。
  • 生成:将 LLM 生成的响应返回给用户。

RAG 使 LLM 能够利用实时信息,从而提高生成内容的准确性和相关性。Redis 因其速度快、功能多样且易于使用,是 RAG 的理想选择。

6.2 Redis 在 RAG 中的作用

Redis 为管理实时数据提供了一个强大的平台。它支持向量的存储和检索,这对于处理大规模非结构化数据和执行相似性搜索至关重要。Redis 的关键特性和组件使其适用于 RAG,其中包括:

  1. 向量数据库:存储和索引语义上表示非结构化数据的向量嵌入。
  2. 语义缓存:将常见问题 (FAQ) 缓存到 RAG 流水线中。Redis 使用向量搜索来检索先前已解答的类似问题,从而降低 LLM 推理的成本和延迟。
  3. LLM会话管理器:存储LLM与用户之间的对话历史记录。Redis会获取聊天历史记录中最近和相关的部分,以提供上下文信息,从而提高回复的质量和准确性。
  4. 高性能和可扩展性:Redis 以其低延迟和高吞吐量而闻名,是 RAG 系统和需要快速数据检索和生成的 AI 代理的理想选择。

6.3 使用 Redis 构建 RAG 应用程序

要使用 Redis 构建 RAG 应用程序,请按照以下一般步骤操作:

  1. 设置 Redis:首先设置一个 Redis 实例,并将其配置为处理向量数据。

  2. 使用框架

    1. Redis 向量库 (RedisVL)RedisVL通过高效管理向量和元数据,增强了生成式 AI 应用的开发。它允许存储向量嵌入,并促进快速相似性搜索,这对于在 RAG 中检索相关信息至关重要。
    2. 流行的AI框架:Redis可与各种AI框架和工具无缝集成。例如,将Redis与用于构建语言模型的库LangChainLlamaIndex结合使用,可帮助开发者创建复杂的RAG管道。这些集成支持高效的数据管理和构建实时LLM链。
    3. Spring AI 和 Redis:将Spring AI 与 Redis结合使用,可以简化 RAG 应用的构建。Spring AI 提供了一种结构化的方法来将 AI 功能集成到应用程序中,而 Redis 则负责数据管理,从而确保 RAG 流水线的高效性和可扩展性。
  3. 嵌入和存储数据:使用合适的模型(例如 BERT、GPT)将数据转换为向量嵌入。将这些嵌入存储在 Redis 中,以便可以根据向量搜索快速检索它们。

  4. 与生成式模型集成:使用能够利用已检索数据的生成式 AI 模型。该模型将使用存储在 Redis 中的向量来增强其生成过程,确保输出结果基于相关且最新的信息。

  5. 查询和生成:实现查询逻辑,根据输入提示从 Redis 中检索相关向量。将这些向量输入生成模型,以生成增强的输出。

6.4 使用 Redis 实现 RAG 的好处

  • 效率:Redis 的内存数据存储确保检索操作以最小的延迟执行。
  • 可扩展性:Redis 可以水平扩展,无缝处理不断增长的数据量和查询量。
  • 灵活性:Redis 支持多种数据结构,并可与 AI 框架集成。

总而言之,Redis 为实现 RAG 提供了一个强大而高效的平台。其向量管理能力、高性能以及与 AI 框架的无缝集成,使其成为增强生成式 AI 应用实时数据检索功能的理想选择。

七、用于 GenAI 应用的 Redis

7.1介绍

Redis 提供高性能、可扩展且可靠的数据管理,使其成为 GenAI 应用、聊天机器人和 AI 代理的关键组件。通过利用 Redis 的快速数据检索、缓存和向量搜索功能,您可以增强 AI 驱动的交互,降低延迟,并改善用户体验。

Redis 擅长存储和索引语义上表示非结构化数据的向量嵌入。借助向量搜索,Redis 可以检索相似问题和相关数据,从而降低 LLM 推理的成本和延迟。它还能提取聊天记录的相关部分,丰富上下文信息,从而提供更准确、更相关的回复。这些特性使得 Redis 成为需要快速数据访问的 RAG 系统和 GenAI 应用的理想选择。

7.2 Redis 在 GenAI 应用中的主要优势

  • 性能:低延迟数据访问可实现实时交互,这对人工智能驱动的应用至关重要。
  • 可扩展性:Redis 旨在处理大量并发连接,非常适合高需求的 GenAI 应用。
  • 缓存:高效存储频繁访问的数据和响应,减少主数据库负载并加快响应速度。
  • 会话管理:内存数据结构简化了对话式人工智能场景中的会话状态管理。
  • 灵活性:Redis 支持多种数据结构(例如字符串、哈希、列表、集合),从而为 GenAI 应用提供定制解决方案。

RedisVL是一个集成了 CLI 的 Python 库,可与 Redis 无缝集成,以增强 GenAI 应用程序。

7.3 GenAI 应用中的 Redis 用例

7.3.1 优化人工智能代理性能

Redis 可以提升对话代理在处理高交互量时的会话持久性和缓存性能。有关实现细节,请参阅Flowise 对话代理与 Redis 的教程和演示。

7.3.2 聊天机器人开发与管理

Redis 通过以下方式支持聊天机器人平台:

  • 缓存:提高机器人响应速度。
  • 会话管理:跟踪对话状态,实现无缝交互。
  • 可扩展性:能够处理高流量的机器人使用情况。

通过LangChain 和 Redis 教程,学习如何使用 Redis 构建 GenAI 聊天机器人。对于将人工客服与聊天机器人集成的客户互动平台而言,Redis 可确保快速访问常用数据。另请参阅关于AI 驱动的视频问答应用的教程。

7.3.3 将机器学习框架与 Redis 集成

机器学习框架利用 Redis 实现以下功能:

  • 消息队列:确保组件之间顺畅的通信。
  • 状态管理:跟踪实时交互的对话状态。

请参阅《使用 LangChain 和 Redis 进行语义图像查询》以获取详细指南。为了扩展您的知识,请报名参加《将 Redis 用作向量数据库》课程,您将学习如何将 Redis 与 LangChain、LlamaIndex、FeatureForm、Amazon Bedrock 和 AzureOpenAI 等工具集成。

7.3.4 推进自然语言处理

Redis 通过以下方式增强自然语言理解:

  • 会话管理:跟踪用户交互,实现流畅的对话体验。
  • 缓存:降低频繁查询的延迟。

7.3.5 资源

查看Redis for AI文档,了解入门指南、概念、生态系统集成、示例和 Python notebook。

八、常见问题

8.1Redis 与其他键值存储有何不同

  • Redis 在键值数据库中有着不同的发展路径,其值可以包含更复杂的数据类型,并针对这些数据类型定义了原子操作。Redis 数据类型与基本数据结构紧密相关,并直接对程序员开放,无需额外的抽象层。
  • Redis 是一种内存数据库,但数据持久化到磁盘,因此它代表了一种不同的权衡:在实现极高的读写速度的同时,也限制了数据集的大小,使其无法超过内存容量。内存数据库的另一个优势在于,与磁盘上的相同数据结构相比,复杂数据结构的内存表示更容易操作,因此 Redis 可以用较低的内部复杂度完成很多工作。同时,两种磁盘存储格式(RDB 和 AOF)无需支持随机访问,因此它们结构紧凑,并且始终以追加方式生成数据(即使是 AOF 日志轮换也是追加操作,因为新版本是从内存中的数据副本生成的)。然而,与传统的磁盘存储相比,这种设计也带来了不同的挑战。由于 Redis 是内存中的主要数据表示形式,因此必须谨慎处理其操作,以确保磁盘上始终存在更新的数据集版本。

8.2 Redis 的内存占用量是多少?

举几个例子(所有例子均使用 64 位实例获得):

  • 一个空实例大约占用 3MB 内存。
  • 100 万个小键 -> 字符串值对占用约 85MB 内存。
  • 100 万个键 -> 哈希值,表示一个具有 5 个字段的对象,使用约 160 MB 内存。

测试您的用例非常简单。使用该redis-benchmark工具生成随机数据集,然后使用命令检查已用空间INFO memory

64 位系统存储相同的键时会比 32 位系统占用更多内存,尤其是在键和值都很小时。这是因为在 64 位系统中,指针占用 8 个字节。当然,64 位系统的优势在于可以拥有更大的内存容量,因此运行大型 Redis 服务器几乎必须使用 64 位系统。另一种选择是分片。

8.3 为什么 Redis 要将整个数据集保存在内存中?

过去,Redis 的开发者们曾尝试过虚拟内存和其他系统,以支持大于内存的数据集,但最终我们还是希望做好一件事:数据从内存中提供服务,磁盘用于存储。因此,目前 Redis 没有创建磁盘后端的计划。毕竟,Redis 的大部分特性都直接源于其当前的设计。

如果您的真正问题不是所需的总 RAM,而是需要将数据集拆分到多个 Redis 实例中,请阅读 本文档中的分区页面以获取更多信息。

Redis Ltd.(Redis 开发赞助公司)开发了一种名为“Redis on Flash”的解决方案,该方案采用混合内存/闪存方式来处理具有特定访问模式的大型数据集。您可以查看他们的产品了解更多信息,但需要注意的是,此功能并非 Redis 开源代码库的一部分。

8.4 Redis 可以与基于磁盘的数据库一起使用吗?

是的,一种常见的设计模式是将写入量很大的小数据集(以及需要使用 Redis 数据结构来高效建模问题的数据)存储在 Redis 中,并将大数据写入 SQL 数据库或最终一致性磁盘数据库。类似地,有时也会使用 Redis 来存储磁盘数据库中相同数据子集的另一个副本。这看起来可能类似于缓存,但实际上是一种更高级的模型,因为通常 Redis 数据集会与磁盘数据库数据集同步更新,而不是在缓存未命中时刷新。

8.5 如何降低 Redis 的整体内存使用量?

在将逻辑数据模型映射到 Redis 中的物理数据模型时,一个好的做法是考虑内存消耗。这些考虑因素包括使用特定的数据类型、键模式和规范化。

除了数据建模之外,内存优化页面

8.6 如果 Redis 内存不足会发生什么?

Redis 内置了内存使用保护机制,允许用户通过maxmemory配置文件中的选项设置最大内存使用量限制。如果达到此限制,Redis 将开始对写入命令返回错误(但仍会继续接受只读命令)。

您还可以配置 Redis,使其在达到最大内存限制时移除键。请参阅移除策略文档。

8.7 Linux 系统下后台保存失败并出现 fork() 错误?

简短回答:echo 1 > /proc/sys/vm/overcommit_memory:)

现在是较长的一段:

Redis 的后台保存机制依赖于fork现代操作系统中系统调用的写时复制(copy-on-write)语义:Redis 会 fork 一个子进程,该子进程是父进程的精确副本。子进程将数据库写入磁盘,最终退出。理论上,作为副本,子进程应该占用与父进程相同的内存,但实际上,由于大多数现代操作系统都实现了写时复制语义,父进程和子进程会共享公共内存页。只有当子进程或父进程中的内存页发生更改时,才会复制该内存页。由于理论上所有内存页都可能在子进程保存期间发生更改,Linux 无法预先确定子进程将占用多少内存,因此,如果设置值overcommit_memory设为零,则 fork 操作将失败,除非有足够的可用 RAM 来真正复制所有父进程的内存页。例如,如果您有一个 3GB 的 Redis 数据集,而只有 2GB 的可用内存,则 fork 操作将会失败。

设置overcommit_memory为 1 会告诉 Linux 放宽限制,以更乐观的分配方式执行 fork,而这正是 Redis 所需要的。

您可以参考proc(5)手册页来了解可用值的说明。

8.8 Redis 磁盘快照是原子性的吗?

是的,当服务器不在执行命令时,Redis 后台保存进程总是会派生一个子进程,因此,在 RAM 中报告为原子操作的每个命令,从磁盘快照的角度来看也是原子操作的。

8.9 Redis 如何利用多个 CPU 或核心?

使用 Redis 时,CPU 很少会成为瓶颈,因为 Redis 通常受内存或网络限制。例如,使用流水线技术时,运行在普通 Linux 系统上的 Redis 实例每秒可以处理 100 万个请求,因此如果你的应用程序主要使用 O(N) 或 O(log(N)) 的命令,它几乎不会占用太多 CPU 资源。

然而,为了最大限度地利用 CPU,您可以在同一台服务器上启动多个 Redis 实例,并将它们视为不同的服务器。无论如何,单台服务器最终可能不够用,因此如果您想使用多核 CPU,可以尽早考虑分片方案。

您可以在分区页面找到有关使用多个 Redis 实例的更多信息。

从 4.0 版本开始,Redis 开始实现多线程操作。目前,这仅限于在后台删除对象以及通过 Redis 模块实现的阻塞命令。在后续版本中,Redis 的计划是逐步扩展其多线程功能。

8.10 单个 Redis 实例最多可以存储多少个键?哈希表、列表、集合和有序集合中最多可以包含多少个元素?

Redis 最多可以处理 2^32 个键,实践测试表明,每个实例至少可以处理 2.5 亿个键。

每个哈希表、列表、集合和有序集合都可以容纳 2^32 个元素。

换句话说,你的瓶颈很可能在于系统可用内存的大小。

8.11 为什么我的副本实例的密钥数量与主实例不同?

如果您使用具有有限生存时间(Redis 会过期)的键,这是正常现象。具体情况如下:

  • 主节点在首次与副本同步时生成 RDB 文件。
  • RDB 文件不会包含主数据库中已过期但仍保存在内存中的键。
  • 即使这些键在逻辑上已过期,它们仍然保留在 Redis 主节点的内存中。它们将被视为不存在,其内存将在稍后通过增量方式或在访问时显式回收。虽然这些键在逻辑上不属于数据集的一部分,但它们会在INFO输出和DBSIZE命令中被记录下来。
  • 当副本读取主节点生成的 RDB 文件时,这组键将不会被加载。

因此,对于拥有大量过期密钥的用户来说,副本中的密钥数量通常会减少。然而,从逻辑上讲,主密钥和副本的内容应该是相同的。

九、连接Redis 客户端 API库

将您的应用程序连接到 Redis 数据库并尝试示例

使用 Redis 客户端库可以从您自己的代码连接到 Redis 服务器。我们为以下八种主要语言提供了客户端库的文档:

LanguageClient nameDocsSupported
Pythonredis-pyredis-py guideYes
PythonRedisVLRedisVL guideYes
C#/.NETNRedisStackNRedisStack guideYes
JavaScriptnode-redisnode-redis guideYes
JavaJedisJedis guideYes
JavaLettuceLettuce guideYes
Gogo-redisgo-redis guideYes
PHPPredisPredis guideNo
Chiredishiredis guideYes
Rustredis-rsredis-rs guideNo

社区还为Python、 C#/.NET、 Node.js和 Java/Spring 提供了几个更高级别的 对象映射 (OM) 库。

9.1 社区支持的客户端库

下表列出了 Redis 官方文档未直接支持的语言的推荐第三方客户端库:

LanguageClient nameGithubDocs
C++Boost.Redishttps://github.com/boostorg/redishttps://www.boost.org/doc/libs/develop/libs/redis/doc/html/index.html
Dartredis_dart_linkhttps://github.com/toolsetlink/redis_dart_linkhttps://github.com/toolsetlink/redis_dart_link
PHPPhpRedis extensionhttps://github.com/phpredis/phpredishttps://github.com/phpredis/phpredis/blob/develop/README.md
Rubyredis-rbhttps://github.com/redis/redis-rbhttps://rubydoc.info/gems/red

十、 使用 Redis 命令

客户端应用程序和工具通过命令与 Redis 进行交互。大多数命令实现了用于存储和检索数据的数据类型,但也有一些命令用于处理服务器配置、安全等其他事项。

10.1 命令结构

每个命令都有一个唯一的名称。相关的命令组通常遵循一致的命名规则。例如,所有处理哈希的命令都以`hash` 为H前缀。大多数命令接收一个或多个参数,用于指定要操作的数据。对于数据类型命令,第一个参数通常是用于标识目标数据对象的键。

发出命令后,服务器会尝试处理该命令并返回响应。更新数据的命令通常会返回状态消息(例如“已更新OK”)或指示已更改或更新项数的数字。检索数据的命令会返回请求的数据。失败的命令会返回描述问题的错误消息。

与 Redis 服务器交互涉及一系列命令和响应。无论您是通过客户端库还是像redis-cli或 Redis Insight这样的客户端工具发送命令,其效果都相同。这在开发过程中非常有用。您可以使用高级工具来试验命令、设置测试数据或构建数据模型原型,然后从应用程序代码访问准备好的数据。大多数 Redis 代码示例都提供了 CLI 会话摘录以及每个客户端库对应的应用程序代码。

10.2 批处理命令

虽然可以逐条执行 Redis 命令,但将一系列相关命令批量处理成一个管道通常效率更高。
管道会将多个命令作为一次通信发送到服务器,并以同样的方式接收响应。
有关 此技术的完整描述,请参阅“管道”部分,并参阅 客户端库的管道示例。

批量处理命令的另一个原因是将其视为一个不间断的整体。
如果您需要确保所有命令都已完成,且不会出现其他客户端修改相同数据的情况(这可能导致数据不一致),则应该这样做。
Redis 使用事务 实现这种行为。有关更多信息请参阅 事务文档 与 客户端库中的事务示例。

10.3 键和值

Redis 中的键管理:键过期、扫描、修改和查询键空间

存储在 Redis 数据库中的每个数据对象都有其唯一的 。键是一个字符串,用于传递给 Redis 命令以检索相应的对象或修改其数据。与特定键关联的数据对象称为值两者共同构成键值对

10.3.1 密匙内容

键通常是数据模型中具有特定含义的文本名称。与编程语言中的变量名不同,Redis 键的格式限制较少,因此包含空格或标点符号的键通常都可以接受(例如,“1st Attempt”或“% of price in $”)。Redis 不支持键的命名空间或其他分类,因此您必须注意避免名称冲突。不过,Redis 约定使用冒号“:”将键拆分为多个部分(例如,“person:1”、“person:2”、“office:London”、“office:NewYork:1”)。您可以利用这种方法将键简单地归类。

虽然键通常是文本格式,但 Redis 实际上实现了二进制安全的键,因此你可以使用任何字节序列作为有效键,例如 JPEG 文件或应用程序中的结构体值。空字符串在 Redis 中也是有效的键。

关于钥匙,还有其他一些需要注意的事项:

  • 过长的密钥并非明智之举。例如,1024 字节的密钥不仅占用大量内存,而且在数据集中查找该密钥可能需要多次代价高昂的密钥比对。即使任务是匹配一个大值是否存在,对其进行哈希处理(例如使用 SHA1)也是更好的选择,尤其是在内存和带宽方面。
  • 过短的键通常不是个好主意。如果可以用“user:1000:followers”代替“u1000flw”,那么写“u1000flw”就毫无意义。后者更易读,而且增加的空间与键对象本身和值对象占用的空间相比微不足道。虽然短键显然会占用更少的内存,但你的任务是找到合适的平衡点。
  • 尽量坚持使用统一的模式。例如,“object-type:id”就是一个不错的选择,例如“user:1000”。对于多词字段,通常使用点号或破折号,例如“comment:4321:reply.to”或“comment:4321:reply-to”。
  • 允许的最大密钥大小为 512 MB。

10.3.2 标签

Redis 使用哈希算法以高效的方式检索与键关联的值。哈希算法将键的原始字节值组合起来,生成一个整数索引号。然后,该索引号用于定位存储该键值的哈希槽。

通常情况下,整个键都会用于计算哈希索引,但在某些情况下,您可能只需要对键的一部分进行哈希处理。您可以使用一对花括号{...}来创建哈希标签,从而选择要进行哈希处理的键的部分。例如,键 `a`person:1person:2`b` 会产生不同的哈希索引,但 ` {person}:1a` 和 `b`{person}:2会产生相同的哈希索引,因为person哈希计算仅使用花括号内的哈希标签部分。

哈希标签的一个常见用途是允许 在集群数据库中执行多键操作(更多信息请参阅 数据库集群 )。Redis 不允许在集群数据库中执行大多数多键操作,除非所有键都生成相同的哈希索引。例如, SINTER 命令查找 两个不同集合值的交集。这意味着该命令

SINTER group:1 group:2

不适用于集群数据库,但

SINTER {group}:1 {group}:2

这样做是可行的,因为井号确保两个键产生相同的哈希索引。

请注意,虽然在某些情况下标签很有用,但您不应养成普遍使用标签的习惯。如果太多键映射到同一个哈希槽,最终会损害数据库的性能。 有关如何使用标签的更多信息,请参阅数据库集群。

10.3.3 修改和查询键空间

有些命令没有针对特定类型进行定义,但对于与键空间进行交互非常有用,因此可以与任何类型的键一起使用。

例如,该EXISTS命令返回 1 或 0 来指示给定的键是否存在于数据库中,而该DEL命令会删除键及其关联的值,无论该值是什么。

> set mykey hello
OK
> exists mykey
(integer) 1
> del mykey
(integer) 1
> exists mykey
(integer) 0

从示例中还可以看出,DEL它本身会根据键是否被删除(它存在)或未被删除(没有具有该名称的键)而返回 1 或 0。

有很多与空间相关的关键命令,但以上两个命令以及TYPE返回指定键处存储的值类型的命令是必不可少的:

posted @ 2025-12-11 16:11  yangykaifa  阅读(9)  评论(0)    收藏  举报