Show HN:KiviDB,一款更快的 Redis 兼容内存数据库与向量缓存

Hacker News Top 工具

摘要

KiviDB 是一个用 Rust 编写的多线程 Redis 兼容内存数据库与向量缓存,支持 RESP2/RESP3 协议及内置全文与向量搜索,在 32 核上实现每秒 2100 万次流水线 GET,约为 Redis 8 的 9 倍。

大家好,<p>我从 2026 年 2 月开始做 KiviDB 这个项目。最初它是我想用来学习 Rust 的练手项目——我之前遇到的问题是产品没有 GC 停顿、快照后内存膨胀,导致运行中的 pod 出现 OOM,这实际上是我使用 Dragonfly 时遇到的真实问题。我希望造出一个既能发挥 Rust 优势,又能借鉴 Garnet 和 Dragonfly 等其他方案优点的数据库。我大量使用了 AI,但所有的设计决策都是我自己做的——依据是 Claude 从我日常排障历史记录中挑选出来的测试用例。KiviDB 同时支持 RESP2 和 RESP3 协议。我的 AWS 账户上有一些创世者积分,帮了我不少忙,让我有足够的基础设施和实例来做基准测试。<p>它的键空间按线程分片,天生是多线程架构,在 Linux 上性能最佳(得益于 io_uring,我用的是 tokio_uring crate)。其他操作系统则回退到 tokio。<p>之前一直没有开源,是因为我觉得它还不够成熟。而我认为最好的学习方式,就是为它构建一个跨三大主流云平台(AWS、GCP 和 Azure)的托管云服务。由于我过去主要从事云相关工作,对部署方式、故障转移、SLA 管理等方面有一些经验。在 Claude 的帮助下,我加快了这个过程。网站看起来确实像 AI 生成的垃圾作品(AI slop),但在目前有限的资源下,这已经是能做到的最好水平了。你们可以看看:<a href="https://kividb.io" rel="nofollow">https://kividb.io</a>。我将核心引擎以 AGPLv3 协议开源了——我不想只是"源码可查",因为其他工具也能做到这一点。它支持大约 98-99% 的 Redis 8.10 命令,其中少数命令存在问题,可以在 <a href="https://github.com/kividbio/kividb/issues" rel="nofollow">https://github.com/kividbio/kividb/issues</a> 查看,欢迎贡献者加入。<p>接下来是基准测试数据。最终测试我用了 2 台 c7gn.metal 服务器,放在 us-east1 同一个放置组(placement group)中,使用 memtier-benchmark 工具进行测试。测试设置为:1000 万(10M)个 key,每个 key 100 字节(100B),使用 32 核,分别进行了管道化(pipeline)和非管道化的测试。<p>管道化 16 个 GET 请求:KiviDB 达到 2120 万 ops/sec,对比 Dragonfly 2.0 的 910 万、Redis 8.10 的 240 万、Redis Cluster 32 分片的 470 万。<p>非管道化时,Dragonfly 稍好一些,为 335 万 ops/sec,KiviDB 为 307 万 ops/sec。每个 key 的内存占用也比 Dragonfly 稍高,但与 Redis 几乎相同:KiviDB 为 177B,Dragonfly 为 134B,Redis 为 178B。<p>在向量数据摄取速度上较慢,但在查询方面,低 ef 值时比大多数替代方案更快,不过高 ef 值时比 Dragonfly 慢。更多技术细节可以在 <a href="https://kividb.io/benchmarks" rel="nofollow">https://kividb.io/benchmarks</a> 查看。<p>最简单的试用方式:docker run -d -p 6380:6380 kividb/kividb<p>我期待围绕这个项目建立社区,提供更多基于 Rust 的工具。我欢迎大家提出建设性的批评意见,也重视有理有据的观点。谢谢!
查看原文
查看缓存全文

缓存时间: 2026/10/19 17:04

kividbio/kividb

来源:https://github.com/kividbio/kividb

KiviDB

