Cloudflare 最近推出 K2 公测版,一项无服务器事件流服务,底层是在 R2 对象存储中运行的分区持久化日志。它用延迟换取成本优势和弹性,官方公布的生产端延迟 p99 约为一秒。但公开测试显示,端到端交付速度比这个数字更慢。

打开网易新闻 查看精彩图片

这项服务最初只是作为底层管道开发。Basin Pipelines 需要一个持久化位置来暂存事件,等待其基于拉取模式的处理引擎读取并转换。大多数公司遇到这种需求会选择 Apache Kafka,Cloudflare 却无法这样做——Pipelines 运行在覆盖335 个以上城市的边缘网络中,使用临时机器上的少量计算资源,通过公共互联网连接,而 Kafka 的设计并未考虑这些条件。

于是 Cloudflare 选择以已经能提供持久性的基础设施为底座。R2 提供十一个 9的持久性以及强一致性 API。将复制和共识机制下沉至存储层后,上层应用变得更简单,计算与存储也可以彼此独立扩展。

难点在于对象存储无法追加写入,而日志恰恰依赖追加操作。K2 的解法是先在边缘服务的内存中暂存写入,短暂停顿等待更多数据到达,再将整批数据写成一个分段文件。R2 的原子操作负责保证顺序并生成递增偏移量,因此完全不需要协调服务。这段等待时间正是延迟的来源。

Hacker News 上的讨论总体认可这种架构模式,但对性能数据提出了直接质疑。评论者 psanford 概括了更广泛的趋势:对象存储正在迅速成为新的核心数据基础,可以在 S3 上构建 Kafka,也可以在 S3 上构建 GitHub。

评论者 necubi 在讨论中表明自己是原文作者兼 K2 技术负责人。他认同,所有不要求 100 毫秒以内延迟的数据系统都在转向对象存储,并指出 K2 团队与 R2 团队相邻办公,双方可以协同演进产品。这篇文章署名为 Micah Wylde 和 Marc Selwan。

最尖锐的讨论来自一名正在使用公测版的用户。评论者 e1g 报告称,写入延迟低于一秒,但端到端交付延迟达到p95 2.5 秒和p99 7.5 秒,并询问这是否符合预期。一名代表团队回应的评论者表示,这一长尾延迟高于他们的预期,Consume API 的性能仍需改进,读取延迟方面的优化应该会在大约一周内显现。

一家竞争对手提出了不同看法。评论者 sensodine 披露自己供职于同一领域的 s2.dev,他认为对象存储的应用空间可以扩展到 100 毫秒以下,并提到了 S3 Express 和 GCS rapid buckets 等速度更快的对象存储层。这两种服务都采用单可用区架构,因此为了实现区域级持久性,仍然需要进行仲裁写入。他这样描述核心矛盾:在将数据刷新到对象存储之前究竟应该等待多久,必须直接在延迟与 PUT 操作的 API 成本之间作出权衡。他表示,自己的服务使用有状态后端进程持续刷新多租户对象,每个对象包含来自多个数据流的记录,在不破坏单位经济模型的情况下,同一区域内的 p99 确认延迟可以达到约50 毫秒。

定价引发了另一项实质性异议。评论者 nnx 认为,每生产 1GB 数据收取0.04 美元,与其他云事件流服务相比价格合理,但消费数据也收取相同费用就显得偏高:在最简单的情况下,也就是只有一个消费者时,实际使用成本为 0.08 美元/GB;而采用扇出式消费者策略后,成本很快就会变得非常高。这一点尤其重要,因为扇出正是 Cloudflare 为 K2 定位的应用场景之一。数据保留费用另行计算,每月每 GB 收取 0.02 美元;公测期间则不收取任何费用。

同一名评论者也从成本角度为 K2 辩护。他表示,相比 Google Pub/Sub,K2 的优势在于成本,尤其是在需要长期保留数据时。对象存储使其价格远低于自行托管或使用云托管的 Kafka,例如 Amazon MSK 或 Confluent,同时无需管理集群,并且在数据量增长时仍能保持稳定性能。他在同一条评论中再次说明了这项取舍:与依赖本地磁盘复制的系统相比,K2 的生产端和端到端 p99 延迟约为一秒。

多名评论者询问,K2 与采用相同对象存储模式的 AutoMQ 和 WarpStream 有何不同,并指出 Kafka 本身如今也支持无磁盘主题。其中一名评论者给出的答案并非来自 Cloudflare:K2 是为 Cloudflare 生态系统构建的,单独使用它并没有太大意义。

Kafka 兼容性已经列入路线图,K2 技术负责人也坦率解释了原因:他个人并不是 Kafka API 的忠实拥护者,认为对普通用户而言它过于底层,但对于需要深入集成到流处理引擎等其他系统的场景,它又过于高层,此外要有效使用它还需要复杂的客户端库。

K2 转而使用基于租约的消费 API。消费者轮询一个订阅,收到一批租期为五分钟的数据,随后可以确认消费、发送否定确认以请求重新投递,或者延长租约。他表示,这种设计可以提高读取并行度。当消费者是 Workers 时,这一点非常重要,因为 Workers 很容易并行扩展,但单个 Worker 的处理能力并不强。

在生产端,Worker 绑定可以发送批量数据,并指出失败是否值得重试。K2 将数据表示为字节,编码方式由应用自行决定。

公测版的限制为10GB存储空间,以及每条数据流30MB/s的生产吞吐量,用户可以填写表单申请提高限额。消息键和基于键的顺序保证、每秒数 GB 的并行写入、基于推送的 Worker 消费者、更低延迟的 Express 层以及 Kafka 客户端支持,都已列入后续计划。用户可以通过控制面板、API、Wrangler 或 cf 创建数据流;cf 是 Cloudflare 在同一周推出的命令行界面。

如果这些讨论具有代表性,那么争议的焦点并不是这种架构是否合理,而是延迟下限究竟在哪里。Cloudflare 公布的生产端延迟为一秒;用户测得的端到端长尾延迟是这一数字的数倍;竞争对手则声称,通过有状态刷新而非纯对象存储,可以在同一区域配置中实现 50 毫秒延迟。