在 Cloudflare Workers KV 等分布式数据存储中存储 ReadableStream 的用例有哪些?

Tra*_*oud 2 distributed-computing cloudflare serverless cloudflare-workers

Cloudflare 自己的全球分布式数据存储 \xe2\x80\x93 Workers KV \xe2\x80\x93可以接受三种“类型”的数据stringArrayBufferReadableStream

\n

虽然前两者的用例足够清楚,但我正在努力弄清楚存储如何ReadableStream有用。我熟悉这个概念:使用它,您可以随着时间的推移“流式传输”不同的值,但是将其放入数据存储中有何意义?典型场景有哪些?

\n

Ken*_*rda 6

string传递、ArrayBuffer、 或之间的区别ReadableStream不在于存储什么数据,而在于数据如何到达那里。请注意,您可以将数据存储为 a string,然后将其读取为 an ArrayBuffer,反之亦然(string使用 UTF-8 将 s 与字节相互转换)。当您传递ReadableStreamto时put(),系统从流中读取数据并存储该数据;它不存储流本身。同样,使用时get(),可以指定"stream"为第二个参数来获取ReadableStream返回值;当您从此流中读取时,它将生成值的内容。

您想要使用流的主要情况是当您想要将 HTTP 请求的正文直接存储到 KV 值中,或者当您想要直接返回 KV 值作为 HTTP 响应的正文时。在这些情况下使用流可以避免将整个值一次性保存在内存中;相反,字节可以在到达时流过。

例如,不要这样做:

// BAD
let value = await request.text();
await kv.put(key, value);
Run Code Online (Sandbox Code Playgroud)

你应该做这个:

// GOOD
await kv.put(key, request.body);
Run Code Online (Sandbox Code Playgroud)

当该值的大小为许多兆字节时,这一点尤其重要。前一个版本会将整个值读入内存以构造一个大值string(包括将 UTF-8 解码为 UTF-16),然后立即将该值写回 KV(将 UTF-16 转换回 UTF-8)。后一个版本直接将字节从传入连接复制到 KV 中,而不会立即将整个值存储在内存中。

同样,对于响应,不要执行以下操作:

// BAD
let value = await kv.get(key);
return new Response(value);
Run Code Online (Sandbox Code Playgroud)

你可以做:

// GOOD
let value = await kv.get(key, "readableStream");
return new Response(value);
Run Code Online (Sandbox Code Playgroud)

这样,响应字节就会从 KV 流式传输到 HTTP 连接。这不仅可以节省内存和 CPU 时间,还意味着客户端可以更快地开始接收字节,因为您的 Worker 不会等到接收到所有字节才开始转发它们。