Cloudflare K2:无服务器事件流

Hacker News Top 产品

摘要

Cloudflare 宣布 K2 进入公开测试阶段,这是其开发者平台(Developer Platform)上一项持久化、完全无服务器的事件流原语,在 R2 对象存储之上实现了分区持久日志,可实现类似 Kafka 的可扩展事件解耦,但专为边缘场景而设计。

暂无内容
查看原文
查看缓存全文

缓存时间: 2026/10/01 17:11

# 发布 Cloudflare K2:无服务器事件流 来源:https://blog.cloudflare.com/cloudflare-k2-streams/ 在传统的远程过程调用(RPC)架构中,存在一个核心难题:生产者与消费者必须在规模和时间上保持对齐。如果你的生产者发送的数据量超出了消费者的处理能力,或者消费者或下游服务不可用,事件就会被丢弃。当有多个消费者需要各自独立地处理数据时,这个问题会更加突出。例如,电商后端在交易完成时会发出事件,这些事件需要被分析系统和欺诈检测服务同时读取。 我们可以通过*解耦*生产者和消费者来解决这个问题——在中间插入一个服务,吸收写入量,同时允许独立的读者按自己的节奏消费数据。 今天,我们正式发布 Cloudflare K2 公测版来解决这一问题。K2 是开发者平台上的一个持久化事件流原语。你将事件发送到 K2 流中,它会将这些事件存储为有序的日志。消费者可以通过多种方式读取事件,例如将读取任务分配给一组消费者,或将所有消息分发给每个消费者。它是完全无服务器的,可以扩展到海量数据量,并支持长期保留,因此即使消费者长时间宕机也不会丢失数据。 在底层,K2 在 R2 对象存储之上实现了分区的持久化日志,这使它能够扩展到巨大的存储规模。 如果你已经准备好开始,可以按照[这里](https://developers.cloudflare.com/k2/get-started/)的指南,在几秒内创建你的第一个流。 ## 边缘上的事件流 我们最初开发 K2,是因为*我们*需要一个位于边缘的持久化缓冲区,最初是作为 [Basin Pipelines](https://developers.cloudflare.com/pipelines/) 的接入层。Pipelines 由一个[流处理引擎](https://www.arroyo.dev/)驱动,该引擎采用基于拉取的模型,这意味着必须由其他系统在事件被读取、转换并写入 R2 之前先存储这些事件。由于我们承诺一旦事件被接受进入 Pipelines 流就绝不会丢弃它们,因此这种存储必须是持久的——即在可能很长的时间内不会丢失数据。 这就是大多数公司会部署 Apache Kafka 的场景。然而,Pipelines 运行在 Cloudflare 边缘网络上,该网络跨越了分布在超过 335 个城市中的大量服务器。我们独特的架构意味着我们往往无法运行像 Kafka 这样的传统分布式系统软件,需要重新思考这些系统的构建和运行方式。 对于有状态服务而言,Cloudflare 的全球基础设施尤其带来一些挑战:我们只能获得相对较小的机器资源切片,这些机器相对短暂,网络连接通常走公共互联网。但我们的基础设施也有几个超能力:无论用户身处世界何处,我们都能与他们保持近距离,并且拥有令人难以置信的水平扩展能力。 在设计最终成为 K2 的持久化缓冲系统时,我们决定依赖我们已有的强大状态原语:R2。像 R2 这样的对象存储系统将极其持久的存储(11 个 9!https://developers.cloudflare.com/r2/reference/durability/)与强一致性 API 结合在一起。将复制和共识委托给存储层,可以使应用层(这里是 K2)变得极其简单、成本更低、性能更高。另一个好处是将计算与存储分离,这意味着两者可以独立扩展。这使我们能够以低成本存储海量历史数据。 我们如何在对象存储之上构建日志?一个直接的问题是,R2 —— 与其他对象存储一样 —— 不支持追加操作,而这是日志的标准操作。相反,我们必须写入完整的文件或段(segment),这些文件需要足够大以摊薄每次写入和读取的成本。我们的做法是:首先在一个边缘服务上将写入累积在内存中。等待一小段时间让数据到达后,我们将所有事件写入为一个段文件。我们利用 R2 的原子操作来实现顺序性和严格递增的偏移量,无需单独的协调服务。 虽然基于 R2 构建有许多优势,但也有一个缺点:产生延迟更高。写入对象存储比写入本地磁盘慢,而且我们必须等待本地批处理累积完成才能开始写入。在 K2 的初始版本中,这会在第 99 百分位响应时间上增加约 1 秒的产生延迟。 我们将在即将发布的技术深度解析文章中分享更多关于 K2 设计的细节。 ## 流、队列还是管道? Cloudflare 已有多个现有的异步投递原语,包括 [Queues](https://developers.cloudflare.com/queues/) 和 [Basin Pipelines](https://developers.cloudflare.com/basin-pipelines/)。在什么情况下应该选择 K2 而不是这些现有产品呢? Queues 和 K2 流之间有一些表面相似之处:两者都接收事件、持久存储事件并将它们投递给消费者。Queues 的设计初衷是跟踪需要异步完成的昂贵或耗时的单项工作。例如,图像处理应用可以将用户请求入队,交由实际的图像处理服务处理。它们支持在单个工作项粒度上的复杂逻辑,如重试、延迟和死信队列(用于失败的尝试)。 相比之下,K2 是为大规模数据移动、长期保留和扇出消费而设计的。消息以批量形式生产和消费——通过牺牲消息级重试来实现高效处理。这种批处理也会带来比队列更高的产生延迟。 Basin Pipelines 是一个无服务器接入服务。你可以发送 Pipeline JSON 事件,这些事件可以被转换并写入 R2 或 Basin Catalog。当最终结果是将事件写入对象存储或 Iceberg 表时,我们推荐使用 Pipelines;当需要自定义处理或写入其他目标时,推荐使用 K2。 ## 快速上手 使用 K2 需要先创建一个流。你可以在账户中创建多个流,用于不同的用例或事件类型。流可以通过 [cf](https://blog.cloudflare.com/cloudflare-cf-cli-launch/)、Wrangler、控制台或 API 创建。 以收集和处理产品分析数据为例。首先,我们用 cf 创建一个流: ``` $ cf k2 streams create --name app_events --http-enabled { "id": "d78b09ee1f50430e9ec92a8af92b0231", "name": "app_events", "retention_seconds": 604800, "endpoint": "https://d78b09ee1f50430e9ec92a8af92b0231.k2.cloudflarestorage.com", "http": { "enabled": true, "authentication": false }, "worker_binding": { "enabled": true }, "created_at": "2026-09-28T15:14:39.053Z", "modified_at": "2026-09-28T15:14:39.053Z" } ``` 有了流之后,我们就可以通过 HTTP API 或 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 以字节形式表示数据,因此你可以使用适合你应用的任何格式或编码方式。 现在事件已经存在于流中,我们可以创建一个订阅。订阅在消费者之间分配工作,实现*读取并行性*——扩展到多个读取器,以处理单台服务器无法承受的更多负载。 我们可以通过 HTTP API 创建一个订阅: ``` $ curl -X POST "https://d78b09ee1f50430e9ec92a8af92b0231.k2.cloudflarestorage.com/subscriptions" \ -H "Authorization: Bearer ${CLOUDFLARE_API_TOKEN}" \ -H "Content-Type: application/json" \ --data '{ "name": "analytics_processor", "start_at": { "type": "earliest" } }' ``` ``` { "result": { "id": "ee13f761783d3823a447a47b572ebf76" }, "success": true, "errors": [], "messages": [] } ``` 订阅创建好之后,我们就可以从每个消费者轮询它: ``` $ curl -X POST "https://4d8f5394e3e733debdeca9c65c5b7439.k2.cloudflarestorage.com/subscriptions/ee13f761783d3823a447a47b572ebf76/consume" \ -H "Authorization: Bearer ${CLOUDFLARE_API_TOKEN}" \ -H "Content-Type: application/json" \ --data '{ "worker_id": "analytics-1", "max_records": 100 }' ``` ``` { "result": { "batch_id": "b7e4c9210a3f468d95c2e1068fdb734a", "leased_until_ms": 1790633929437, "records": [ { "timestamp_ms": 1790633629168, "content": "eyJldmVudCI6InBhZ2VfdmlldyJ9", "headers": { "content-type": "application/json" } }, ... ] }, "success": true, "errors": [], "messages": [] } ``` 当客户端调用 `consume` 时,它会获得该批事件时长为 5 分钟的*租约(lease)*。客户端可以执行以下三种操作之一: - *确认(ack)*该批次,标记其已处理完毕,确保不会被重新投递 - *否认(nack)*(negative ack),表示处理失败,希望该批次被重新投递 - *延长(extend)*其租约,以防处理需要更多时间 ``` $ curl -X POST "https://d78b09ee1f50430e9ec92a8af92b0231.k2.cloudflarestorage.com/subscriptions/ee13f761783d3823a447a47b572ebf76/batches/b7e4c9210a3f468d95c2e1068fdb734a/ack" \ -H "Authorization: Bearer ${CLOUDFLARE_API_TOKEN}" \ -H "Content-Type: application/json" \ --data '{ "worker_id": "analytics-1" }' ``` 这是从 K2 消费的一种方式:将工作分配给多个消费者,使每个消费者获取数据的一部分。另一种读取方式是为每个消费者创建独立的订阅——即发布/订阅(pub/sub)模式——在这种情况下,每个消费者都会看到所有消息。你也可以在两种方式之间灵活组合,维护多个独立的消费者池。 完整 API 详情请参见 [K2 文档](https://developers.cloudflare.com/k2/)。 ## 定价与可用性 K2 今天面向拥有 Workers Paid 订阅的账户在公开测试版中上线,限额如下: - 最高 10GB 存储使用量 - 每个流最高 30 MB/s 的产生速率 如果你需要更高的限额,请通过 Discord 联系我们的团队,或填写[限额提升申请表](https://docs.google.com/forms/d/e/1FAIpQLSf1_eGOxXFGsh4O72fqdvDbYBjzpV3Q6Vf5X3fqpoTHObGFIA/viewform)。 在测试期间,K2 的使用不会计费。我们开始计费后,预计定价如下: 定价 | 项目 | 价格 | | --- | --- | | 产生的数据 | $0.04 / GB | | 消费的数据 | $0.04 / GB | | 保留的数据 | $0.02 / GB / 月 | ## 未来规划 未来几个月,我们对 K2 有一个激动人心的路线图,包括: - 更高的写入并行性,流吞吐量可达数 GB/s - 消息键(message keys)和基于键的顺序保证 - 基于推送的 Worker 消费者 - Express 层级,提供更低的产生延迟和端到端延迟 - 对 Apache Kafka 客户端的即插即用支持 我们非常期待看到你在 K2 上构建的精彩作品!欢迎在 [Cloudflare Discord](https://discord.com/invite/cloudflaredev) 上分享你的反馈。

相似文章

celld — Durable Objects, self-hosted

Lobsters Hottest

celld is a self-hosted, distributed server that runs Cloudflare Workers and Durable Objects code unchanged, using your own S3 bucket for storage and coordination. It claims significantly lower costs and sub-millisecond warm latencies at scale, with data stored in SQLite/LTX format.

Cloudflare Drop

Hacker News Top

Cloudflare 推出了一款名为 'Drop' 的新产品或功能,很可能是一项文件共享或数据传输服务。

@realchendahuang: 我感觉大家对 Cloudflare 的开发程度依然不足 1%。 它现在出了太多的功能。 对象存储用 R2。 后端 API 用 worker。 AI 网关用 AI Gateway。 重计算的,用 Container。 缓存用 KV。 数据库…

X AI KOLs Timeline

本推文介绍了Cloudflare提供的多种开发功能,包括对象存储R2、后端API Worker、AI网关AI Gateway、容器、缓存KV、数据库D1和PostgreSQL连接HyperDrive等,强调其价格便宜、功能丰富且免费额度充足。