KiviDB 发布:Rust 编写的 Redis 兼容内存数据库,内置向量检索
Show HN: KiviDB, a faster Redis-compatible memory database and vector cache
KiviDB 发布,这是一个用 Rust 编写、兼容 Redis 协议(RESP2/RESP3)的多线程内存键值数据库,内置全文与向量(FLAT/HNSW)检索,采用 AGPL-3.0 开源。
KiviDB 是一个用 Rust 编写的快速、多线程的 Redis® 和 Valkey 替代品。它使用 Redis 协议(RESP2 和 RESP3),因此现有的 Redis 客户端、redis-cli 和库无需修改即可使用,并且内置全文和向量搜索。它通过分片的内存键值设计在所有核心上运行,并持久化到快照和可选的仅追加文件。
在相同的 32 核上,KiviDB 每秒可处理 2100 万次流水线 GET:约为 Redis 8 的 9 倍,Dragonfly 的 2.3 倍,且 p99 延迟不到 Dragonfly 的一半(基准测试)。
docker run -d -p 6380:6380 kividb/kividb
redis-cli -p 6380 PING # PONGKiviDB 监听 6380,而非 Redis 的 6379,因此两者可以并行运行;将客户端指向该端口,或传入 --port 6379。
- 协议:Redis 兼容的命令接口(支持的命令见 COMMANDS.md)
- 搜索和向量:Redis Stack 风格的
FT.*命令,用于全文、标签、数值和向量(FLAT / HNSW)搜索 - Lua 脚本:可选的 Cargo 特性。
EVAL、SCRIPT、FUNCTION、FCALL及相关命令在启用--features lua的构建中可用(见 脚本命令(Lua)) - TLS:可选的 Cargo 特性(
--features tls) - 默认监听地址:
0.0.0.0:6380,并启用 保护模式 - 许可证:GNU Affero 通用公共许可证 v3(AGPL-3.0-only),开源;使用 KiviDB 不会使你的应用程序受 AGPL 约束;见 许可证
仓库:github.com/kividbio/kividb · 网站:kividb.io
对比
| KiviDB | Redis 8 | Valkey 8 | Dragonfly | KeyDB | |
|---|---|---|---|---|---|
| 许可证 | AGPL-3.0 | RSALv2、SSPLv1 或 AGPL-3.0 | BSD-3-Clause | BSL 1.1 | BSD-3-Clause |
| 语言 | Rust | C | C | C++ | C++ |
| 命令运行于 | 每个核心(分片) | 单线程(I/O 线程) | 单线程(I/O 线程) | 每个核心(无共享) | 多线程 |
全文和向量搜索(FT.*) |
内置 | 内置(查询引擎) | 独立模块 | 内置 | 否 |
| Lua 脚本 | lua 构建 |
是 | 是 | 是 | 是 |
截至 2026 年 10 月。有内容过时或错误?请 提交 issue。
性能
吞吐量、延迟、向量搜索和向量摄入。点击查看全分辨率视频。
以下所有数据均来自 2026 年 10 月在 AWS Graviton3 裸金属上的一次会话:服务器位于 c7gn.metal(64 vCPU),限制在 32 核,负载生成器位于同一置放群组中的第二个 c7gn.metal 上。每个引擎在服务器上单独运行,一个接一个。
键值
通过 kivi-benchmark 的 run-matrix.sh 运行 memtier_benchmark:1000 万个键,100 字节值,每个场景 30 秒,两轮平均值;300 个连接启用流水线,1200 个连接不启用流水线。
| ops/s | KiviDB 1.1.0 | Dragonfly 2.0.2 | Redis 8.10 | Redis Cluster(32 分片) |
|---|---|---|---|---|
| GET,流水线 16 | 21.2M | 9.1M | 2.4M | 4.7M |
| SET,流水线 16 | 19.2M | 8.5M | 2.0M | 4.7M |
| GET,无流水线 | 3.07M | 3.35M | 1.32M | 1.46M |
| SET,无流水线 | 3.12M | 3.38M | 1.54M | 1.46M |
| p99 延迟,GET / SET,流水线 16 | 0.36 / 0.42 ms | 0.88 / 1.07 ms | 2.2 / 2.7 ms | |
| 每键内存 | 177 B | 134 B | 178 B | 183 B |
向量搜索
在 glove-25-angular 上运行 redis/vector-db-benchmark(118 万向量,25 维):HNSW,M=16,EF_CONSTRUCTION=256,100 个客户端以每批 64 个上传,然后在 ef 64、128、256 和 512 下查询。
| KiviDB 1.1.0 | Dragonfly 2.0.2 | Redis 8.10(查询引擎) | |
|---|---|---|---|
| ef 64 时的查询/秒(recall@10) | 59.3k(0.943) | 41.3k(0.912) | 31.8k(0.912) |
| ef 128 时的查询/秒 | 50.7k(0.961) | 40.3k(0.937) | 28.9k(0.937) |
| ef 256 时的查询/秒 | 31.5k(0.989) | 36.2k(0.979) | 21.1k (0.979) |
| ef 512 时的每秒查询数 | 18.7k(0.998) | 29.8k(0.995) | 13.7k(0.995) |
| 数据摄取与索引构建 | 31 秒 | 13 秒 | 38 秒 |
| 摄取后的内存占用 | 1.66 GB | 1.13 GB | 1.07 GB |
- 方法与脚本:kivi-benchmark
- 最近一次自动化运行:benchmarks/LATEST.md
结果取决于运行环境。请将公布的数值视为一次受控采集,而非保证值,并请在你自己的硬件和工作负载上进行测量。
向量搜索(Redis Stack 风格 FT.*)
KiviDB 实现了兼容 Redis Stack 的搜索与向量命令,因此现有客户端和教程基本可以原样使用。可将它们用于哈希字段上的全文检索(BM25)、标签 / 数值以及向量 ANN(FLAT 或 HNSW)。
快速开始
- 创建索引:在具有指定前缀的键上创建索引,至少声明一个
VECTOR字段(HNSW 或 FLAT),以及可选的TEXT/TAG/NUMERIC字段:
redis-cli -p 6380 FT.CREATE idx ON HASH PREFIX 1 doc: SCHEMA \ vec VECTOR HNSW 10 TYPE FLOAT32 DIM 128 DISTANCE_METRIC COSINE M 16 EF_CONSTRUCTION 128
-
存储向量:以原始 FLOAT32 小端字节形式存入哈希字段(
DIM × 4字节),与 Redis Stack 及redis-py/numpyblob 的约定相同。请使用客户端支持二进制安全的HSET(tests/e2e/下的集成测试中有示例)。 -
使用 KNN 查询(Dialect 2),将查询向量作为具名二进制参数传入:
redis-cli -p 6380 FT.SEARCH idx '*=>[KNN 10 @vec $q]' PARAMS 2 q <blob> DIALECT 2
完整的命令接口、过滤器、混合搜索和边界情况见 COMMANDS.md(搜索 FT.CREATE、FT.SEARCH、FT.HYBRID 等)。
持久化与重启
- 原生快照(
dump.kdb)会存储键、索引模式,并且当你在索引已填充的情况下执行SAVE/BGSAVE时,还会存储每个向量字段的 HNSW 图,因此重启后的搜索质量与关机前所拥有的图一致。 - 启动时重建搜索索引期间,大多数命令会返回
LOADING,直到重建完成;PING、INFO及其他少数命令仍可正常工作。 - 在大量摄取数据后,请运行
SAVE(或安排BGSAVE),以便下次启动时从磁盘重新加载图,而不是从哈希重建。
构建
KiviDB 有四种变体,在构建时通过 Cargo features 选择:
| 变体 | Cargo features | 新增功能 |
|---|---|---|
default |
无 | 核心服务器,不含 Lua 或 TLS |
lua |
lua |
Lua 脚本(EVAL、EVALSHA、SCRIPT、FUNCTION、FCALL 等) |
tls |
tls |
TLS 监听器,以及集群节点与副本之间的 TLS |
full |
lua,tls |
两者兼具 |
在未启用 Lua 的构建中,脚本命令会返回错误。未启用 TLS 的构建在指定 --tls-port 时会拒绝启动,而不是以明文方式提供服务。
从源码构建
需要 stable Rust 工具链(rust-toolchain.toml 会选择带 rustfmt 和 clippy 的 stable)。该 crate 使用 2024 edition;其检查所依据的最旧工具链为 Rust 1.89,即 Dockerfile 构建所用的版本。
git clone https://github.com/kividbio/kividb.git cd kividb cargo build --release # default variant cargo build --release --features lua # with Lua scripting cargo build --release --features tls # with TLS cargo build --release --features lua,tls # full ./target/release/kividb
在 Linux 上,当内核允许时服务器会使用 io_uring,否则回退到 Tokio(--io-model auto,即默认值)。
如需自行构建 Docker 镜像,docker build -t kividb . 会构建默认变体;docker build --build-arg KIVIDB_FEATURES=lua,tls -t kividb:full . 会构建另一个变体。
运行 KiviDB
./target/release/kividb # listens on 0.0.0.0:6380
redis-cli -p 6380 PING任何 Redis 客户端均可使用;将其指向端口 6380。
保护模式
保护模式默认开启,与 Redis 相同。开启期间,如果未设置绑定地址(配置文件中为 --bind 或 bind)且 default 用户没有密码,则只有同一台机器上的客户端(回环地址)可以连接。其他任何客户端都会收到一个 -DENIED 错误,其中说明了可选项,随后连接被断开。
要接受来自其他机器的客户端,请执行以下操作之一:
- 设置密码:
--requirepass <password>,或ACL SETUSER default ><password>; - 设置绑定地址:
--bind <address>; - 关闭保护模式:在配置文件中设置
--protected-mode no、protected-mode no,或从本地客户端执行CONFIG SET protected-mode no。
如果你将其关闭或绑定到公网地址,请确保服务器在没有密码的情况下无法从互联网访问。
Docker
镜像发布到 Docker Hub 和 GitHub Container Registry,两处的标签相同:
docker pull kividb/kividb:latest
# or
docker pull ghcr.io/kividbio/kividb:latestlatest 以及诸如 v1.1.0 的版本标签是默认变体;v1.1.0-lua、v1.1.0-tls 和 v1.1.0-full 是其他变体。镜像为 amd64 和 arm64 构建。
docker run -p 6380:6380 kividb/kividb
容器通过其网络访问,永远不会从回环地址访问,因此镜像的默认命令是 --protected-mode no。你传入的参数会替换该默认值,这会使保护模式重新开启。当你传入自己的标志时,请设置密码(推荐)或自行添加 --protected-mode no:
docker run -p 6380:6380 ghcr.io/kividbio/kividb \
--requirepass "change-me" \
--databases 8 \
--loglevel debug使用 AOF 持久化(挂载卷以便数据在重启后保留;服务器在 /home/kividb 中以用户 kividb 运行):
docker run -p 6380:6380 \ -v $(pwd)/data:/home/kividb \ ghcr.io/kividbio/kividb --aof --requirepass "change-me"
使用 --aof 时,每次写入都会追加到 appendonly.aof,并在启动时重放该文件,因此崩溃最多丢失约最后一秒的写入(fsync 间隔),而不是自上次快照以来的所有内容。当存在 AOF 时,它就是事实来源,不会加载快照;原因见 docs/PERSISTENCE.md。
容器中的 io_uring:Docker 的默认 seccomp 配置文件在近期版本中会阻止 io_uring,KiviDB 随后回退到 Tokio。要在 Linux 主机上允许它,请使用 --security-opt seccomp=unconfined 运行(在生产环境中使用前请了解这允许了什么)。
发布二进制文件
Linux(x86_64、aarch64)和 macOS(Apple silicon、Intel)的发布二进制文件发布在 GitHub Releases 上。下面的 latest/download 链接始终指向最新版本;将 latest/download 替换为 download/v1.1.0 可固定版本。
# Linux x86_64 curl -LO https://github.com/kividbio/kividb/releases/latest/download/kividb-linux-x86_64.tar.gz tar xzf kividb-linux-x86_64.tar.gz ./kividb # Linux aarch64 (an ARMv8.1 CPU or newer: Graviton2 and later, Ampere; not a Raspberry Pi 4) curl -LO https://github.com/kividbio/kividb/releases/latest/download/kividb-linux-aarch64.tar.gz # macOS, Apple silicon / Intel curl -LO https://github.com/kividbio/kividb/releases/latest/download/kividb-darwin-aarch64.tar.gz curl -LO https://github.com/kividbio/kividb/releases/latest/download/kividb-darwin-x86_64.tar.gz
除默认变体外,每个变体的名称都在文件名中:kividb-lua-linux-x86_64.tar.gz、kividb-tls-…、kividb-full-…。默认变体还为 Linux 打包为 kividb_amd64.deb / kividb_arm64.deb 和 kividb.x86_64.rpm / kividb.aarch64.rpm,由 nfpm 从 packaging/nfpm.yaml 构建。一个 SHA256SUMS.txt 文件列出了发布中每个文件的校验和。
curl -LO https://github.com/kividbio/kividb/releases/latest/download/kividb_amd64.deb && sudo dpkg -i kividb_amd64.deb curl -LO https://github.com/kividbio/kividb/releases/latest/download/kividb.x86_64.rpm && sudo rpm -i kividb.x86_64.rpm
配置
KiviDB 通过命令行标志或 Redis 风格的配置文件(每行一条指令,例如 port 6380 或 appendonly yes)进行配置。如果存在,则从 /etc/kividb/kividb.conf 读取该文件;--configfile <path> 指定另一个文件。命令行上给出的标志优先于文件中的相同设置。运行 kividb --help 获取完整列表。
| 标志 | 默认值 | 描述 |
|---|---|---|
--port |
6380 |
监听的端口 |
--bind |
0.0.0.0 |
监听的地址。显式设置它会关闭保护模式 |
--protected-mode <yes|no> |
yes |
参见保护模式 |
--threads |
0(自动) |
工作线程数;自动为核数减 2(低于 4 核时使用全部核) |
--databases |
16 |
数据库数量 |
--dir <path> |
起始目录 | dump.kdb、appendonly.aof 和 nodes.conf 所在的位置 |
--aof |
关闭 | 仅追加文件持久化 |
--maxmemory <bytes> |
0(无限制) |
内存限制 |
--maxmemory-policy |
noeviction |
达到限制时的行为:noeviction,或 allkeys-* / volatile-* 淘汰策略(kividb --help 列出了它们) |
--loglevel |
info |
debug、verbose、notice(或 info)、warning、nothing |
--logfile <path> |
标准错误 | 将日志写入文件 |
--log-format <text|json> |
text |
日志行格式 |
--io-model |
auto |
auto、uring 或 tokio(io_uring 仅限 Linux) |
--requirepass <password> |
无 | default 用户的密码 |
--aclfile <path> |
无 | 从中加载用户的 ACL 文件 |
--replicaof <HOST> <PORT> |
无 | 从主节点复制 |
--replica-announced-port <port> |
服务器端口 | 通过 REPLCONF listening-port 向主节点通告的端口 |
--slowlog-log-slower-than <us> |
关闭 | 慢日志阈值,单位为微秒(0 记录每条命令) |
--slowlog-max-len <n> |
128 |
保留的慢日志条目数 |
--cluster-enabled <yes|no> |
no |
集群模式:集群总线使用 <port> + 10000,拓扑信息存于 nodes.conf,包含 gossip、故障检测与故障转移 |
--cluster-node-timeout <ms> |
15000 |
在判定对端疑似故障前等待回复的时间 |
--tls-port <port> |
0(关闭) |
TLS 监听器(仅 TLS 构建版本) |
--tls-cert-file,--tls-key-file |
无 | 服务器证书与密钥(PEM) |
--tls-ca-cert-file |
无 | 用于校验客户端证书的 CA |
--tls-auth-clients <yes|optional|no> |
yes |
客户端是否必须出示证书(仅在 --tls-ca-cert-file 时生效) |
--update-check <yes|no> |
yes |
启动时更新检查 |
TLS
TLS 客户端在单独的端口 --tls-port 上连接;明文流量仍使用 --port。
cargo build --release --features tls
./target/release/kividb --port 6380 --tls-port 6381 --tls-cert-file cert.pem --tls-key-file key.pem
redis-cli --tls -p 6381 --cacert ca.pem # ca.pem: the CA that signed cert.pem客户端证书(双向 TLS)。使用 --tls-ca-cert-file ca.pem 时,客户端必须出示由该 CA 签发的证书;其他客户端会在握手阶段被拒绝。--tls-auth-clients optional 接受未出示证书的客户端,但仍会拒绝无效证书,而 --tls-auth-clients no 不会要求出示证书。使用 redis-cli 时:redis-cli --tls -p 6381 --cacert ca.pem --cert client.pem --key client.key。
客户端在 TLS 端口上必须使用 TLS。对该端口的明文连接(例如不带 --tls 的 redis-cli -p 6381)会导致握手失败,服务器会记录 [TLS] handshake failed。对于 memtier_benchmark,请添加 --tls(若使用自签名证书,还需添加 --tls-skip-verify)。
日志与错误
日志输出到标准错误,或输出到 --logfile。docs/LOGGING.md 描述了日志;docs/ERRORS.md 解释了警告、错误和错误回复,以及针对每种情况的处理方法。
启动时更新检查
KiviDB 的发布版本在启动时会向 https://github.com/kividbio/kividb/releases/latest 发出 一次 HTTPS 请求,该地址与您查找最新版本时打开的页面相同。GitHub 会以重定向到该版本标签的方式应答;如果该版本比正在运行的构建更新,KiviDB 会在启动横幅之前打印一条带有链接的简短提示。除请求本身外不会发送任何内容,请求的 User-Agent 为 kividb/<version>:不包含主机名、配置、密钥、数据或标识符。GitHub 会看到该请求的源 IP 地址,这与任何 Web 服务器一样。
启动时最多等待 1.5 秒以获取回复;失败仅以调试级别记录,绝不会影响客户端。回复中只接受版本格式的标签,不会打印回复中的其他任何内容。
以下任一方式均可将其关闭:
- 命令行中的
--update-check no; - 配置文件中的
update-check no; - 环境变量中的
KIVIDB_NO_UPDATE_CHECK=1。
调试构建也绝不会执行该检查,设置了 CI 环境变量时同样不会执行。--update-check-url 可将其指向另一个 https:// 地址,例如封闭网络内的镜像。docs/UPDATE_CHECK.md 中有详细说明。
贡献
欢迎贡献。有关如何构建、测试和提交更改,请参阅 CONTRIBUTING.md。贡献需依据 贡献者许可协议 接受,您需在首次提交拉取请求时签署该协议。
安全
请不要在公开 issue 中报告安全漏洞。有关如何私下报告,请参阅 SECURITY.md。
许可证
Copyright (c) 2026 KIVIDB PRIVATE LIMITED。
KiviDB 是开源软件,采用 GNU Affero 通用公共许可证第 3 版(AGPL-3.0-only)许可,该许可证已获 OSI 批准。您可依据其条款使用、修改和再分发。请参阅 NOTICE。
使用 KiviDB 不会使你的应用受到 AGPL 约束。通过网络、经由任意 Redis 客户端与 KiviDB 通信的应用是一个独立的程序:你可以在任何产品中运行未经修改的 KiviDB 作为数据库,无论开源还是闭源、商业与否,都无需对你的应用代码承担任何义务。AGPL 在 GPL 之外只多要求一件事:如果你修改了 KiviDB 本身,并让他人通过网络使用你修改后的版本(例如作为托管服务),你必须向他们提供你所修改的 KiviDB 的源代码。
商业许可。KIVIDB PRIVATE LIMITED 拥有 KiviDB 的版权,并同时以商业许可的方式提供它,面向无法使用 AGPL 软件、或希望修改或嵌入 KiviDB 而不公开其改动的组织。请联系 support@kividb.io。
我们的承诺。我们以 AGPLv3 发布的每个 KiviDB 版本都将持续以 AGPLv3 提供。贡献者许可协议让我们能够在其之外同时提供商业许可;它并不是收回开源版本的手段。
常见问题
- 我可以将 KiviDB 用作我的闭源或商业应用的数据库吗?可以。你的应用通过网络连接 KiviDB;它不是 KiviDB 的衍生作品,AGPL 不对其施加任何义务。
- 我可以将 KiviDB 作为服务提供给我自己的用户或客户吗?可以。如果你运行的是未经修改的版本,你无需发布任何内容。如果你修改了 KiviDB 并通过网络提供该修改后的版本,你必须向该服务的用户提供其源代码。
- 客户端库或我的配置算作修改吗?不算。Redis 客户端、配置文件,以及你发送给 KiviDB 的脚本和函数都不属于 KiviDB 的一部分。
- 我的组织不允许使用 AGPL 软件。商业许可正是为此而设:support@kividb.io。
商标
Redis® 是 Redis Ltd. 的注册商标。其中的一切权利均归 Redis Ltd. 所有。KiviDB 的任何使用仅为指代目的,并不表示 Redis 与 KiviDB 之间存在任何赞助、认可或关联关系。KiviDB 与 Redis Ltd. 无关联。文中提及的其他名称均为其各自所有者的商标。
来源:Hacker News · github.com
