5作者: rockeetterark8 个月前
作为 TerarkDB(2019 年被字节跳动收购)的创建者,我近年来开发了 ToplingDB。 ToplingDB 源于 RocksDB,我们用更高效的替代方案替换了几乎所有组件(db_bench 显示 ToplingDB 比 RocksDB 快约 8 倍): * MemTable:SkipList 被 CSPP(Crash Safe Parallel Patricia trie)取代,速度提高了 8 倍。 * SST:BlockBasedTable 被 ToplingZipTable 取代,它通过可搜索的压缩算法实现,体积非常小且速度快,通常每次查找少于 1 微秒: * 键/索引使用 NestLoudsTrie(一个多层嵌套 LOUDS 简洁 trie)进行压缩。 * SST 中的值与比 zstd 更好的压缩比一起压缩,并且可以以 1GB/秒的速度解压缩单个值。 * 不再需要 BlockCache,避免了双重缓存(BlockCache &amp; PageCache) 其他热点也得到了改进: * 省略了将 MemTable 刷新到 L0 的过程,大大减少了写放大,并且对大型(GB 级)MemTable 非常友好 * MemTable 充当“WAL 日志中值的位置”的键索引 * 由于 WAL 文件内容几乎总是在页面缓存中,因此可以通过 mmap 有效地访问值内容 * 当发生刷新时,MemTable 被转储为 SST,而 WAL 被视为 blob 文件 * CSPP MemTable 使用整数索引而不是物理指针,因此内存中格式与文件内格式完全相同 * 用于搜索候选 SST 的前缀缓存和用于迭代器扫描的前缀缓存 * 将固定长度的键前缀缓存到一个数组中,并将其作为 uint 数组进行二分查找 * 分布式压缩(优于 rocksdb 的远程压缩) * 优雅地支持 MergeOperator、CompactionFilter、PropertiesCollector... * 开箱即用,大大减少了开发工作量 * 非常容易在许多数据库节点的现成实例上共享压缩服务 有用的额外功能: * 通过 json/yaml 配置:可以配置几乎所有功能 * 可选的嵌入式 WebView:在 Web 浏览器中显示数据库结构,像动画一样刷新页面 * 通过 http 在线更新数据库配置 MySQL 集成,ToplingDB 已通过 MyTopling 集成到 MySQL 中,MyTopling 源于 MyRocks,并进行了重大改进,类似于 ToplingDB 对 RocksDB 的改进: * WBWI(WriteBatchWithIndex):类似于 MemTable,SkipList 被 CSPP 替换,速度提高了 20 倍(加速超过 MemTable)。 * LockManager &amp; LockTracker:速度提高了 10 倍 * 编码和解码:速度提高了 5 倍 * 其他... 与 InnoDB 相比,MyRocks 有许多缺点,而 MyTopling 在几乎所有方面都优于 InnoDB——除了功能差异。 我们为 RocksDB 创建了大约 100 个 PR,其中大约 40 个被接受。我们的 PR 主要是“小”改动,因为大的改动不太可能被接受。 ToplingDB 已部署在众多生产环境中。 欢迎大家使用 ToplingDB &amp; MyTopling,并在 <a href="https://github.com/topling/toplingdb/discussions">https://github.com/topling/toplingdb/discussions</a> 中进行讨论
2作者: duckerduck8 个月前
嗨,HN 社区,和许多人一样,我对软件工程目前的发展方向很感兴趣,尤其是在编码 LLM 变得越来越普遍的今天。虽然我们还没有达到“自然语言编程”的阶段,但新的抽象概念似乎已经开始形成。为了进一步探索这一点,我构建了 semcheck(语义检查器)。它是一个简单的命令行工具,可以在 CI 或 pre-commit 阶段使用,通过 LLM 检查你的实现是否与你的规范相符。 这个想法的灵感来自于我正在参与的另一个项目,该项目需要一个 GeoJSON 对象的的数据结构。我把 RFC-7946 的文本传递给 Claude,它给了我一个实现方案。之后我来回调整了好几次才满意,但这也意味着 RFC 已经超出了 LLM 的上下文范围。这就是为什么我再次要求 Claude 检查 RFC,以确保我们没有偏离规范太远。我意识到,有一个正式的方法来定义这类检查会很好,可以在 pre-commit 或合并请求流程中运行。 创建这个工具本身就是一次实验,尝试使用 Claude Code 进行“规范驱动开发”,这介于完全的即兴编码和传统编程之间。我的工作流程如下:要求 AI 编写规范和实现计划,手动编辑这些内容以符合我的喜好,然后要求 AI 一次执行一个步骤。小心谨慎,确保 AI 不会偏离我所认为的要求太远。我的第一个提交 [1] 是配置文件结构的规范和实现计划。 一旦 semcheck 能够自检,它就开始发现问题 [2]。我发现这种工作流程不仅能改进你的实现,还能帮助你同时完善你的规范。 除了规范之外,我还开始在我的规则中包含文档,确保我在 README.md 文件中的配置示例和 CLI 标志与实现保持一致 [3]。 最好的是,你可以将发现的问题直接放回你的 AI 编辑器中,进行快速迭代。 一些经验教训: * LLM 非常擅长发现差异,只要你传递给比较函数的文件的数量不是太大,换句话说,真阳性结果相当好。 * 假阳性:LLM 是一个无所不知的(字面意思)家伙,并且经常认为它更懂。LLM 渴望使用它自己的世界知识来发现错误。这既好又成问题。我经常遇到它抱怨我的 Go 版本不存在的情况,但这仅仅是因为它是在该模型的知识截止日期之后发布的。我专门提示 [4] 模型只查找差异,但它经常“选择”使用它的知识。 * 为了减少假阳性,我要求模型给我一个置信度分数(0-1),以表明它对它发现的问题在这种情况下是否实际适用的确定程度。模型总是超级自信,并且几乎只输出 > 0.7 的值。 * 一件确实能显著减少假阳性的事情是,要求模型在为发现的问题分配严重级别之前给出其推理。 * 在我的(粗略的)实验中,我发现像 O3 这样的“思考型”模型并没有在性能上带来多少提升,而且不值得额外的 tokens/时间。(可能是因为我已经要求它给出推理了) * 表现最好的模型是 Claude 4 和 GPT-4.1 如果你认为这在你的工作流程中很有用,请告诉我,以及你需要什么功能才能使其发挥作用。 \[1]: <https://github.com/rejot-dev/semcheck/commit/ce0af27ca0077fe158a179bae5f6258b8a1f73d9> \[2]: <https://github.com/rejot-dev/semcheck/commit/2f96fc428b551d9f48b8fe9bc5321838ac9139f2> \[3]: <https://github.com/rejot-dev/semcheck/blob/47f7aaf98811c54e231a81cb98b1bc9b25d9871d/semcheck.yaml#L26> \[4]: <https://github.com/rejot-dev/semcheck/blob/fec2df48304d9eff959c4eda3ee0d3a92295eb22/internal/checker/prompt_template.go>