llvm/clangir[17] llvm/llvm-project[18]
目前,优化器的过程分为三组:
-
表达式分析:主要优化逻辑表达式,如 AND、OR、NOT 运算符等; -
数值分析:通过区间分析优化数值比较,例如消除不必要的比较,或改进比较表达式来实现查询优化; -
查询计划生成:把 Syntatical IR 转换成 Planning IR 并通过选择最佳索引以及消除不必要排序来增强查询计划。
Kvrocks 的阶段管理器会控制上述阶段的运行顺序。每个阶段可能运行多次,但最终会收敛并交给执行器执行。
查询计划执行
KQIR 计划执行器是一个 Volcano 模型[19]的实现。
一旦 IR 优化器完成所有优化,计划执行器就可以拿到最终的 Planning IR 结果。然后,计划执行器会将 IR 转化为具体的执行算子,串接成为一个从源端拉取数据,经过层层转换后输出结果的流水线。
随后,Kvrocks 从最终结果的迭代器中轮询拉取数据,取得查询结果。
磁盘上的索引
不同于 Redis 在内存中存储索引数据,Kvrocks 需要在磁盘上构建索引。这意味着,对于任何字段类型,我们都需要设计编码来将索引转换为 RocksDB 上的键值对。
此外,我们需要在执行 JSON 或 HASH 命令前后分别递增地创建索引,以确保查询结果是实时的。
现状与限制
KQIR 功能目前已经合并到 unstable 分支上,支持 FT.CREATE
、FT.SEARCH
和 FT.SEARCHSQL
等命令。我们鼓励用户进行测试和发布反馈。
然而,KQIR 仍处于早期开发阶段,我们无法保证兼容性,并且,许多功能仍然不完整。因此,即将发布的版本 2.9.0 将不包括 KQIR 组件。我们将在 2.10.0 版本开始发布 KQIR 功能。
字段类型支持
目前,我们只支持两种字段类型:标记(tag)和数字(numeric)。
标记字段用多个 tag 标记了每个数据记录,以便在查询中进行筛选。
数字字段保存双精度浮点范围内的数字数据,允许按特定的数值范围进行排序和过滤。
未来,我们计划扩大支持范围,将向量搜索和全文检索功能与其他字段类型一起实现。
事务保证
目前,KQIR 的事务保证非常弱,这可能会导致使用过程中出现意外问题。
Kvrocks 社群有另一个项目[20],计划通过建立结构化框架来增强 Kvrocks 的事务保证,从而在 KQIR 实现的 ACID 支持。
『译注』
上述项目也是今年开源之夏(OSPP)的一个项目。
IR 优化器的限制
目前,KQIR 在优化排序时没有使用成本模型,而是依赖一段专门的逻辑。这点会在未来的版本里以高优先级做改进。
此外,KQIR 目前没有使用基于运行时统计数据的优化。我们未来的重点将是将运行时统计信息集成到成本模型中,以实现更精确的索引选择。
与其他功能的关系
KQIR 与命名空间功能[21]集成良好。
FT.CRAETE
创建的任何索引都限制在当前命名空间中,不能在其他命名空间中访问,这与命名空间中访问其他数据的方式一致。
目前,KQIR 无法在集群模式[22]下启用。集群模式支持目前还没有计划,但是这是我们想要实现的功能。欢迎在 Kvrocks 社群当中分享你的需求场景或设计思路。
合规问题
虽然 KQIR 实现了 RediSearch 的接口,但它不包括任何来自 RediSearch 的代码。如前所述,KQIR 采用了一个全新的框架,其查询架构(包括解析、优化、执行)均独立于 RediSearch 的实现。
这点非常重要,因为 RediSearch 并不是开源软件,而是专有许可下的扩展。Kvrocks 的实现保证用户在开源协议下使用相关功能,而无需担心额外的合规风险。这也是 Apache 软件基金会品牌的一个重要保证。
这是一次冒险!
KQIR 目前仍处于早期实验阶段。我们建议用户在生产环境中使用 KQIR 功能时要慎重考虑,因为我们不保证兼容性。但是我们非常欢迎用户试用和提供反馈,这将有助于我们尽快稳定相关功能并正式发布。
未来计划
目前,twice 和 Kvrocks 的其他成员正在快速开发 KQIR 框架。所有上文提到的内容都将继续发展。如果你对这些主题感兴趣,欢迎在 GitHub 上随时了解最新进展。我们欢迎任何期望参与这些工作的开发者加入 Apache Kvrocks 社群并共同创造出有价值的软件。
作为 Apache 软件基金会旗下的开源社群,Kvrocks 社群完全由志愿者组成。我们致力于提供一个开放、包容和供应商中立的环境。
向量搜索
支持向量搜索的设计和实现目前正在进行中。相关进展非常乐观。
Kvrocks 社群的一些成员正在讨论,并提出了在 KQIR 上实现向量搜索的编码设计。
根据计划,我们将首先在磁盘上实现 HNSW 索引,然后引入向量字段类型。
-
Vector Search HNSW Indexing Encoding[23]
全文检索
目前,Kvrocks 社群还没有全文搜索的设计方案。
不过,我们正在探索通过 CLucene[24] 或 PISA[25] 将全文索引纳入 KQIR 的可能性。
欢迎任何有兴趣参与的开发者分享想法或建议!
SQL 功能
未来,我们计划逐步支持更多 SQL 功能,可能包括子查询、JOIN操作、聚合函数和其他功能。
Kvrocks 的 SQL 能力主要关注的仍然是事务处理,而不是分析任务。
完整示例
首先,我们需要启动一个 Kvrocks 的实例。可以运行下述命令,启动一个 Kvrocks 的 Docker 容器:
docker run -it -p 6666:6666 apache/kvrocks:nightly --log-dir stdout
当然,你也可以选择克隆 unstable 分支的最新版本代码[26],并从源码构建出 Kvrocks 二进制并运行。
成功启动 Kvrocks 实例之后,我们用 redis-cli
工具连接上实例。运行一下命令:
FT.CREATE testidx ON JSON PREFIX 1 'test:' SCHEMA a TAG b NUMERIC
这个命令创建了一个名为 testidx
的索引,包括一个名为 a
的 tag 字段和名为 b
numeric 字段。
然后,我们可以使用 Redis JSON 命令写入一系列的数据:
JSON.SET test:k1 $ '{"a": "x,y", "b": 11}'
JSON.SET test:k2 $ '{"a": "y,z", "b": 22}'
JSON.SET test:k3 $ '{"a": "x,z", "b": 33}'
写入数据也可以在 FT.CREATE
创建索引之前,执行顺序并不会影响最终效果。
最后,我们就可以用 SQL 语句来基于刚才创建的索引,在这些数据上运行查询了:
FT.SEARCHSQL 'select * from testidx where a hastag "z" and b < 30'
除了使用 SQL 查询,RediSearch 语法的查询也是支持的:
FT.SEARCH testidx '@a:{z} @b:[-inf (30]'
欢迎下载试用、探索和发表反馈。
参考资料
[2]完整示例: #完整示例
[3]Apache Kvrocks 官方博客: https://kvrocks.apache.org/blog/kqir-query-engine/
[4]绝大部分 Redis 命令: https://kvrocks.apache.org/docs/supported-commands/
[5]RESP 通信协议: https://redis.io/docs/latest/develop/reference/protocol-spec/
[6]Functions: https://redis.io/docs/latest/develop/interact/programmability/functions-intro/
[7]Bloom Filter: https://redis.io/docs/latest/develop/data-types/probabilistic/bloom-filter/
[8]JSON: https://redis.io/docs/latest/develop/data-types/json/
[9]RediSearch: https://github.com/RediSearch/RediSearch
[10]对应的 Redis 命令: https://redis.io/docs/latest/operate/oss_and_stack/stack-with-enterprise/search/commands/
[11]支持各种字段类型: https://redis.io/docs/latest/develop/interact/search-and-query/basic-constructs/field-and-type-options/
[12]独特的查询语法: https://redis.io/docs/latest/develop/interact/search-and-query/advanced-concepts/query_syntax/
[13]LangChain: https://www.langchain.com/
[14]不同的方言版本: https://redis.io/docs/latest/develop/interact/search-and-query/advanced-concepts/query_syntax/#basic-syntax
[15]KQIR 框架: https://github.com/apache/kvrocks/tree/unstable/src/search
[16]LLVM 的概念和设计: https://llvm.org/docs/Passes.html
[17]llvm/clangir: https://github.com/llvm/clangir/commits?author=PragmaTwice
[18]llvm/llvm-project: https://github.com/llvm/llvm-project/commits?author=PragmaTwice
[19]Volcano 模型: https://cs-people.bu.edu/mathan/reading-groups/papers-classics/volcano.pdf
[20]另一个项目: https://github.com/apache/kvrocks/issues/2331
[21]命名空间功能: https://kvrocks.apache.org/docs/namespace/
[22]集群模式: https://kvrocks.apache.org/docs/cluster
[23]Vector Search HNSW Indexing Encoding: https://github.com/apache/kvrocks/discussions/2316
[24]CLucene: https://clucene.sourceforge.net/
[25]PISA: https://github.com/pisa-engine/pisa
[26]最新版本代码: https://github.com/apache/kvrocks/?tab=readme-ov-file#build-and-run-kvrocks
原创文章,作者:guozi,如若转载,请注明出处:https://www.sudun.com/ask/88696.html