系统设计 Lab
Ad tracking 架构只在约束逼它变时才变。
从最简单的 click/impression collector 开始。用这些 scenario 走一条常规的演化路径,再调 workload,看清楚单机、单个共享 database、或单个 partition 究竟在什么时候不再是好答案。
常规演化 scenario
从左到右点,就是设计好的 demo 路径。每张卡片都会改 workload 输入。
推荐形态
单机 collector
当 workload 还能塞进一台机器时,把 ingest、校验和存储放在一起。
当前架构路径 Ad events -> single collector -> shared database
Clients
Client ad server 发出 click/impression event
Edge / API
Load balancer 主机扩展后做 fanout 和健康检查
Collector 服务 校验、dedupe key,接收 event
Event backbone
持久化 event log 缓冲、replay,并让 consumer 解耦
Partition key 按 campaign 还是 bucket 决定 ordering 和热点
处理
Stream worker window、dedupe、counter,以及 late-event 策略
存储 + serving
Primary DB 负载还小时,简单存原始数据和报表
Serving store OLAP、billing、dashboard 和 risk view
Warehouse 离线真值、保留、审计和 replay 核对
瓶颈
单机 ingest
共享 DB 压力
原始数据存储
Hot partition
新鲜度压力
为什么会变
决策取舍
有出处的规则
这些是模型背后那些经得起推敲的系统设计结论。而滑块上具体的阈值,是被刻意标注成教学假设的。
Partition 能扩 throughput,但 ordering 只在 partition 内成立
Kafka 的 topic 会切成多个 partition 分布在 broker 上;consumer 只在单个 topic-partition 内看到有序的 event。这就是本 lab 把 partition key 既当扩展手段、又当 ordering 取舍的原因。
Apache Kafka docs持久化 queue 和 stream 把故障与 back pressure 解耦
queue 和 streaming 系统把 producer 和 consumer 隔开,让各组件独立扩展或独立失败。当直写开始把 ingest 和报表耦在一起时,这支撑了引入 event log 这一步。
AWS Well-Architected实时 window 需要 event time、watermark 和 late-event 策略
Flink 用 watermark 追踪 event-time 的进度,迟到或乱序的 event 会逼出 latency 与正确性之间的取舍。这支撑了本 lab 里 streaming 和新鲜度的部分。
Apache Flink docs实时 analytics 本质是 event-stream 的 serving 问题
实时 analytics 系统在 event 产生后很快就从 event stream 里提炼洞察。这就是随着读压力上升,dashboard/risk/billing view 应该从原始 ingest 路径里拆出来的原因。
ClickHouse docs教学假设
- 滑块里的容量数字是教学阈值,不是生产环境的 benchmark。
- 真实容量取决于 payload 大小、batching、replication、acks、index、查询形态、磁盘、网络以及运维 SLO。
- 这个 lab 最适合用来做面试推演:先给出最简单的设计,再点名那个逼你加下一个组件的具体约束。