从 Rust 到 Zig,我写了一个小型 KV 数据库后,终于理解 Zig 到底“怪”在哪

  • King
  • 发布于 5小时前
  • 阅读 23

作为一个Rust爱好者,在真正深入使用Zig之后,我对这门语言的理解发生了转变。在这篇文章中,我将通过vibecoding写的一个小型KV数据库项目来分析Zig和Rust的异同。kvdb:一款轻量级嵌入式KV数据库首先,来看看我们这个项目:kvdb。它是一

作为一个 Rust 爱好者,在真正深入使用 Zig 之后,我对这门语言的理解发生了转变。

在这篇文章中,我将通过 vibe coding 写的一个 小型 KV 数据库 项目来分析 Zig 和 Rust 的异同。

kvdb:一款轻量级嵌入式 KV 数据库

首先,来看看我们这个项目:kvdb。它是一个轻量级、嵌入式的 Key-Value 数据库,采用了 B-tree 索引写前日志(WAL) 来确保数据持久化。核心功能如下:

  • B-tree 结构:实现高效的键值对插入、查找和删除。
  • 写前日志(WAL):确保数据在发生崩溃时的可恢复性。
  • 事务支持:提供基本的事务机制,保证操作的原子性。
  • 页面存储:使用固定大小的 4KB 页进行存储,以优化磁盘 I/O 性能。

然而,尽管这个项目具备了数据库的基本功能,它更像是一个数据库内核的雏形,并不完全是一个成熟的产品。

仓库地址:https://github.com/lispking/kvdb

设计与实现:从 Rust 的眼光看 Zig

在实现过程中,我很快就意识到,Zig 和 Rust 在设计哲学上有显著的差异。

  • Rust 是一门注重“内存安全”的语言,依靠 ownership 系统来确保内存安全,无需垃圾回收。
  • 而 Zig 则倾向于“暴露真相”,减少语言的魔法,给程序员更多的控制权。

Zig 的优点:暴露底层,简洁透明

Zig 在内存管理、控制流等方面非常直接:

  • 没有隐藏的控制流或内存分配,所有操作都是显式的。
  • 没有预处理器,也没有宏。它的语法看起来可能有点古怪,但这正是 Zig 希望消除复杂抽象的体现。

这种设计让我在写 kvdb 时感受到了极大的灵活性,虽然刚开始时有些不适应。

Rust 的优点:内存安全与高抽象

与此相对,Rust 则通过 ownershipborrowinglifetime 等特性提供了强大的内存安全保证,它通过 编译期检查 让程序员避免了许多常见的内存错误。

Rust 会在编译时就要求程序员“遵守规则”,这让我在写代码时不需要担心内存泄漏或者悬空指针等问题。在大型工程中,Rust 的这一点尤其重要。

Zig 让我“重新认识”底层控制感

Zig 的核心哲学是“程序员直接面对控制流和内存管理”。

在我写 kvdb 时,我不得不深入思考每一行代码,思考它如何与硬盘交互、如何管理内存、如何确保数据一致性。

Zig 不会通过隐藏一些复杂的实现来“保护”我,而是让我在做每个决定时都能清楚了解背后的原因。

这种直接控制的感觉,非常像我之前在 C 语言中体验到的那种“强烈的底层感”。不过,Zig 的优势在于,它减少了 C 语言中的许多危险操作,同时仍保留了较高的控制力。

kvdb:当前的局限性与改进方向

尽管 kvdb 的架构已经具备了基本的数据库功能,但它并不完美。当前最显著的问题是 B-tree 索引 部分:

  1. B-tree 目前是单页版本BTree.put() 方法会检查 root 是否已满,如果已满就返回 Error.NodeFull,而没有实现分裂节点的逻辑。这样一来,B-tree 的操作非常简化,无法支持真正的多页树结构。
  2. 事务回滚不完全abort() 方法并没有完全实现 WAL 的回滚机制,而是通过 reload() 恢复状态。虽然 WAL 已经在代码中实现,但恢复操作的精细度还远远不够。
  3. WAL 的性能问题:每次写入 WAL 后都会执行 sync(),这对于性能要求较高的场景来说会成为瓶颈。

B-tree 需要支持节点分裂与多页操作

目前,B-tree 只支持单页插入,当根节点满时直接返回 Error.NodeFull,缺少分裂、合并和多页遍历的完整实现。接下来,应该完善分裂和合并机制,确保数据库能够处理更大规模的数据集。

事务回滚与恢复机制的改进

abort() 方法虽然已经实现了基本的回滚,但还缺少通过 WAL 重放来实现更细粒度的撤销。后续可以进一步增强这一部分,使得系统能够在发生故障时,准确地恢复到正确的状态。

WAL 的性能优化

目前,WAL 的每条记录都进行 sync(),这对于写入密集型应用来说可能会影响性能。未来可以通过引入批量提交、事务提交时才刷新 WAL 等方式来优化这一部分。

总结

Zig 的独特魅力与 Rust 的优势

通过这次使用 Zig 写数据库内核的经历,我更加深刻地理解了 Rust 和 Zig 的设计哲学

  • Rust 强调编译时安全,强调内存和并发安全。
  • 而 Zig 则通过显式的控制流和内存管理,给程序员更多的自由和控制权。

两者各有千秋。

在项目中,我对 Zig 的控制力和透明性有了全新的理解。尽管它的语法有点“古怪”,但它的设计哲学却让我对低层编程有了更深的体验。

Rust

  • 强调安全、性能和并发。
  • 适用于长期维护、大型项目。

Zig

  • 更加透明、直接控制底层。
  • 适合高性能计算、嵌入式应用。

如果让我选择,我会依然选择 Rust 作为主要开发语言,尤其是在大型系统和复杂并发场景下。

但 Zig 的低级控制感和灵活性,绝对值得在一些特定场景下使用。

点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
King
King
0x56af...a0dd
擅长Rust/Solidity/FunC/Move开发