kevy 4.0
AI 系统的
数据层。
兼容 Redis,所以可以直接换上去。每一个操作都更快。而且它做的正是一个 AI 系统真正需要的事——向量检索、全文检索、二级索引、物化视图、变更流——都在同一个引擎里,都建在同一批 key 上。
$ cargo install kevy
$ kevy --port 6379
$ redis-cli -p 6379
> SET session:7f3a '{"user":"ada"}' EX 3600
OK
> IDX.QUERY idx:sem KNN "<vector>" LIMIT 10
1) "doc:4410"
2) "doc:9982"为什么可以直接替换 Redis
同样的协议。更高的吞吐。
你的客户端不用改——RESP2 和 RESP3,184 条命令,还是你现在用的那个库。一台机器,16 核,loopback,小 value,五次运行取中位数。
LPUSH 和 ZADD 只领先 12% 和 10%。差距薄到这个程度,决定胜负的是你的 value 大小和 key 分布。如果 list 或者 sorted set 是你的热路径,那么性能就不是换过来的理由。完整的表格在这里,valkey 和 Dragonfly 也一起打了。
一个 AI 系统需要的那些东西,
就在已经存着数据的那个引擎里。
不是模块。不是 sidecar。也不是一份会慢慢偏离原件的事实副本。
在你的 keyspace 上做 KNN
一个 HNSW 索引,声明一次,之后由写入路径维持最新。embedding 由你给出;kevy 负责存它、索引它、检索它。
怎么做 全文BM25,以及混合排序
在同一批 key 上做全文检索,还有一种把文本排序和向量排序融合起来的混合查询。
怎么做 索引按任意字段来查
二级索引把一次带过滤的读变回一次查表。没有查询计划器,没有扫描。
怎么做 视图答案一直是备好的
物化视图在写入路径上就把聚合维持在最新,于是读的时候永远不必重算一遍。
怎么做 变更流跟读每一次写
一条可以续读的流,另一个进程——或者一个 agent——可以一直跟着它。什么都不用轮询。
怎么做 哪里都能放服务器、二进制、浏览器、设备
同一个引擎,同一批命令:一台 16 核的服务器、你的二进制内部、浏览器标签页里的 151 KB,或者一颗没有操作系统的芯片。
怎么做为什么 AI 系统需要一个不一样的数据层
一个 agent 写下一篇文档,给它做 embedding,给它建索引,把它放进缓存,再通知别的东西它变了。今天这是四套系统——一个缓存、一个向量数据库、一个搜索索引、一个队列——它们持有同样的事实,然后慢慢彼此偏离。每一套都是一个可能漏掉一步的地方。
kevy 把它们收成一个。声明索引,然后照你原来的方式写 key。引擎会在写入路径上把向量索引、文本索引、二级索引和视图都维持在最新,而变更流会告诉每一个在听的人。
而且 agent 在哪里跑,它就能在哪里跑。在你的服务里,在二进制内部、连 socket 都没有,在浏览器标签页里作为 WebAssembly,或者在网络边缘的那台设备上。
你在做的是什么?
每一页都会说清楚 kevy 合不合适、代价是什么、以及具体怎么做——命令可以直接粘贴。
开始
当服务端跑
在 6379 上说 RESP。你的 redis-cli 和你的客户端库不会发现有任何变化。
cargo install kevy kevy --port 6379在你的 Rust 程序里
没有 socket,没有第二个进程,没有序列化。
kevy-embedded = "4.0" let db = Db::open("data/")?; db.set(b"k", b"v", None)?;在浏览器标签页里
151 KB。落在浏览器的文件系统上,刷新之后还在。
import { open } from "@goliajp/kevy"; const db = await open({ persist: { name: "app" } }); db.set("cart:u1", json, { ttlMs: 3_600_000 });
它不是集群。复制和故障切换有;把数据分片到多台机器上没有,以后也不会有。如果一台机器不够用,kevy 就是错的答案。没有 AUTH,也没有 TLS——把它跑在内网,或者放在一个真正把这两件事做好的东西后面。还有,有些命令和 Redis 不一样:SCAN 不是游标迭代器,ZRANK 是 O(N),SPOP 不随机。每一处差异都逐条写下来了。还有,这里写着什么时候根本不该用它。