System Design: Cloudflare Serverless Social Network
基于 Cloudflare Workers、R2、D1、KV 与 Durable Objects 构建高扩展无服务器社交网络系统设计。
构建像 Twitter/X 或 Threads 这样的社交网络(Social Network)平台,需要应对高写入吞吐量、实时信息流推送(Newsfeed Fanout)以及全球低延迟多媒体资源分发等挑战。
利用 Cloudflare Edge 生态(Workers、R2 Object Storage、D1 Database、KV 以及 Durable Objects),我们可以构建一个完全 Serverless 架构的高性能社交网络。
1. 核心设计挑战#
社交网络系统设计的核心需求包括:
- Feed 广播与推送 (Fanout Service):高效将新动态分发至成千上万甚至数百万关注者。
- 多媒体存储与分发:零出站流量费(Zero Egress Fee)的图片/视频存储与 CDN 加速。
- 全球边缘低延迟缓存:在靠近用户的边缘节点直接读取 Timeline 和用户 Profile。
2. 整体架构设计 (System Architecture)#
系统架构由以下 5 个 Cloudflare 核心组件构成:
- Cloudflare Workers:边缘 API 网关,负责身份验证、发布动态与 Feed 查询。
- Cloudflare R2:无出站流量费的对象存储,用于存储图片与视频。
- Cloudflare D1:分布式 Serverless SQLite 数据库,管理关系型数据(用户、帖子、关注关系)。
- Cloudflare KV:边缘键值存储,高速缓存用户的 Timeline Feed。
- Durable Objects (DO):有状态后台引擎,负责 Feed Fanout 异步推送与点赞/评论计数聚合。
+--------------+ HTTP / Upload +---------------------+
| User Client | <----------------------> | Cloudflare Workers |
+--------------+ +---------------------+
/ | \
Presigned URL | \ Cache Feed
v v v
+-------+ +-------+ +-------+
| R2 | | D1 | | KV |
+-------+ +-------+ +-------+
|
Async Event
v
+--------------------------+
| Durable Object (Fanout) |
+--------------------------+text3. 核心代码实现#
3.1. 基于 Durable Objects 与 KV 的 Feed Fanout 扇出#
src/feed-fanout.ts
export class FeedFanoutDO implements DurableObject {
private state: DurableObjectState;
constructor(state: DurableObjectState) {
this.state = state;
}
async fetch(request: Request): Promise<Response> {
const { authorId, postId, followers } = await request.json();
// 将帖子 ID 异步推送至各关注者的 KV 时间线中 // [!code focus]
const updates = followers.map(async (followerId: string) => {
const feedKey = `user:feed:${followerId}`;
const currentFeed: string[] = (await ENV_KV.get(feedKey, 'json')) || [];
const updatedFeed = [postId, ...currentFeed.slice(0, 99)];
await ENV_KV.put(feedKey, JSON.stringify(updatedFeed), { ttl: 86400 * 7 });
});
await Promise.all(updates);
return new Response('Feed Fanout Completed', { status: 200 });
}
}typescript3.2. 直连 Cloudflare R2 的多媒体上传#
src/media.ts
export async function generateUploadUrl(env: Env, filename: string): Promise<string> {
// 生成 R2 预签名上传 URL
const objectKey = `posts/${Date.now()}-${filename}`;
const signedUrl = await env.MY_R2_BUCKET.createSignedUrl(objectKey, {
expiresIn: 3600,
method: 'PUT'
});
return signedUrl;
}typescript[!NOTE] Cloudflare R2 完全免收出站流量费(Zero Egress Fee),极大降低了大流量高清晰度图片与视频分发的带宽成本。
4. 架构优势与权衡 (Trade-offs)#
[!TIP] 优势:
- 零运维成本(Zero Infra Ops):无需维护 Redis、Kafka 或 Kubernetes 集群。
- 极致边缘响应:Timeline 数据直接在距离用户最近的 Cloudflare KV 节点进行读取。
[!WARNING] 限制:
- 超大 V 扇出处理:对于拥有数百万粉丝的大 V 账号,建议采用混合模式(活跃用户使用 Fanout-on-Write 写入 KV,非活跃用户采用 Fanout-on-Read 实时查询 D1)。