Redis 查询引擎性能最佳实践

注意
如果您正在使用 Redis Software 或 Redis Cloud,请参阅可扩展 Redis 查询引擎的最佳实践页面。

检查清单

以下是一些确保 Redis 查询引擎 (RQE) 良好性能的基本步骤。

  • 在设计 Redis 数据模型时考虑您的查询模式。
  • 使用大小计算器确保 Redis 架构已根据预期负载调整大小。
  • 为 Redis 节点配置足够的资源(RAM、CPU、网络)以支持预期的最大负载。
  • 检查 FT.INFOFT.PROFILE 的输出,查找异常和/或错误。
  • 在测试环境中,使用真实世界的查询和由 memtier_benchmark 或自定义负载应用生成的负载进行负载测试。

索引注意事项

一般

  • 对于只需要匹配的使用案例,优先使用 TAG 而非 NUMERIC
  • 对于不需要全文搜索功能(纯匹配)的使用案例,优先使用 TAG 而非 TEXT
  • 仅将您查询中使用的字段放入索引。
  • 仅当字段在 SORTBY 查询中使用时,才将其设置为 SORTABLE
  • 使用 DIALECT 2
  • 将查询字段和任何投影字段(RETURNLOAD)都放入索引。
  • 将所有字段设置为 SORTABLE
  • 将 TAG 字段设置为 UNF
  • 可选:如果使用案例支持,将 TEXT 字段设置为 NOSTEM
  • 使用 DIALECT 2

查询优化

  • 避免返回大型结果集。使用 CURSORLIMIT
  • 避免通配符搜索。
  • 避免投影所有字段(例如,LOAD *)。只投影属于索引 schema 的字段。
  • 如果查询运行时间长,启用线程化(查询性能因子)以减少对主 Redis 线程的竞争。

验证性能(FT.PROFILE

您可以分析 FT.PROFILE 输出,以了解查询执行的详细信息。以下信息项可用于分析:

  • 总执行时间
  • 每个分片的执行时间
  • 协调时间(适用于多分片环境)
  • 查询分解为基本组件,例如 UNIONINTERSECT
  • 警告,例如 TIMEOUT

反模式

在设计和查询 RQE 中的索引时,某些做法可能会阻碍性能、可扩展性和可维护性。以下是一些常见的反模式,应予以避免:

  • 大型文档:在 Redis 中存储过大的文档会减慢数据检索速度并增加内存使用。尽可能将数据分解为更小、更集中的记录。
  • 深层嵌套字段:检索或索引深层嵌套的 JSON 字段计算成本很高。使用更扁平的 schema 以获得更好的性能。
  • 大型结果集:获取不必要的大型结果集会占用内存和网络资源。将结果限制在所需范围内。
  • 通配符使用:在查询中不加区分地使用通配符模式可能导致大规模且低效的扫描,尤其是在索引规模较大时。
  • 大型投影:在查询结果中包含过多字段会增加内存开销并减慢查询执行速度。将投影限制在必需的字段。

以下示例描述了一个反模式索引 schema 和查询,随后是为 RQE 可扩展性设计的更正版本。

反模式索引 schema

以下 schema 带来了可扩展性和性能方面的挑战:

FT.CREATE jsonidx:profiles ON JSON PREFIX 1 profiles: 
          SCHEMA $.tags.* as t NUMERIC SORTABLE 
                 $.firstName as name TEXT 
                 $.location as loc GEO

问题

  • 最小化 schema 定义:该 schema 稀疏,缺少可能频繁查询的字段,如 lastNameidversion。这导致需要额外的操作来单独获取这些字段,降低了效率。
  • 文本字段缺少 SORTABLE 标志:对不可排序字段执行排序操作需要全文处理,速度很慢。
  • 通配符索引:$.tags.* 创建了一个广泛的索引,可能导致过度的内存使用和降低的查询性能。

反模式查询

以下查询效率低下,未针对垂直扩展进行优化:

FT.AGGREGATE jsonidx:profiles '@t:[1299 1299]' LOAD * LIMIT 0 10

问题

  • 通配符投影(LOAD *):在结果集中检索所有字段效率低下,会增加内存使用,尤其是在文档较大的情况下。
  • 不必要的字段:当前操作不需要的字段仍然被获取,减慢了执行速度。
  • 缺乏高级查询语法:未指定查询方言或利用标签等功能,查询可能执行不必要的计算。

改进的索引 schema

以下是遵循垂直扩展最佳实践的优化 schema:

FT.CREATE jsonidx:profiles ON JSON PREFIX 1 profiles: 
          SCHEMA $.tags.* as t NUMERIC SORTABLE 
                 $.firstName as name TEXT NOSTEM SORTABLE 
                 $.lastName as lastname TEXT NOSTEM SORTABLE 
                 $.location as loc GEO SORTABLE 
                 $.id as id TAG SORTABLE UNF 
                 $.ver as ver TAG SORTABLE UNF

改进

  • 文本字段的 NOSTEM:防止对 firstNamelastName 等字段进行词干提取,以允许精确匹配(例如,“Smith” 保持 “Smith”)。
  • 扩展 schema:添加了常用查询字段,如 lastNameidversion,通过减少查询后数据检索的需要,使查询更高效。
  • TAG 字段:idver 定义为 TAG 字段,以支持快速精确匹配过滤。
  • 所有相关字段的 SORTABLE:确保排序操作高效,无需全文扫描。

您可能想知道为什么在改进的 schema 中 $.tags.* as t NUMERIC SORTABLE 是可接受的,而之前不是。包含 $.tags.* 在以下情况下是可以接受的:

  • 它有明确的目的:它在查询中被积极使用,例如按数值范围过滤或匹配特定值。
  • schema 中的其他字段对其进行补充:这些字段减少了所有查询操作对 $.tags.* 的过度依赖,更均匀地分配负载。
  • 投影和限制得到精心管理:使用 $.tags.* 的查询应避免加载不必要的字段或返回过大的结果集。

改进的查询

以下查询更适合垂直扩展:

FT.AGGREGATE jsonidx:profiles '@t:[1299 1299]' 
                LOAD 6 id t name lastname loc ver 
                LIMIT 0 10
                DIALECT 2

改进

  • 定向投影:LOAD 子句仅指定必需字段(id, t, name, lastname, loc, ver),减少内存和网络开销。
  • 限制结果:LIMIT 子句确保查询仅检索前 10 个结果,避免大型结果集。
  • DIALECT 2:启用最新的 RQE 语法和功能,确保与现代功能兼容。
评价本页
回到顶部 ↑