KiviDB 是一个用 Rust 编写的快速多线程数据库,可作为 Redis® 和 Valkey 的替代方案。它实现了 Redis 协议(RESP2 和 RESP3),因此现有的 Redis 客户端、redis-cli 和各类库无需修改即可使用,同时内置了全文搜索和向量搜索功能。它采用分片内存键值设计,充分利用每个 CPU 核心,并将数据持久化到快照文件和可选的追加写入(AOF)文件中。在相同的 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
# PONG

KiviDB 默认监听 6380 端口,而非 Redis 的 6379 端口,因此两者可以同时运行。将客户端指向该端口即可,也可以通过 --port 6379 指定端口。

  • 协议:兼容 Redis 的命令集(支持的命令详见 COMMANDS.md)
  • 搜索与向量:提供 Redis Stack 风格的 FT.* 命令,支持全文、标签、数值及向量(FLAT / HNSW)搜索
  • Lua 脚本:可选的 Cargo feature。使用 --features lua 构建后可用 EVAL、SCRIPT、FUNCTION、FCALL 等相关命令(详见 脚本命令(Lua))
  • TLS:可选的 Cargo feature(--features tls)
  • 默认监听地址:0.0.0.0:6380,并启用受保护模式
  • 许可证:GNU Affero General Public License v3(AGPL-3.0-only),开源;使用 KiviDB 不会将你的应用程序纳入 AGPL 范围;详见许可证

