Cloudflare 最近推出了 K2 公测版。这是一项无服务器事件流服务,底层是在 R2 对象存储中运行的分区持久化日志。它以延迟换取成本优势和弹性,Cloudflare 也公布了具体数据:生产端延迟的 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 绑定可以发送批量数据,并指出失败是否值得重试:
const result = await env.EVENTS.send([ { content: new TextEncoder().encode( JSON.stringify({ event: "page_view", path: new URL(request.url).pathname, timestamp: Date.now(), }), ), headers: { "content-type": "application/json" }, },]);if (!result.success) { console.error(`Produce failed: ${result.error.message}`); return new Response("Failed to record event", { status: result.error.retryable ? 503 : 500, });}K2 将数据表示为字节,编码方式由应用自行决定。
如果这些讨论具有代表性,那么争议的焦点并不是这种架构是否合理,而是延迟下限究竟在哪里。Cloudflare 公布的生产端延迟为一秒;用户测得的端到端长尾延迟是这一数字的数倍;竞争对手则声称,通过有状态刷新而非纯对象存储,可以在同一区域配置中实现 50 毫秒延迟。
公测版的限制为 10GB 存储空间,以及每条数据流 30MB/s 的生产吞吐量,用户可以填写表单申请提高限额。消息键和基于键的顺序保证、每秒数 GB 的并行写入、基于推送的 Worker 消费者、更低延迟的 Express 层以及 Kafka 客户端支持,都已列入后续计划。用户可以通过控制面板、API、Wrangler 或 cf 创建数据流;cf 是 Cloudflare 在同一周推出的命令行界面。
原文链接:
https://www.infoq.com/news/2026/10/cloudflare-k2-serverless-streams/





