Page 1 of 1

有了这种架构,将 Go 代码移植到

Posted: Tue Apr 22, 2025 8:49 am
by sakib40
事实证明,重复数据删除缓存的数据存储选择并非显而易见。缓存是尽力而为的,旨在避免对日志中已经存在的条目重新排序。缓存键通过对请求的某些字段进行哈希处理计算得出add-[pre-]chain,缓存值由日志中条目的索引和对其进行排序的时间戳组成。按照当前的日志提交率,重复数据删除缓存在 6 个月的日志数据中可能会增长到超过 50 GB。在 Sunlight 实现中,重复数据删除缓存实现为本地 SQLite 数据库,对它的检查与排序紧密结合,这确保了正确处理来自正在进行的请求的重复项。但是,这种架构无法很好地转换为 Cloudflare 的架构。数据大小无法轻松适应持久对象存储或单数据库 D1限制,并且从排序循环内直接读取和写入远程存储的速度太慢。最终,我们将重复数据删除缓存拆分为两个部分:一个本地固定大小的内存缓存,用于在短时间内(几分钟内)快速进行重复数据删除;另一个是基于Cloudflare Workers KV构建的长期重复数 澳大利亚电报号码数据 据删除缓存,这是一个不受存储限制的全局、低延迟、最终一致的键值存储。

Rust 并在 Workers 上启动一个功能齐全的静态 CT 日志就相对简单了。这样就大功告成了,对吧?其实不然。性能测试表明,该日志每秒只能对 20-30 个新条目进行排序,远低于现有日志每秒 70 个的目标。我们可以通过运行更多日志来解决这个问题,但这会给 CT 生态系统的其他部分带来压力——即 TLS 客户端和监视器,它们需要保存每个日志的状态。此外,用于触发排序的警报通常会延迟数秒,这意味着日志无法以一致的间隔生成新的树头。是时候重新开始设计了。

使其快速
在目前的设计中,我们要求单线程 Durable Object 实例执行大量的多任务处理。DO 处理来自前端工作线程的传入请求,以将条目添加到排序池,并且必须定期对池进行排序,并将状态写入各个存储后端。每秒处理 100 个请求的日志需要在 101 个正在运行的任务(排序的额外任务)以及任何异步任务(例如写入远程存储)之间切换——通常每个排序条目需要 10 次以上的对象存储写入操作和 1 次长期重复数据删除缓存写入操作。难怪排序任务会被延迟!