仓库:github.com/kividbio/kividb(https://github.com/kividbio/kividb)· 官网:kividb.io(https://kividb.io)

对比

KiviDBRedis 8Valkey 8DragonflyKeyDB
许可证AGPL-3.0RSALv2、SSPLv1 或 AGPL-3.0BSD-3-ClauseBSL 1.1BSD-3-Clause
语言RustCCC++C++
命令运行方式每个核心(分片)单线程(I/O 线程)单线程(I/O 线程)每个核心(无共享架构)多线程
全文与向量搜索(FT.*)内置内置(Query Engine)独立模块内置无
Lua 脚本lua 构建版本支持支持支持支持

数据截至 2026 年 10 月。发现信息过时或有误?请提交 issue(https://github.com/kividbio/kividb/issues/new/choose)。

性能基准测试

吞吐量、延迟、向量搜索与向量摄取。点击查看完整分辨率视频。

以下所有数据均来自 2026 年 10 月在 AWS Graviton3 裸金属服务器上的一次测试:服务端为 c7gn.metal(64 vCPU),限制使用 32 核;负载生成端为同一放置组中的另一台 c7gn.metal。每个引擎在服务端上单独运行,依次测试。

键值

通过 kivi-benchmark 的 run-matrix.sh 运行 memtier_benchmark:1000 万个键、100 字节的值、每个场景 30 秒、两轮取平均值;300 个连接使用流水线,1200 个连接不使用流水线。

ops/sKiviDB 1.1.0Dragonfly 2.0.2Redis 8.10Redis Cluster(32 分片)
GET,流水线 162120 万910 万240 万470 万
SET,流水线 161920 万850 万200 万470 万
GET,无流水线307 万335 万132 万146 万
SET,无流水线312 万338 万154 万146 万
p99 延迟,GET / SET,流水线 160.36 / 0.42 ms0.88 / 1.07 ms2.2 / 2.7 ms
每个键的内存177 B134 B178 B183 B

向量搜索

使用 redis/vector-db-benchmark(https://github.com/redis/vector-db-benchmark)在 glove-25-angular 数据集(118 万个向量,25 维)上测试:HNSW,M=16,EF_CONSTRUCTION=256,100 个客户端以每批 64 上传,然后分别以 ef 64、128、256 和 512 进行查询。

KiviDB 1.1.0Dragonfly 2.0.2Redis 8.10(query engine)
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 GB1.13 GB1.07 GB
  • 方法论与脚本:kivi-benchmark(https://github.com/kividbio/kivi-benchmark)
  • 最近一次自动化运行结果:benchmarks/LATEST.md

测试结果取决于运行环境。请将已发布的数据视为一次受控测试的快照,而非性能保证,请在自己的硬件和工作负载上进行实测。

向量搜索(Redis Stack 风格的 FT.*)

KiviDB 实现了兼容 Redis Stack 的搜索与向量命令,因此现有客户端和教程基本无需修改即可使用。可用于对哈希字段进行全文搜索(BM25)、标签/数值搜索以及向量 ANN 搜索(FLAT 或 HNSW)。

快速开始

  1. 创建索引:对具有指定前缀的键创建索引,至少声明一个 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
    
  2. 存储向量:以原始 FLOAT32 小端字节序的格式存入哈希字段(共 DIM × 4 字节),这与 Redis Stack 以及 redis-py / numpy blob 的约定一致。请使用客户端的二进制安全 HSET 命令(tests/e2e/ 下的集成测试中有示例)。

  3. 使用 KNN 查询(Dialect 2),以命名二进制参数传入查询向量:

    redis-cli -p 6380 FT.SEARCH idx '*=>[KNN 10 @vec $q]' PARAMS 2 q DIALECT 2
    

完整的命令集、过滤器、混合搜索及边界情况详见 COMMANDS.md(搜索 FT.CREATE、FT.SEARCH、FT.HYBRID 等)。

持久化与重启

  • 原生快照(dump.kdb)存储键、索引模式,以及当索引中有数据时执行 SAVE / BGSAVE 所保存的每个向量字段的 HNSW 图,因此重启后搜索质量与停机前一致。
  • 启动阶段重建搜索索引时,大多数命令会返回 LOADING,直到重建完成;PING、INFO 等少数命令仍可正常使用。
  • 大批量数据摄取后,请执行 SAVE(或调度 BGSAVE),使下次启动时从磁盘加载 HNSW 图,而不是从哈希中重新构建。

构建变体

KiviDB 提供四种构建变体,通过构建时的 Cargo feature 选择:

变体Cargo feature新增功能
default无核心服务端,不含 Lua 和 TLS
lualuaLua 脚本(EVAL、EVALSHA、SCRIPT、FUNCTION、FCALL 等)
tlstlsTLS 监听器,以及集群节点和副本之间的 TLS
fulllua,tls以上全部

在不含 Lua 的构建中,脚本命令会返回错误。不含 TLS 的构建在指定 --tls-port 时会拒绝启动,而不会以明文方式提供服务。

源码构建

需要 stable Rust 工具链(rust-toolchain.toml 选择了 stable,并包含 rustfmt 和 clippy)。该 crate 使用 2024 edition;最低支持的工具链为 Rust 1.89,即 Dockerfile 使用的版本。

git clone https://github.com/kividbio/kividb.git
cd kividb
cargo build --release                          # 默认变体
cargo build --release --features lua           # 启用 Lua 脚本
cargo build --release --features tls           # 启用 TLS
cargo build --release --features lua,tls       # 完整版
./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
# 监听 0.0.0.0:6380
redis-cli -p 6380 PING

任何 Redis 客户端均可使用,请指向端口 6380。

受保护模式

受保护模式默认启用,与 Redis 一致。当启用时,如果未设置绑定地址(--bind 或配置文件中的 bind)且 default 用户未设置密码,则只有本机(回环地址)上的客户端可以连接。其他客户端会收到 -DENIED 错误(其中说明了可用选项)并被断开连接。

要允许来自其他机器的客户端,请执行以下操作之一:

  • 设置密码:--requirepass <密码>,或 ACL SETUSER default > <密码>
  • 设置绑定地址:--bind <地址>
  • 关闭受保护模式:--protected-mode no,配置文件中 protected-mode no,或在本地客户端执行 CONFIG SET protected-mode no

如果关闭受保护模式或绑定到公网地址,请确保服务端不会在无密码的情况下被互联网访问到。

Docker

镜像发布在 Docker Hub 和 GitHub Container Registry 上,两处标签相同:

docker pull kividb/kividb:latest
# 或
docker pull ghcr.io/kividbio/kividb:latest

latest 和版本标签(如 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 持久化(挂载卷以在重启后保留数据;服务端以 kividb 用户身份在 /home/kividb 目录下运行):

docker run -p 6380:6380 \
  -v $(pwd)/data:/home/kividb \
  ghcr.io/kividbio/kividb --aof --requirepass "change-me"

启用 --aof 后,每次写入都会追加到 appendonly.aof 文件,启动时会重放该文件,因此崩溃最多丢失最近约一秒(fsync 间隔)的写入数据,而非上次快照以来的所有数据。当存在 AOF 文件时,以 AOF 为准,不会加载快照;原因详见 docs/PERSISTENCE.md。

容器中的 io_uring: Docker 的默认 seccomp 配置文件在近期版本中会阻止 io_uring,KiviDB 会回退到 Tokio。要在 Linux 宿主机上允许 io_uring,请使用 --security-opt seccomp=unconfined 运行(在生产环境使用前请先了解该选项的安全影响)。

发布二进制文件

Linux(x86_64、aarch64)和 macOS(Apple silicon、Intel)的发布二进制文件发布在 GitHub Releases(https://github.com/kividbio/kividb/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(需要 ARMv8.1 或更新的 CPU:Graviton2 及以上、Ampere;不支持 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(https://github.com/goreleaser/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 <路径> 可指定其他文件。命令行参数优先于配置文件中的相同设置。运行 kividb --help 查看完整参数列表。

参数默认值说明
--port6380监听端口
--bind0.0.0.0监听地址。显式设置会关闭受保护模式
--protected-mode <yes/no>yes参见受保护模式
--threads0(自动)工作线程数;自动为 CPU 核心数减 2(核心数少于 4 时使用全部核心)
--databases16数据库数量
--dir <路径>启动目录dump.kdb、appendonly.aof 和 nodes.conf 的存放目录
--aof关闭追加写入文件持久化
--maxmemory <字节>0(无限制)内存限制
--maxmemory-policynoeviction达到上限时的策略:noeviction,或 allkeys-* / volatile-* 淘汰策略(kividb --help 列出了所有策略)
--loglevelinfodebug、verbose、notice(或 info)、warning、nothing
--logfile <路径>标准错误输出将日志写入文件
--log-format <格式>text日志行格式
--io-modelautoauto、uring 或 tokio(io_uring 仅限 Linux)
--requirepass <密码>无default 用户的密码
--aclfile <路径>无从文件加载用户的 ACL 文件
--replicaof <ip> <port>无从主节点复制
--replica-announced-port <端口>服务端口通过 REPLCONF listening-port 向主节点通告的端口
--slowlog-log-slower-than <微秒>关闭慢日志阈值(单位微秒,0 记录所有命令)
--slowlog-max-len <数量>128慢日志保留条目数
--cluster-enabled <yes/no>no集群模式:监听 <port> + 10000 的集群总线,拓扑信息存于 nodes.conf,支持 gossip、故障检测和故障转移
--cluster-node-timeout <毫秒>15000多长时间无响应则怀疑节点故障
--tls-port <端口>0(关闭)TLS 监听端口(仅限 TLS 构建版本)
--tls-cert-file、--tls-key-file无服务端证书和私钥(PEM 格式)
--tls-ca-cert-file无用于验证客户端证书的 CA 证书
--tls-auth-clients <yes/no/optional>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:签发 cert.pem 的 CA 证书

客户端证书(双向 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 的 release 构建在启动时会发起一次 HTTPS

相似文章

TurboKV: 极速 Rust 键值存储

Hacker News Top

TurboKV 是一款用 Rust 编写的快速、嵌入式键值数据库,具有原子批处理、有序范围扫描、可配置持久性和压缩功能,以实现高效的数据存储。

KV-Repurpose:用于评估非前缀 KV 缓存复用的测试平台

arXiv cs.CL

本文提出 KV-Repurpose,一个基于 vLLM 的开源测试平台,用于评估超越精确前缀匹配的分段 KV 缓存复用;在服从 Zipf 分布的检索增强生成(RAG)负载下,其词元级缓存命中率达到 63.9%,远高于前缀缓存的 3.3%,并显著降低首词元生成时间(TTFT)。