MoonKV 是一款完全采用 MoonBit 语言原生实现、基于经典 Bitcask 模型的高性能嵌入式键值(Key-Value)存储引擎。 本项目借鉴了 Erlang/Riak 数据库底层的 Bitcask 存储模型,采用**追加写日志(Write-Ahead Log, WAL)与内存索引(Keydir)**相结合的架构。写入时仅进行顺序追加写入,从而提供极高的写入吞吐量;读取时通过内存中维护的
版权所有:中国计算机学会技术支持:开源发展技术委员会
京ICP备13000930号-9
京公网安备 11010802047560号
MoonKV
MoonKV is a small embedded, append-only key-value store written entirely in MoonBit. It follows the Bitcask model: writes are appended to a write-ahead log, point reads use an in-memory key directory, and compaction produces a data segment plus a hint file for faster restart recovery.
What is included
Keydirpoint lookup with averageO(1)lookup cost.Scope and limitations
MoonKV is an embedded storage component, not a network server. The current scope is deliberately single-process and single-writer: applications should not open the same directory concurrently from multiple processes. Values are
Bytes; the convenience CLI uses text values. TTL is a deterministic logical clock measured by database writes, not wall-clock time. The native and JavaScript adapters append directly; the WebAssembly adapter uses a portable read-merge-write fallback and is therefore not an append-throughput benchmark. The native adapter flushes each append, but this project does not claim filesystemfsyncor power-loss durability.User keys may be empty, but keys beginning with
__tx__:or__tx_commit__:are reserved for the transaction journal and are rejected.max_file_sizeand TTL values must both be greater than zero.Quick start
Clone and validate the repository:
Use MoonKV as a dependency in another MoonBit module:
The package metadata declares the public module name, repository, Apache-2.0 license, and the
moonbitlang/x@0.4.46dependency. The full package guide is in README.mbt.md.Library API
DB::open,put,get,delete,put_ttl,merge, and batch commit may raiseMoonKVError. A caller should handleKeyNotFound,InvalidRecord,CorruptedDatabase, andIOErrorat its application boundary.For cache indexes, queues, and local metadata services, the query API provides deterministic ordered reads without exposing internal transaction records:
scan_rangeuses a half-open[start_key, end_key)interval.scan_pagereturnsrows,has_more, and an optional continuation cursor. Scan limits must be positive; expired and deleted keys are omitted.delete_prefixuses a single atomic batch and is bounded by its limit.fingerprintis a stable FNV-1a smoke-check value, not a cryptographic integrity boundary.CLI usage
The CLI uses a 10 MiB default segment size:
The deterministic native benchmark writes and reads the requested number of records in one process. The scripts measure the complete command, including startup and filesystem overhead:
See benchmarks/README.md for methodology and the checked-in baseline format.
Storage and recovery model
Each record has a 28-byte header containing a checksum, logical timestamp, expiration timestamp, key size, and value size, followed by key and value bytes. Compaction rewrites live records to an immutable data segment and a matching hint file. It also creates the next empty active segment before returning, so records written by a later process cannot be appended to the hint-backed segment. The regression in
scripts/cross-process-recovery.shcovers this restart sequence.Verification and CI
The workflow in
.github/workflows/test.ymlruns on Linux, macOS, and Windows. It first attempts MoonBit 0.10.3. Because old 0.10.3 archives can be removed from the official distribution service, the workflow falls back to the current official toolchain only when that exact archive returns an error; the fallback is printed in the job log. It then updates dependencies, checks formatting, checks and builds every target, runs tests with warnings denied, runs the native cross-process recovery regression where the shell is available, and verifies thatmoon infoleaves no generated-interface diff.Local native validation additionally requires a C compiler. The full local equivalent is:
Repositories and project history
License
MoonKV is licensed under the Apache License 2.0. See LICENSE.