DDIA 架构总脑图 — 由点及面¶
定位:卷一 · 架构全书(索引 + 正文)— 数据密集型系统从需求到硬件的 干货正文,非提纲、非可跑示例工程。
用法:精读 §1–§6 正文 · 查询 §0 + 附录 A · 术语 术语速查 · 全景 展开图(Markmap=目录,拓扑=链路)· 交互 Canvasddia-master-mindmap.canvas.tsx
锚点:站内链接依赖 MkDocsattr_list(见zero.site/mkdocs.yml);若#path-stream跳不准,请 硬刷新(Cmd+Shift+R)后重试,或使用别名#path_stream。
深读:机制细节仍链 Ch.3 / Ch.10 / Ch.11 / Part 2
纵轴(共享):L0 业务需求 → L1 场景/负载 → L2 组件 → L3 分布式运行时 → L4 存储引擎 → L5 OS/内存 → L6 硬件/网络 · **L7** 实践横切(监控/应急/容量/成本)
本书体例¶
| 篇 | 对应 § | 读什么 |
|---|---|---|
| 第一篇 需求与场景 | §1 · §2 | 九宫格 SLA、八类场景契约与架构取舍 |
| 第二篇 组件与链路 | §3 · 展开图拓扑 | Unbundled 分工、边语义、计费主链路 |
| 第三篇 原理下钻 | §4 | 四条运行时路径 + L4–L6 存储栈 |
| 第四篇 实践与 TCO | §5 · §6 | 问题库 runbook、容量公式与人力 |
| 工具章 | §0 · §7 · §8 · 附录 A | 排障罗盘、自测、节点表、百科速查 |
三种读法(分工明确)
| 形态 | 角色 | 何时用 |
|---|---|---|
| Markmap 树 | 全书 目录(可折叠) | 复习结构、找节点 id |
| Mermaid 拓扑 | 链路图 + 图注精读 | 理解数据流、批/流权威边 |
| §1–§6 正文 | 干货主体 | 设计评审、写 SLA、排障叙述 |
维护顺序:Markmap → §8 节点表 → 附录 A → Canvas NODES。
与 DDIA 原书章节对照¶
| 原书章 | 主题 | 本脑图落点 |
|---|---|---|
| Ch.1–2 | 数据系统分类、数据模型 | L0 需求、L1 场景选型 |
| Ch.3 | 存储与检索 | L4、path_query、§4 L4 对比 |
| Ch.4–7 | 分布式:复制、分区、事务 | path_meta、comp_pg、Part 2 专题 |
| Ch.8–9 | 分布式问题、共识 | path_meta、§5 P04–P06 |
| Ch.10 | 批处理 | path_batch、scene_billing |
| Ch.11 | 流处理 | path_stream、scene_realtime |
| Ch.12 | 未来数据系统 | §2 Lambda/Kappa/Lakehouse 决策 |
术语速查¶
正文与组件卡片中的英文/行话,在此统一解释。链接格式
#术语速查-锚点可在文内引用。
| 锚点 | 术语 | 含义(读本页够用) |
|---|---|---|
| anti-pattern | 反模式 | Anti-pattern:常见但长期有害的做法(不是「反对使用模式」)。组件卡片里列举的是应规避的用法。 |
| eos | EOS | Exactly-Once Semantics,精确一次:每条记录在端到端上只生效一次;需 checkpoint + 幂等/事务 sink 配合。 |
| at-least-once | 至少一次 | 同一条记录可能被处理多次;须 幂等写入 或下游去重,否则 sym_dup。 |
| idempotent | 幂等 | 同一操作执行多次,结果与执行一次相同(如按业务主键 REPLACE 分区)。 |
| watermark | Watermark | 事件时间上的「进度线」:估计不会再有更早事件;推进太慢 → 延迟高,太快 → 丢迟到。 |
| event-time | event time | 业务发生时间(点击/下单时刻);归因、对账、计费窗口应基于此。 |
| processing-time | processing time | 算子机器处理时间;只适合运维看延迟,不宜做计费窗口。 |
| backpressure | 反压 | 下游处理不过来时,上游主动降速;Flink 反压高常伴随 lag、checkpoint 超时。 |
| checkpoint | Checkpoint | Flink 分布式快照;失败可从上一成功点恢复,决定 RPO。 |
| lag | lag | 消费落后生产的偏移量;records-lag-max 持续很高即 sym_lag。 |
| parts | parts | ClickHouse MergeTree 的不可变数据片;过多会导致查询变慢(P16)。 |
| merge | merge | CH 后台合并小 part;与查询争资源,积压时 p99 上升。 |
| skew | skew / 倾斜 | 数据按 key 分布极不均,个别分区/subtask 拖全局。 |
| shuffle | Shuffle | 批/分布式计算中按 key 跨节点重分布数据;skew 时单 reducer 瓶颈。 |
| authority | 权威源 | 争议时以哪条链路为准;计费场景通常为 日批 dbt 产出。 |
| false-positive | 假阳性 | 告警看起来像病,实为预期(如调度延迟、ReplacingMergeTree 未 merge 完)。 |
| unbundled | Unbundled | 不用单一厂商全家桶,用 Kafka+Flink+CH+dbt+Airflow 等 最佳组合,靠契约与对账粘合。 |
| lambda | Lambda | 流快 + 批准;两套逻辑,必须 scene_reconcile。 |
| rpo-rto | RPO / RTO | 恢复点目标(最多丢多少数据)/ 恢复时间目标(多久恢复服务)。 |
展开图导读¶
三种读法互补:查询精确定位 · 树形全貌折叠 · 拓扑看链路与层级。
Markmap 由 mkdocs-markmap 渲染(需mkdocs serve或部署站点;Cursor 内看源码即可)。
| 形态 | 适合什么时候 | 跳转 |
|---|---|---|
| 正文 | 设计评审、写 SLA、学机制 | §1 · §2 · §4 |
| 查询 | 线上告警、5 分钟落到层+组件 | §0 罗盘 · 附录 A · Canvas |
| 树形 | 全书目录、复习父子关系 | Markmap |
| 拓扑 | 数据流与批/流权威边 | 纵向下钻 · 计费链路 · 排障路径 |
维护顺序:先改 Markmap 树 → 再改 §8 节点表 → 最后同步 Canvas NODES。
树形 · Markmap(可交互展开)¶
拓扑 · 纵向下钻(L0→L6)¶
主干 = 业务到硬件;L7 横切所有层。
flowchart TB
subgraph L0_box [L0 业务需求]
L0[延迟/一致/成本/可观测]
end
subgraph L1_box [L1 场景]
S1[scene_billing]
S2[scene_realtime]
S3[scene_reconcile]
end
subgraph L2_box [L2 组件]
K[comp_kafka]
F[comp_flink]
CH[comp_ch]
AF[comp_airflow]
DB[comp_dbt]
end
subgraph L3_box [L3 运行时]
PS[path_stream]
PB[path_batch]
PQ[path_query]
PM[path_meta]
end
subgraph L4_box [L4 存储]
ST[L4_storage B+Tree/LSM/列存]
end
subgraph L5_box [L5 OS内存]
OS[L5_os_mem]
end
subgraph L6_box [L6 硬件]
HW[L6_hw_net]
end
L0 --> S1
L0 --> S2
L0 --> S3
S1 --> AF
S1 --> DB
S2 --> K
S2 --> F
S1 --> CH
S2 --> CH
AF --> PB
DB --> PB
K --> PS
F --> PS
CH --> PQ
PS --> ST
PB --> ST
PQ --> ST
PM --> ST
ST --> OS
OS --> HW
sym_hub[sym_lag等 L7]
sym_hub -.-> K
sym_hub -.-> F
sym_hub -.-> CH
sym_hub -.-> ST
图注 · 精读(纵向下钻):L0 输出 SLA 与牺牲项,约束 L1 场景选型;L1 不直接碰磁盘,而是通过 L2 组件实例化。L3 四条路径 共享 L4 存储栈——流写 LSM、批/查询写列存 part、元数据写协调 log。L5–L6 是 所有路径的资源地板(页缓存、顺序/随机 IO、跨 AZ 带宽)。L7 症状 横切 L2–L4:lag 多在 Kafka/Flink,slowq 多在 CH parts,对账不平回到 L0 口径。读图时先定场景(L1),再定路径(L3),最后落到引擎(L4)。
拓扑 · 计费 Unbundled 链路¶
flowchart LR
PG[(业务库 PG)]
Kafka[(Kafka)]
Flink[Flink]
Airflow[Airflow]
Dbt[dbt]
CH[(ClickHouse)]
Daily[日批对账]
PG -->|"CDC/导出 最终一致"| Kafka
Kafka --> Flink
Flink -->|"分钟级 可能滞后"| CH
PG -->|"T+1 有界"| Airflow
Airflow --> Dbt
Dbt -->|"幂等分区"| CH
CH --> Daily
Flink -.->|"流指标"| Daily
| 边 | 语义 |
|---|---|
| PG → Kafka | 至少一次 / 异步 |
| Flink → CH | EOS 或 幂等 sink |
| 日批 | 权威收敛 |
图注 · 精读(计费链路):PG→Kafka 边是 最终一致 CDC,允许短延迟但不可长期断流。Flink→CH 边标注 分钟级近似,不可用于关账。Airflow→dbt→CH 是 T+1 权威路径,对账作业(Daily)必须以该路径为准,流指标仅作输入之一。设计评审时要 画清边的语义(至少一次、幂等、权威),避免「同一张 CH 表双写无版本」。
拓扑 · 排障路径¶
与 §0 罗盘 症状列对应;箭头 = 优先排查方向。
flowchart TB
sym_lag[sym_lag 延迟高]
sym_dup[sym_dup 重复]
sym_loss[sym_loss 丢数]
sym_skew[sym_skew 倾斜]
sym_oom[sym_oom OOM]
sym_reconcile[sym_reconcile 对账不平]
sym_stale[sym_stale 不新鲜]
sym_slowq[sym_slowq 查询慢]
sym_lag --> comp_kafka
sym_lag --> comp_flink
sym_lag --> path_stream
sym_dup --> comp_flink
sym_dup --> path_stream
sym_dup --> path_meta
sym_loss --> path_meta
sym_loss --> path_batch
sym_skew --> comp_kafka
sym_skew --> comp_flink
sym_oom --> comp_flink
sym_oom --> L4_storage
sym_oom --> L5_os_mem
sym_reconcile --> scene_reconcile
sym_reconcile --> comp_dbt
sym_stale --> comp_airflow
sym_stale --> comp_flink
sym_slowq --> comp_ch
sym_slowq --> path_query
sym_slowq --> L4_storage
comp_kafka[comp_kafka]
comp_flink[comp_flink]
comp_ch[comp_ch]
comp_airflow[comp_airflow]
comp_dbt[comp_dbt]
path_stream[path_stream]
path_batch[path_batch]
path_query[path_query]
path_meta[path_meta]
L4_storage[L4_storage]
L5_os_mem[L5_os_mem]
scene_reconcile[scene_reconcile]
图注 · 精读(排障路径):箭头表示 优先排查顺序,不是数据流向。sym_lag 先到 Kafka 再看 Flink,避免一上来改 CH。sym_reconcile 直达 scene_reconcile 与 dbt,勿在 CH 索引上耗一天。sym_oom 同时看 Flink 状态与 L4 LSM。与 §0 表 症状列 一一对应,on-call 卡片可链本图。
0. 5 分钟排障罗盘¶
步骤:① 选症状 → ② 看「先查指标」→ ③ 锁定层
L?→ ④ 打开 §4 对应路径或专题链接 → ⑤ 仍不明记入 QA
| 症状 | 先查指标(本栈) | 优先怀疑层 | 第一锚点 |
|---|---|---|---|
| 端到端延迟高 | Kafka consumer lag;Flink records-lag-max;CH 查询 query_duration_ms |
L2–L4 | §4 流路径 · Ch.11 |
| 数据重复 | Flink 是否 EOS;sink 是否 幂等;Kafka 是否重复投递 | L3 | Part 2 §Ch.7 · Flink EOS |
| 数据丢失 / 偏少 | 副本/ISR;checkpoint 失败;分区是否扫错 dt |
L3–L4 | Part 2 §Ch.5 · Ch.10 有界输入 |
| 倾斜 / 热点 | 某 partition lag 独大;CH 单分区 rows 异常;Flink subtask busy | L2–L3 | §4 流/批 skew · Part 2 §Ch.6 |
| OOM / GC 抖 | Flink managed memory;TM 堆;CH max_memory_usage |
L4–L5 | §4 流状态 · Ch.3 LSM |
| 对账不平 | 时区/归因窗口;从库延迟;流批口径 | L0–L3 | §2 对账场景 · 双指针 §二 |
| 数据不新鲜 | 调度是否成功;sink 写入延迟;max_event_time 滞后 |
L2 | Ch.10 DAG · Airflow SLA |
| 查询突然变慢 | CH parts 数;merge 队列;全表扫 | L4 | §4 查询路径 · ClickHouse |
5 分钟口述模板
症状 __ → 指标 __ → 层 L__ → 组件 __ → 原理点 __ → 下一步 __
症状精读(与 §5 / 附录 A 对齐)¶
sym_lag — 端到端延迟高¶
定义:业务感知的结果晚于 SLA(如大屏晚 30min)。假阳性(术语速查):调度故意延迟、上游停更但无消费。首选指标:Kafka records-lag-max(>10万持续 15min 需行动);Flink 反压;CH max_event_time 与 wall clock 差。下钻:L2 Kafka → L3 Flink path_stream。根因:消费慢、生产激增、Watermark 不推进、sink 背压。应急:扩 consumer/并行度 → 查反压 → 限流生产 → savepoint 重启。→ P07
sym_dup — 数据重复¶
定义:同一业务键计数偏大。假阳性:ReplacingMergeTree 未 merge 完成前查询。指标:幂等键重复率;Flink 是否 EOS;升级前后 offset。下钻:L3 path_stream + path_meta。根因:至少一次 + 非幂等 sink;重复消费;双写。应急:停作业 → 去重表评估 → 修 sink → 重跑分区。→ P03 · T5 自测
sym_loss — 数据丢失 / 偏少¶
定义:行数或金额系统性偏低。假阳性:过滤条件变更。指标:ISR 副本数;checkpoint 连续失败;批作业是否扫错 dt。下钻:L3–L4。根因:副本未同步仍提交;CK 失败仍 commit offset;分区漏跑。应急:停 commit → 从 savepoint 恢复 → 补跑 dt。
sym_skew — 倾斜 / 热点¶
定义:少数 partition/subtask 承载大部分流量。指标:各 partition lag 方差;Flink subtask busy% 极差。下钻:L2 分区键 → L3 shuffle。根因:key 分布不均(campaign 爆款)。应急:加盐、提高 shuffle 分区、临时热点隔离。→ P05
sym_oom — OOM / GC 抖¶
定义:TM/CH 进程内存超限或长时间 GC。指标:Flink managed memory 使用率;RocksDB 状态 GB;CH memory_usage。下钻:L4 LSM → L5 堆。根因:状态无 TTL;单 key 状态过大;查询无内存上限。应急:调并行/TTL → 扩容 → kill 超大查询。
sym_reconcile — 对账不平¶
定义:流批或两套报表差异超阈值。指标:对账 SQL 差异率;event_time 窗口对齐。下钻:L0 口径 → scene_reconcile。根因:双逻辑;时区;从库延迟。应急:以批为准冻结口径 → 修流 → 公告差异窗口。→ P01 · P06
sym_stale — 数据不新鲜¶
定义:展示的数据时间戳明显落后于现在。指标:Airflow 最后成功 execution_date;sink 写入延迟。下钻:L2 调度 → 上游断流。根因:DAG 失败;依赖未就绪;CDC 停。应急:修 DAG → 手动补跑 dt → 检查 CDC。
sym_slowq — 查询突然变慢¶
定义:同类 SQL p99 恶化数倍。指标:system.parts;merge 队列长度;是否全表扫。下钻:L4 path_query。根因:parts 爆炸;merge 积压;并发大查询。应急:限并发 → 触发 merge → 优化分区过滤。→ P09 · P16
1. 需求九宫格¶
设计前 逐格填 SLA;不可能全满 — 标出 牺牲项 与 收敛手段(对账/重跑/降级)。
| 维度 | 在问什么 | 可量化例 | DDIA / 工程要点 | 常牺牲 |
|---|---|---|---|---|
| 延迟 | 用户多久看到结果 | 实时 <1min;报表 T+1 | 批 vs 流;缓存 | 绝对正确 |
| 吞吐 | 单位时间处理量 | 日增 500GB 事件 | 分区并行;水平扩展 | 单条延迟 |
| 可用性 | 挂了多少仍服务 | 99.9% / 年 | 复制、无单点、多 AZ | 强一致 |
| 一致性 | 读到的有多「新」 | 最终一致 + 日对账 | 复制延迟;EOS;幂等 | 最低延迟 |
| 持久性 | 丢不丢数 | RPO 0 / 15min | 同步复制;WAL;checkpoint | 成本 |
| 可演进 | schema/逻辑能否改 | 向后兼容 90 天 | Avro/契约;dbt version | 开发速度 |
| 可观测 | 能否定位问题 | lag、p99、新鲜度 | Metrics + 血缘 + 对账作业 | — |
| 安全合规 | 权限/审计/脱敏 | PII 列级权限 | 行列权限;审计日志 | 分析灵活 |
| 人月成本 | 建+运+on-call | 2 FTE 运维 | 组件数越少越好;Unbundled 换灵活 | 极致性能 |
不可同时最大化(背三角)
- CAP:分区下 C 与 P 必选,A 与强一致取舍 → 数仓多选 AP + 对账(见
scene_reconcile)。 - 延迟–正确性–成本:实时近似 + 日批权威;或全批牺牲延迟。
- 灵活–简单:组件多 → 能力强、运维复杂 → 需要 §3 契约与 §5 runbook。
九维精读(设计前逐格填数)¶
req_latency — 延迟¶
端到端从 事件发生 到 可被查询/展示 的时间。量化:实时 p99 < 60s;报表 T+1 08:00 前产出。与 一致性、成本 冲突:追最低延迟常牺牲批级正确性。收敛:流侧近似 + 日批权威(scene_billing / scene_realtime)。设计必问:用户看的是 event time 还是 processing time?
req_throughput — 吞吐¶
单位时间可处理的事件行数或字节数。量化:日增 500GB、峰值 50k events/s。与 单条延迟 冲突:提高并行度可能增加 shuffle 与排队。收敛:Kafka 分区、Flink 并行度、CH 分区键对齐。设计必问:瓶颈在 ingest、计算还是 sink?
req_avail — 可用性¶
故障时仍能提供约定服务的能力。量化:99.9%(年宕机 <8.76h)。与 强一致、同步复制 冲突。收敛:多副本、无单点 JobManager、跨 AZ;接受异步复制 + 读旧。计费例:CH 副本读;实时例:Flink 从 savepoint 恢复。
req_consist — 一致性¶
读者看到的数据与「真相」的偏离程度。量化:最终一致 + 日对账差异率 <0.01%。与 最低延迟 冲突。收敛:EOS、幂等 sink、批权威覆盖流(P06)。设计必问:有没有写明的权威源?
req_durability — 持久性¶
故障后不丢已承认写入的程度。量化:RPO 0(同步复制)或 RPO 15min(异步 + checkpoint)。与 成本、延迟 冲突。收敛:Kafka min.insync.replicas、Flink checkpoint 到可靠存储、CH 多副本。
req_evolve — 可演进¶
schema 与业务逻辑变更而不炸下游。量化:字段向后兼容 90 天、双写过渡期。与 开发速度 冲突。收敛:Avro/Protobuf 契约、dbt version、契约测试(govern)。
req_observ — 可观测¶
能否用指标与血缘在分钟级定位层与组件。量化:lag、checkpoint 成功率、新鲜度、对账差异率全覆盖。常与其它维正交,但 缺了会拖垮所有 SLA。收敛:统一 dt/event_time 标签、§0 症状表与告警一一对应。
req_security — 安全合规¶
权限、审计、脱敏可证明。量化:PII 列级权限、操作审计保留 1 年。与 分析灵活 冲突。收敛:宽表拆敏感列、脱敏视图、审计日志入 CH。
req_cost — 人月成本¶
建设 + 7×24 运维 + on-call 的总拥有成本。量化:2 FTE 运维 Unbundled 栈。与 极致性能、全强一致 冲突。收敛:组件数克制、批错峰、§6 TCO 填数表季度复盘。
取舍实例(文字)
- 计费 T+1:牺牲实时强一致,换 高吞吐 + 可重跑;用日批 dbt 作权威,流仅作监控近似。
- 实时大屏:牺牲绝对正确,换 秒级延迟;Watermark 允许迟到关闭窗口,日批修正归因。
2. 场景 → 模式 → 组件¶
八类场景统一体例:业务约束 → 数据契约 → 架构模式 → 栈分工 → 备选 → 失败 Top3 → 运维节奏。默认栈面向 广告/计费 Unbundled。
scene-billing — 计费 T+1 报表¶
业务约束:财务与运营需要 按自然日/账单日 闭合的权威金额;允许小时级监控流,但 结算以批为准;必须可重跑历史分区纠错。
数据契约:分区键 bill_date(或 dt)不可变追加;事实表主键含 (order_id, bill_date) 或业务幂等键;时间字段 统一 event_time UTC 写入口径文档;输出 ADS 层只接受 INSERT 覆盖分区 语义。
架构模式:有界批处理 + 不可变分区(Ch.10)。DAG 按日切分,失败重跑同一 dt 不产生双份(幂等写入 CH ReplacingMergeTree 或先删后插策略需写清)。
默认栈分工:comp_pg 业务源 → comp_airflow 调度边界 → comp_dbt 分层 SQL 与测试 → comp_ch ADS 查询。Kafka/Flink 可选作 预聚合监控,不替代日批权威。
备选:Spark 承担重 ETL;Lakehouse 表格式统一湖与仓(见下文决策段)。
失败 Top3:① 分区漏跑导致整日缺失;② 时区导致 bill_date 错日;③ 重跑未幂等重复计费。
运维节奏:日 — DAG 成功率、分区行数环比;周 — 重跑次数与耗时;季 — 最大分区回填 drill。
节点:scene_billing → comp_airflow comp_dbt comp_ch · 深读 Ch.10
scene-realtime — 实时大屏 / 风控¶
业务约束:秒~分钟级可见;7×24;可接受 近似值(与批有已知差异窗口)。
数据契约:Kafka 按 campaign_id 或业务键分区;Flink 使用 event time + Watermark;sink 到 CH 实时表需 幂等键 或 Replacing 版本列。
架构模式:无界流 + 有状态算子(Ch.11)。状态与 checkpoint 决定 RPO;EOS 决定是否重复计数。
默认栈:comp_kafka → comp_flink → comp_ch(分钟级物化)。
备选:Kafka Streams(状态较轻);Spark Structured Streaming 微批(延迟更高)。
失败 Top3:① consumer lag 涨(sym_lag);② checkpoint 超时反压;③ Watermark 不推进导致窗口永不关。
运维节奏:实时 — lag、反压、CK 成功率;日 — 与批对账差异率。
节点:scene_realtime → comp_kafka comp_flink · Ch.11
scene-reconcile — 流批对账¶
业务约束:流指标与批指标 长期同口径;允许日内流快批慢,但差异需可解释、可告警。
数据契约:对账键(如 campaign_id + dt);权威源 = 日批 dbt 产出;流侧表标注 is_approximate;差异率阈值写入 SLA。
架构模式:Lambda — 流近似 + 批权威。内联要点(摘自 Ch.11/Part2):processing time 反映机器何时处理;event time 反映业务何时发生;对账必须用 event time 对齐窗口。迟到事件靠 Watermark 关闭窗口后,需 日批回补 修正。
默认栈:日批 comp_dbt + 对账 SQL(CH)+ 告警;流表仅作输入之一。
失败 Top3:① 双份逻辑(流 SQL ≠ 批 SQL);② 从库延迟导致批读旧;③ 归因窗口不一致(P01)。
运维节奏:日 — 对账作业;周 — 口径文档评审。
节点:scene_reconcile · Part 2 计费链路
scene-cdc — 业务库入湖/入仓¶
业务约束:明细近实时入仓;顺序 per 主键;容忍 schema 演进。
数据契约:CDC 事件含 op(c/u/d)、before/after、主键稳定;全量快照与增量切换点打标;Kafka 保留覆盖 至少一次重放窗口。
架构模式:事务日志 CDC → Kafka → Flink/微批入 CH。顺序性:同一主键进同一分区。
默认栈:Debezium/自研 CDC → comp_kafka → comp_flink 或批量消费。
失败 Top3:① 全量+增量切换重复/丢行;② 主键变更导致分区乱序;③ schema 不兼容下游 NPE(P02)。
运维节奏:日 — lag、DDL 变更清单;发布前 — 契约测试。
scene-attribution — 归因 / 转化窗口¶
业务约束:点击—转化需在 业务时间窗口 内关联;乱序与迟到普遍。
数据契约:事件带 event_time、user_id/device_id;窗口长度(如 7d)写入口径;流侧 Watermark 最大乱序 maxOutOfOrderness 与 允许迟到 需产品签字。
架构模式:Flink event time 窗口 + 侧输出迟到流;日批修正 覆盖窗口边界外迟到(批=权威补丁)。
内联干货:Watermark = 估计「不会再有更早事件」的边界;推进过慢 → 延迟高;推进过快 → 丢迟到。处理时间窗口仅适合 系统监控,不适合计费归因。
失败 Top3:① 用 processing time 做归因;② Watermark 过小丢转化;③ 批未回补导致流批永久差。
scene-scd — 维表缓慢变化¶
业务约束:维度属性变更后,历史报表仍能按 当时有效版本 解释。
数据契约:SCD2:surrogate_key、valid_from、valid_to、is_current;快照表 dbt snapshot 策略(timestamp/check)。
架构模式:批建模维护维度版本;事实表 join 时点有效 维度(as-of join 或宽表冗余需权衡)。
默认栈:comp_dbt snapshot → CH 维度表。
失败 Top3:① 全表重算事实历史;② 快照漏捕获;③ 时区导致版本边界错日。
运维节奏:周 — 快照行数异常;维表变更走评审。
scene-backfill — 历史回填¶
业务约束:重算 N 天分区;不拖垮日常 SLA;输出与日常 同逻辑同幂等。
数据契约:有界 dt 列表;Airflow pool 限制并发;CH 写入同 scene_billing 幂等语义。
架构模式:Ch.10 有界输入 + 可重跑;与在线 DAG 资源隔离。
失败 Top3:① 并发回填抢 Spark/CH(P12);② 逻辑版本与日常不一致;③ 回填写错分区范围。
运维节奏:季 — 回填 drill;回填前 — 容量评估 §6。
scene-dr — 灾备 / 多活¶
业务约束:定义 RPO/RTO;跨 AZ/Region;定期演练可切换。
数据契约:元数据与数据复制策略分离文档化;切换后 脑裂写 防护(幂等、单主写)。
架构模式:异步复制(Kafka 镜像、CH 副本)+ path_meta 共识;配置即代码。
默认栈:CH 多副本;Kafka ISR/镜像;Flink savepoint 跨集群恢复手册。
失败 Top3:① 复制延迟未监控读旧;② 切换双写;③ savepoint 与版本不兼容。
节点:Part 2 §Ch.5
模式对照(横向宽)
| 模式 | 核心 | 何时选 |
|---|---|---|
| Lambda | 批主 + 流快 | 既要 T+1 又要分钟级 |
| Kappa | 一切重放 log | 逻辑可纯流、批=重放 |
| Lakehouse | 湖表格式 + 多引擎 | 统一存储、多分析 |
| Unbundled | 最佳组件组合 | 当前栈:Kafka+Flink+CH+dbt+Airflow |
架构模式决策(Lambda / Kappa / Lakehouse)¶
Lambda:适用 业务已接受双路径(流监控 + 批结算)。优点:各取所长;缺点:两套逻辑 必须对账(scene_reconcile)。不选情形:团队无法维护口径文档与对账作业。
Kappa:适用 逻辑可完全流化、批 = 重放 Kafka 某时间范围。优点:单代码路径;缺点:重放成本高、状态复杂作业难重放历史。不选情形:计费需复杂批聚合、大量维表 join 历史全量。
Lakehouse:适用 多引擎读同一份表格式(Iceberg/Hudi/Delta)。优点:存储统一;缺点:格式与引擎成熟度、运维新技能栈。不选情形:已有 CH 深度优化且团队无湖运维能力。
Unbundled(本栈):在 Kafka + Flink + CH + dbt + Airflow 上显式写清组件契约(§3)与边语义(拓扑图);用 §5/§0 统一排障语言,避免「每个组件一套方言」。
3. 组件架构层(L2)¶
每个组件:解决的需求 · 邻接契约 · 不选的代价 · 专题链接
flowchart LR
subgraph ingest [采集]
Conn[connector]
CDC[CDC]
end
subgraph msg [消息]
Kafka[Kafka]
end
subgraph compute [计算]
Flink[Flink]
Spark[Spark可选]
end
subgraph model [建模]
Dbt[dbt]
end
subgraph store [存储]
CH[ClickHouse]
PG[(OLTP)]
end
subgraph orch [编排]
Airflow[Airflow]
end
PG --> CDC
Conn --> CH
CDC --> Kafka
Kafka --> Flink
Flink --> CH
Airflow --> Dbt
Dbt --> CH
| 组件 ID | 解决什么 | 契约 / 接口 | 不选代价 | 深潜 |
|---|---|---|---|---|
comp-kafka |
削峰、解耦、可重放 log | 分区、offset、schema | 直连耦合、难回溯 | Ch.11 §log |
comp-flink |
低延迟有状态计算 | event time、checkpoint、EOS | 微批延迟高 | flink-streaming |
comp-ch |
OLAP 扫描聚合 | 分区键、MergeTree、副本 | PG 分析慢 | clickhouse-deep-dive |
comp-dbt |
SQL 血缘、测试、分层 | 模型依赖、incremental | SQL 脚本混乱 | dbt-learning-path |
comp-airflow |
何时跑、依赖、回填 | DAG、幂等分区 | cron 地狱 | airflow-data-pipeline |
comp-pg |
事务型源库 | ACID、CDC | — | Part 2 §Ch.7 |
govern |
质量/血缘/权限 | 契约、Great Expectations | 口径漂移 | 待沉淀 |
Unbundled 计费主链路 → 详见 Part 2 应用视角图
组件卡片(精读)¶
comp_kafka — 消息日志¶
边界:只做 持久、有序、可重放 的字节流;不做复杂计算与事务结算。
Ingress:Producer batch、acks、压缩;Egress:Consumer group、offset commit 语义(至少一次 为主)。
反模式(术语速查·反模式):超大消息塞单分区;消费不设 lag 告警;把 Kafka 当数据库长期存全量。
指标:records-lag-max、under-replicated partitions、磁盘使用率。
comp_flink — 流计算¶
边界:有状态 低延迟 计算;不负责最终权威报表闭合。
契约:event time、checkpoint 间隔、状态 TTL、sink 幂等/EOS。
反模式(术语速查·反模式):processing time 做业务窗口;状态无限增长;checkpoint 存本地盘。
指标:checkpoint 成功率、反压 ratio、lastCheckpointDuration。
comp_ch — OLAP¶
边界:读多写追加 的分析库;非 OLTP 行级高频更新。
契约:MergeTree 分区键、排序键、副本一致性级别;写入 batch + part。
反模式(术语速查·反模式):高频小批写入导致 parts 爆炸;无分区过滤的大聚合;忽略 merge 队列。
指标:system.parts 数量、merge 积压、query_duration_ms p99。
comp_dbt — 建模¶
边界:SQL 变换 + 测试 + 血缘;不替代调度与流引擎。
契约:ref/source 依赖、incremental 策略、snapshot SCD。
反模式(术语速查·反模式):全表 scan 的 incremental;测试不覆盖主键唯一;口径只存在于 Slack。
指标:model 运行时长、test failure 率。
comp_airflow — 编排¶
边界:何时跑、依赖、重试;不算子逻辑本身。
契约:DAG 幂等、execution_date 与业务 dt 映射、pool 隔离回填。
反模式(术语速查·反模式):单 DAG 深度过深导致连锁失败;回填无并发上限。
指标:task 成功率、SLA miss、scheduler delay。
comp_pg — 源库¶
边界:ACID 事务真相;分析负载应迁出。
契约:binlog/逻辑复制、主键稳定、CDC 兼容性。
反模式(术语速查·反模式):在 PG 上做重型报表;从库延迟无监控仍切读。
govern — 数据治理¶
三条线:① 质量 — 契约测试(发布前)、dbt test/not null(发布中)、对账作业(发布后);② 血缘 — dbt docs + 调度元数据,回答「指标从哪张表来」;③ 权限 — 列级/行级、PII 脱敏与审计(P14)。SLA 归属:治理失败视为 L0 一致性/安全 违约,而不仅是「数据组杂活」。
4. 原理下钻(L3–L6)四条路径¶
结构:动机 → 端到端 → 机制 → 参数表 → 资源 → 瓶颈信号 → 内联干货。症状对齐 §0。
path-stream — 流路径¶
动机:在 Unbundled 栈中承担 无界事件 的低延迟聚合与投递,连接 Kafka 与 CH 实时层(scene_realtime)。
端到端:Consumer 拉取分区 → 解析/水位线 → KeyBy 进子任务 → 状态读写 → 周期性 checkpoint 对齐 barrier → sink 写 CH。offset 提交点与 EOS 绑定:成功 checkpoint 后才 commit offset(两阶段语义,摘自 Ch.11)。
机制分步
- Source:分区并行度 ≤ Kafka 分区数;offset 可重置用于重放。
- Watermark:event time 推进窗口;乱序容忍由
maxOutOfOrderness控制。 - State:KeyedState 存窗口/聚合;RocksDB 落盘,受 compaction 与 checkpoint 影响。
- Checkpoint:异步快照状态 + 对齐输入 offset;失败则回滚到上一成功点。
- Sink:至少一次需幂等;EOS 需 transactional sink 或幂等键。
参数表
| 参数 | 调大效果 | 调小效果 / 风险 |
|---|---|---|
| 并行度 | 吞吐升、状态分散 | 过高 → 小文件与协调开销 |
| checkpoint 间隔 | CK 开销降 | 失败重做范围变大、RPO 变差 |
| 状态 TTL | 状态无限涨 | 过早淘汰 → 窗口结果错 |
| Watermark 乱序 | 更能等迟到 | 延迟升高 |
| 网络缓冲 | 抗突发 | 内存占用升 |
资源(L5–L6):TM 堆 + managed memory + RocksDB block cache;磁盘顺序写 SSTable 与 CK 文件;网络为反压第一现场。
瓶颈信号:sym_lag、sym_oom、P08、反压、state 体积周环比。
内联干货(Ch.11):流处理 = 处理 无界 数据 + 有状态 + 容错;与批差别在输出随时间演化、需连续 checkpoint。→ Ch.11 · Part 2 三角
path-batch — 批路径¶
动机:有界 输入上构建 派生数据集(日分区 ADS),提供计费权威(scene_billing)。
端到端:Airflow 触发 → dbt/Spark 读有界 dt → shuffle 可选 → 写 CH 新 part 或覆盖分区 → 元数据登记产出时间。
机制分步
- InputSplit:按
dt/文件切分,可重跑同一 split。 - Map:过滤投影,尽量 列裁剪 + 分区剪枝。
- Shuffle:按 key 重分布;skew 时单 reducer 拖全局(sym_skew)。
- Reduce/Agg:哈希聚合内存不足则溢写磁盘。
- Commit:不可变分区追加;失败重跑须幂等。
参数表
| 参数 | 调大 | 调小 / 风险 |
|---|---|---|
| shuffle 分区数 | 并行度升 | 过多小任务开销 |
| 执行器内存 | 减少溢写 | OOM |
| 重跑并发 | 回填快 | 抢资源 P12 |
| 分区粒度 | 并行好 | 过多小 part 拖 CH |
资源:执行器堆、shuffle 中间文件占磁盘;批常可 错峰 换 CPU。
瓶颈信号:单 stage 慢、skew、磁盘满、DAG 连锁失败 P11。
内联干货(Ch.10):批核心 = 有界输入 + 可重跑 + 不可变输出;MapReduce 思想仍存在于 Spark/dbt 底层。→ Ch.10
path-query — 查询路径¶
动机:对 已落盘 列存数据做交互分析与大聚合,不承担持续写入状态(comp_ch)。
端到端:SQL → AST → 分区剪枝 → 多线程读 part → 合并聚合 → 返回;副本读可能 读旧(P04)。
机制分步
- 剪枝:
WHERE dt命中分区;排序键影响 merge 与跳数。 - 读 part:每 part 列文件 + mark 索引;parts 过多 → 打开文件成本高。
- 聚合:内存
max_memory_usage限制;超则 spill 或失败。 - 后台 merge:将小 part 合并;与查询争 IO。
参数表
| 参数 | 调大 | 调小 / 风险 |
|---|---|---|
max_threads |
查询快 | CPU 争用、多查询互相拖 |
| 并发查询上限 | 保护集群 | 排队延迟 |
| TTL / 分区数 | 控制 parts | 删数据影响报表 |
资源:mark/cache 占内存;列存 scan 偏 顺序读(L6)。
瓶颈信号:sym_slowq、P09、parts 爆炸 P16。
内联干货(Ch.3):列存适合 少列大 scan;行存 B+Tree 适合点查更新。→ Ch.3 · ClickHouse
path-meta — 元数据 / 协调路径¶
动机:在分布式组件间维护 领导、成员、进度(offset、作业图、副本集),本身不是业务数据通路但 丢元数据 = 丢进度或脑裂。
端到端:Kafka controller / KRaft;Flink JobManager + checkpoint 元数据;CH ZooKeeper 副本与 merge 协调。
机制要点:Leader 选举;ISR 副本集合;Flink checkpoint 元数据与算子状态分离存储;不展开 Raft 证明,只需知 多数派提交 与 会话超时 导致 rebalance。
参数表
| 参数 | 过大 | 过小 |
|---|---|---|
| ZK session 超时 | 故障发现慢 | 频繁 rebalance |
min.insync.replicas |
写可用性降 | 丢副本仍 ack 的风险 |
| Flink 重启策略 | — | 无限重启掩盖根因 |
瓶颈信号:sym_loss、offset 提交失败、选主抖动、升级后重复 sym_dup。
内联干货(Part 2):复制 = 多副本抗故障;共识 = 多节点对 谁先写 达成一致。→ Part 2 §Ch.5–9
L4–L6 存储栈(共享下钻)¶
| 引擎族 | L4 机制 | L5 内存 | L6 磁盘 | 选型场景 |
|---|---|---|---|---|
| B+Tree | 页分裂、原地更新 | buffer pool | 随机读、WAL 顺序写 | OLTP、点查更新 |
| LSM | MemTable、SSTable、compaction | memtable + block cache | 顺序写、读放大 | 高写、Flink 状态 |
| 列存 MergeTree | part 不可变、后台 merge | mark/cache | 大顺序 scan、压缩 | OLAP、计费汇总 |
三引擎对比长表
| 维度 | B+Tree(PG) | LSM(RocksDB/Flink) | MergeTree(CH) |
|---|---|---|---|
| 写路径 | 原地更新页 | 顺序写 memtable→SST | 追加 part,后台 merge |
| 读放大 | 低(索引稳定) | 多层 SST 合并 | part 多时可高 |
| 写放大 | 随机写、页分裂 | compaction 重写 | merge 重写 |
| 范围查询 | 强 | 中 | 极强(列裁剪) |
| 典型负载 | 事务、点查 | 高写流状态 | 分析聚合 |
| 本栈角色 | comp_pg 源 |
Flink state | ADS 查询 |
为何 Flink 状态偏 LSM:写吞吐高、可落盘;代价是 compaction 与读放大需监控。
为何计费 ADS 用列存:扫描聚合为主、压缩比高;代价是 parts 与 merge 运维。
→ 全文 Ch.3 存储引擎
拓扑 · 存储引擎选型(L4)¶
flowchart TB
Q[负载特征]
Q -->|点查更新 OLTP| BT[B+Tree PG]
Q -->|高写有状态流| LSM[LSM RocksDB]
Q -->|大范围聚合扫描| COL[列存 MergeTree CH]
图注 · 精读:选型看 读写比例与访问模式,非看流行度。B+Tree 优化 读稳定;LSM 用 顺序写换随机写;列存用 不可变 part + merge 换 scan 吞吐。跨层错误:在 CH 模拟 OLTP 高频更新 → parts 爆炸;在 PG 跑全表聚合 → IO 打满。
5. 实践问题库(横切 L7)¶
格式:现象 → 根因 → 设计期规避 → 运行期运维 → 应急 → 演练
数据质量¶
| ID | 现象 | 根因 | 规避 | 运维 | 应急 | 演练 |
|---|---|---|---|---|---|---|
| P01 | 对账恒差固定值 | 时区/汇率/归因窗口 | 统一 event_time 口径文档 |
日对账 SQL | 停发版、回滚口径 | 每月口径回归 |
| P02 | 突增 NULL | 上游 schema 变更 | 契约测试、dbt test | 告警非空率 | 挡板默认值 | 注入坏 schema |
| P03 | 重复计费 | 至少一次+非幂等 sink | 幂等键、EOS | 去重表监控 | 停作业、重跑分区 | 重复灌数演练 |
一致性¶
| ID | 现象 | 根因 | 规避 | 运维 | 应急 | 演练 |
|---|---|---|---|---|---|---|
| P04 | 读旧数据 | 异步副本延迟 | 关键读走主;会话粘滞 | 复制延迟指标 | 切主/降从库读 | 故障切换 drill |
| P05 | 分区倾斜 | 热点 key | 加盐、重分区 | skew 报表 | 临时扩容热点 | 灌热点流量 |
| P06 | 流批不一致 | 双口径双逻辑 | 单定义双实现+对账 | 差异率 dashboard | 以批为准修流 | 对账 fail 演练 |
性能¶
| ID | 现象 | 根因 | 规避 | 运维 | 应急 | 演练 |
|---|---|---|---|---|---|---|
| P07 | Kafka lag 暴涨 | 消费慢/生产激增 | 分区数、消费者数 | lag 告警 | 扩容 consumer、限流生产 | 峰值压测 |
| P08 | Checkpoint 超时 | 状态大/慢盘/反压 | 调间隔、增量 CK、调并行 | Flink CK 成功率 | 重启、savepoint | 状态膨胀注入 |
| P09 | CH 查询慢 | parts 多、merge 慢 | 分区设计、TTL | system.parts |
强制 merge、限并发 | 大查询压测 |
| P10 | dbt 全表扫 | 缺分区过滤 | incremental、分区键 | 运行时长告警 | 杀查询 | 大表 model 审查 |
可用性¶
| ID | 现象 | 根因 | 规避 | 运维 | 应急 | 演练 |
|---|---|---|---|---|---|---|
| P11 | Airflow DAG 失败连锁 | 依赖过深 | 分层 DAG、隔离关键路径 | SLA 任务标记 | 手动 skip 非关键 | 单点 task fail |
| P12 | 回填炸集群 | 并发 backfill | 队列、资源池 | 并发上限 | 暂停回填 | 季度回填 drill |
| P13 | Flink 单 TM 挂 | 数据倾斜/OOM | keyBy 均衡、状态 TTL | task failed 率 | 重启 TM、扩并行 | kill TM 演练 |
安全与组织¶
| ID | 现象 | 根因 | 规避 | 运维 | 应急 | 演练 |
|---|---|---|---|---|---|---|
| P14 | PII 泄露 | 宽表权限粗 | 列级权限、脱敏 | 审计日志 | 撤权、删副本 | 权限评审 |
| P15 | on-call 反复踩坑 | 无 runbook | 链本文 §0 + §5 | 事故复盘写回 | 值班手册 | Game day |
| P16 | CH parts 爆炸 | 高频小批写、无 merge | 批量写、分区 TTL | system.parts 日趋势 |
强制 merge、停写入 | 小批灌入演练 |
| P17 | 反压致 CK 失败 | sink 慢、并行过高 | 异步 sink、限流 | Flink 反压指标 | 降并行、扩容 CH | sink 慢演练 |
高优问题 · 排障叙述¶
P01 — 对账恒差固定值¶
假设:差异额每日稳定。验证:按 dt 比对流批;检查 event_time 与时区;核对归因窗口边界。设计期:口径文档 + 单定义双实现。运行期:日对账 SQL 入 dashboard。应急:停发版、回滚逻辑版本。演练:每月注入时区边界用例。
P02 — 突增 NULL¶
验证:对比上游 schema 版本与 dbt compile 时间线。规避:契约测试阻断发布。应急:挡板列或回滚上游。
P03 — 重复计费¶
验证:幂等键 group by count>1;查 Flink delivery 语义。规避:EOS 或 Replacing 版本列。应急:停作业、去重表、重跑分区。
P04 — 读旧数据¶
验证:副本延迟秒数;是否读从库。规避:关键报表读主或粘滞会话。
P05 — 分区倾斜¶
验证:per-key 行数分布;Flink subtask 指标极差。规避:加盐、重分区键设计。
P06 — 流批不一致¶
验证:双 SQL diff;确认权威源为批。应急:以批覆盖、修流逻辑。→ scene_reconcile
P07 — Kafka lag 暴涨¶
验证:生产速率 vs 消费速率;是否单分区热点。应急:扩 consumer、临时限流。→ sym_lag
P08 — Checkpoint 超时¶
验证:state 大小趋势、CK 存储延迟、反压。规避:增量 CK、调间隔、状态 TTL。应急:savepoint 重启、降并行。
P09 — CH 查询慢¶
验证:EXPLAIN 是否剪枝;parts 数;merge 积压。应急:kill query、off-peak merge。
P10 — dbt 全表扫¶
验证:compiled SQL 无 dt 过滤。规避:incremental + 分区键测试。
P11 — Airflow DAG 失败连锁¶
验证:关键路径 task;非关键是否可 skip。规避:DAG 分层、SLA 标记。
P12 — 回填炸集群¶
验证:回填 pool 并发与 CH CPU。规避:队列与资源上限。→ scene_backfill
P13 — Flink 单 TM 挂¶
验证:是否单 subtask OOM/skew。应急:重启 TM、扩并行、调 TTL。
P14 — PII 泄露¶
验证:审计日志异常访问;宽表权限。规避:列级权限、脱敏视图。
P16 — CH parts 爆炸¶
验证:SELECT count() FROM system.parts 按表;写入 batch 大小。规避:批量写、合理分区粒度、TTL。应急:OPTIMIZE、暂停高频写入。关联:Flink sink 小批 → P17。
P17 — 反压致 CK 失败¶
验证:Flink 反压 graph;CH insert 延迟。应急:降 sink 并行、异步批量、扩容 CH。
日常运维节奏(建议)
| 频率 | 动作 |
|---|---|
| 实时 | lag、CK 失败、Flink 反压、新鲜度 |
| 日 | 对账作业、分区产出、调度成功率 |
| 周 | parts 增长、状态大小趋势、成本报表 |
| 季 | 灾备切换、回填、压测、权限审计 |
6. 容量与成本¶
6.1 机器资源(填数表)¶
Kafka
磁盘_GB ≈ 日增量_GB × 保留天数 × 副本数 × (1 - 压缩率)
网络_MBps ≈ 生产者峰值_MBps × 副本扇出(含副本间复制)
| 变量 | 含义 | 典型区间 | 敏感度 |
|---|---|---|---|
| 日增量_GB | 净写入(压缩后) | 50–500 | 线性乘保留天 |
| 保留天 | 可重放窗口 | 3–14 | +1 天 ≈ +日增量磁盘 |
| 副本数 | 容灾与读扩展 | 3 | 磁盘 ×3 |
| 压缩率 | lz4/zstd 效果 | 0.4–0.6 | 越高磁盘越低 |
| 输入 | 你的值 | 备注 |
|---|---|---|
| 日增量 GB | ||
| 保留天 | ||
| 副本 | 3 | |
| 压缩率 | 0.5 |
Flink
TM 数 ≈ 并行度(常 ≥ Kafka 消费分区数)
单 TM 内存 ≈ 堆 + managed_memory + RocksDB 块缓存
状态磁盘_GB ≈ 状态_GB × (1 + checkpoint 保留份数 × 0.2)
| 变量 | 含义 | 典型 | 敏感度 |
|---|---|---|---|
| 状态_GB | RocksDB 常驻 | 10–500 | CK 间隔↓ → 写放大升 |
| checkpoint 间隔 | 秒 | 60–300 | 过小 → CPU/IO 涨 |
| 并行度 | subtask 数 | = 分区数起 | 过高 → 协调开销 |
| 输入 | 你的值 |
|---|---|
| 并行度 | |
| 状态 GB | |
| checkpoint 间隔 s | |
| sink QPS |
ClickHouse
存储_TB ≈ 原始_TB / 压缩比 × 副本数
查询 CPU ∝ 并发 × 扫描列宽 × parts 数(parts 是隐藏乘子)
| 变量 | 含义 | 敏感度 |
|---|---|---|
| 压缩比 | 列存 3–10× | 存储反比 |
| parts 数 | 小批写劣化 | 查询延迟非线性恶化 |
| 副本 | 2 | 存储 ×2,读扩展 |
| 输入 | 你的值 |
|---|---|
| 年增 TB(压缩后) | |
| 副本 | 2 |
| 峰值 QPS |
批(Airflow + 引擎)
月集群小时 ≈ 日作业数 × 平均时长_h × 30 × 重跑系数(1.05–1.3)
回填季 spike 需单独加 峰值系数 1.5–2。
| 输入 | 你的值 |
|---|---|
| 日分区行数 | |
| 最大 shuffle GB | |
| 月均重跑次数 |
6.2 人力资源¶
| 阶段 | 估算维度 | 典型区间(参考) |
|---|---|---|
| 建设 | 组件数 × 集成复杂度 | 3–12 人月 / 域 |
| 运维 | SLA 等级、on-call | 0.3–1 FTE / 10 组件 |
| 治理 | 口径/质量/安全 | 0.2–0.5 FTE |
Unbundled 运维项清单(on-call 复杂度)
| 组件 | 典型告警 | 技能要求 |
|---|---|---|
| Kafka | lag、URP | 分区、ISR |
| Flink | CK 失败、反压 | savepoint、状态 |
| CH | 慢查、parts | merge、分区 |
| Airflow | SLA miss | DAG 依赖 |
| dbt | test fail | SQL 血缘 |
| 横切 | 对账、口径 | 业务 + L0 |
TCO
TCO ≈ Σ(计算实例) + Σ(存储 GB×单价) + 跨 AZ 流量 + 人力(建设/3年 + 运维×12)
流作业 7×24 常使 Flink+Kafka 计算高于 错峰批;Unbundled 在 灵活 vs 组件数×on-call 上偏灵活侧,需用 §5 runbook 降低人力边际成本。
6.3 容量演练清单¶
- Kafka:峰值生产 2× 持续 1h,lag 可恢复
- Flink:savepoint 升级、单 TM 杀、状态恢复
- CH:并发 10 大查询 + 写入不崩
- 批:最大分区回填与日常并行
- 对账:故意灌 1% 差异,告警与工单流
7. 自信拆解练习¶
过关:90s 口述 症状 → L层 → 组件 → 1 原理 → 1 指标;或书面填六格。
| # | 现象(自测) | 提示层 |
|---|---|---|
| T1 | 实时大屏晚 30 分钟 | L2 lag / L3 watermark |
| T2 | 日批金额比流式少 2% | L0 口径 / scene-reconcile |
| T3 | 单 campaign 消费极慢 | L3 skew |
| T4 | 凌晨 CH 磁盘打满 | L4 merge / L6 容量 |
| T5 | 升级 Flink 后重复数据 | L3 EOS / sink 幂等 |
| T6 | 回填三天 DAG 全红 | L2 Airflow 资源 |
| T7 | 查询偶发 10 分钟 | L4 parts |
| T8 | 新字段上线下游 NPE | L0 契约 / govern |
| T9 | 跨 AZ 切换后双写 | L3 脑裂 |
| T10 | 成本环比 +40% | L7 §6 填数表 |
T1 参考答案
症状:大屏晚 30min → 指标:Kafka lag、Flink watermark 滞后 → L2–L3 Kafka/Flink → 原理:消费慢或 event time 推不动 → 扩并行/查反压/上游断流。→ sym_lag
T2 参考答案
L0 口径 / scene_reconcile → 验证 event time 窗口与批 SQL 一致 → 以批为准修流。→ P06
T3 参考答案
L3 skew → 查单 campaign 分区 lag、Flink subtask busy → 加盐/重分区。→ P05
T4 参考答案
L4 merge + L6 磁盘 → system.parts、merge 队列、磁盘趋势 → OPTIMIZE/TTL。→ P16
T5 参考答案
L3 EOS 与 sink 幂等 → 升级后 delivery 语义变?→ 停作业、查重复键、savepoint 回滚或去重。→ P03
T6 参考答案
L2 Airflow pool / 资源 → 回填并发 vs 日常 → 降并发、错峰。→ P12
T7 参考答案
L4 parts → parts 数、p99、是否剪枝 → merge/杀查询。→ P09
T8 参考答案
L0 契约 / govern → schema 契约测试、dbt test → 阻断发布。→ P02
T9 参考答案
L3 脑裂 / path_meta → 切换后双写、幂等与单主写策略。→ scene_dr
T10 参考答案
L7 §6 → 填 Kafka 保留天、Flink 并行、CH 存储,看哪项环比驱动 TCO。
与出题模板对接 → 知识点出题 · 拆 6 层
使用建议
- 告警 → 只开 §0。
- 评审 → §1 + §2。
- 每周 2 题 §7 口述;细节下钻专题,不背全书。
- 新坑 → QA + 对应专题「待沉淀」。
- 低电量:框架 30 秒 + §0 罗盘 + Part2 三角 + Ch.11 四件套。
8. 节点 ID 表 + 分区简图(与 Canvas 同步)¶
全景展开(树形 + 拓扑)→ 展开图导读。
Canvas 同步:下列id与ddia-master-mindmap.canvas.tsx一致;改节点先改 Markmap 树,再改此表,最后同步 Canvas。
L0 需求层¶
flowchart LR
req_latency[req_latency]
req_throughput[req_throughput]
req_avail[req_avail]
req_consist[req_consist]
req_durability[req_durability]
req_evolve[req_evolve]
req_observ[req_observ]
req_security[req_security]
req_cost[req_cost]
L1 场景层¶
flowchart LR
scene_billing[scene_billing]
scene_realtime[scene_realtime]
scene_reconcile[scene_reconcile]
scene_cdc[scene_cdc]
scene_attribution[scene_attribution]
scene_scd[scene_scd]
scene_backfill[scene_backfill]
scene_dr[scene_dr]
L2 组件层¶
flowchart LR
comp_kafka[comp_kafka]
comp_flink[comp_flink]
comp_ch[comp_ch]
comp_dbt[comp_dbt]
comp_airflow[comp_airflow]
comp_pg[comp_pg]
govern[govern]
L3–L6 纵轴(概念)¶
flowchart TB
L3[L3_runtime]
L4[L4_storage]
L5[L5_os_mem]
L6[L6_hw_net]
L3 --> L4 --> L5 --> L6
path_stream[path_stream]
path_batch[path_batch]
path_query[path_query]
path_meta[path_meta]
L3 --> path_stream
L3 --> path_batch
L3 --> path_query
L3 --> path_meta
L7 实践 + 症状¶
flowchart LR
sym_lag[sym_lag]
sym_dup[sym_dup]
sym_loss[sym_loss]
sym_skew[sym_skew]
sym_oom[sym_oom]
sym_reconcile[sym_reconcile]
sym_stale[sym_stale]
sym_slowq[sym_slowq]
ops_monitor[ops_monitor]
ops_incident[ops_incident]
ops_capacity[ops_capacity]
ops_cost[ops_cost]
节点 ID 主表(Canvas JSON 源)¶
| id | layer | label | mdAnchor | 百科 |
|---|---|---|---|---|
| req_latency | L0 | 延迟 | #req_latency | A |
| req_throughput | L0 | 吞吐 | #req_throughput | A |
| req_avail | L0 | 可用性 | #req_avail | A |
| req_consist | L0 | 一致性 | #req_consist | A |
| req_durability | L0 | 持久性 | #req_durability | A |
| req_evolve | L0 | 可演进 | #req_evolve | A |
| req_observ | L0 | 可观测 | #req_observ | A |
| req_security | L0 | 安全合规 | #req_security | A |
| req_cost | L0 | 人月成本 | #req_cost | A |
| scene_billing | L1 | 计费T+1 | #scene-billing | A |
| scene_realtime | L1 | 实时大屏 | #scene-realtime | A |
| scene_reconcile | L1 | 流批对账 | #scene-reconcile | A |
| scene_cdc | L1 | CDC入仓 | #scene-cdc | A |
| scene_attribution | L1 | 归因窗口 | #scene-attribution | A |
| scene_scd | L1 | 维表SCD | #scene-scd | A |
| scene_backfill | L1 | 历史回填 | #scene-backfill | A |
| scene_dr | L1 | 灾备 | #scene-dr | A |
| comp_kafka | L2 | Kafka | #comp_kafka | A |
| comp_flink | L2 | Flink | #comp_flink | A |
| comp_ch | L2 | ClickHouse | #comp_ch | A |
| comp_dbt | L2 | dbt | #comp_dbt | A |
| comp_airflow | L2 | Airflow | #comp_airflow | A |
| comp_pg | L2 | PG | #comp_pg | A |
| govern | L2 | 治理 | #govern | A |
| path_stream | L3 | 流路径 | #path-stream | A |
| path_batch | L3 | 批路径 | #path-batch | A |
| path_query | L3 | 查询路径 | #path-query | A |
| path_meta | L3 | 元数据路径 | #path-meta | A |
| L3_runtime | L3 | 运行时 | §4 | A |
| L4_storage | L4 | 存储引擎 | #l4l6-存储栈共享下钻 | A |
| L5_os_mem | L5 | OS与内存 | #l5_os_mem | A |
| L6_hw_net | L6 | 硬件网络 | #l6_hw_net | A |
| sym_lag | L7 | 延迟高 | #sym_lag-端到端延迟高 | A |
| sym_dup | L7 | 重复 | #sym_dup-数据重复 | A |
| sym_loss | L7 | 丢失 | #sym_loss-数据丢失--偏少 | A |
| sym_skew | L7 | 倾斜 | #sym_skew-倾斜热点 | A |
| sym_oom | L7 | OOM | #sym_oom-oom--gc-抖 | A |
| sym_reconcile | L7 | 对账不平 | #sym_reconcile-对账不平 | A |
| sym_stale | L7 | 不新鲜 | #sym_stale-数据不新鲜 | A |
| sym_slowq | L7 | 查询慢 | #sym_slowq-查询突然变慢 | A |
| ops_monitor | L7 | 监控 | #ops_monitor | A |
| ops_incident | L7 | 应急 | #ops_incident | A |
| ops_capacity | L7 | 容量 | #63-容量演练清单 | A |
| ops_cost | L7 | 成本 | §6 | A |
症状 → 高亮节点路径(Canvas)
| symptomId | highlightNodes |
|---|---|
| sym_lag | comp_kafka, comp_flink, path_stream, sym_lag |
| sym_dup | comp_flink, path_stream, path_meta, sym_dup |
| sym_skew | comp_kafka, comp_flink, path_stream, sym_skew |
| sym_reconcile | scene_reconcile, comp_dbt, comp_ch, sym_reconcile |
| sym_oom | comp_flink, L4_storage, L5_os_mem, sym_oom |
| sym_slowq | comp_ch, path_query, sym_slowq |
附录 A · 节点百科¶
速查卡:是什么 · 为何 · 机制 · 坑 · 指标 · 深读。场景/路径正文见 §2–§4。
L0 需求¶
req_latency
是什么:端到端可见延迟。为何:业务 SLA 首要感知。机制:批=调度+计算;流=lag+水印。坑:用 processing time 当业务时间。指标:p99 延迟、新鲜度。深读:§1 req_latency
req_throughput
是什么:单位时间处理量。为何:数据增长直接驱动集群规模。机制:分区水平扩展。坑:只扩 Kafka 不扩消费。指标:日增 GB、峰值 eps。深读:§1
req_avail
是什么:故障下仍服务。为何:广告计费不能长期全停。机制:副本+无单点+savepoint。坑:把异步复制当同步。指标:年可用率、MTTR。深读:§1 · Part2 Ch.5
req_consist
是什么:读到的与真相偏差。为何:数仓多为最终一致。机制:EOS、幂等、批权威。坑:无权威源双写。指标:对账差异率。深读:§1 · scene_reconcile
req_durability
是什么:故障不丢已承认数据。为何:RPO 合同。机制:ISR、WAL、checkpoint。坑:CK 失败仍提交 offset。指标:RPO 实测、CK 成功率。深读:§1 · path_meta
req_evolve
是什么:schema/逻辑可演进。为何:业务字段频繁变。机制:契约、dbt version。坑:破坏性变更一次上线。指标:契约测试通过率。深读:§1 · govern
req_observ
是什么:可定位层与组件。为何:否则 on-call 盲飞。机制:指标+血缘+对账。坑:告警与 §0 症状不对应。指标:lag、CK、parts、对账率。深读:§0 · ops_monitor
req_security
是什么:权限审计脱敏。为何:合规。机制:列级权限、审计日志。坑:宽表全员可读。指标:异常访问次数。深读:P14
req_cost
是什么:TCO 含人力。为何:Unbundled 组件多。机制:§6 填数+错峰。坑:只算机器不算 on-call。指标:月云账单、FTE。深读:§6
L1 场景¶
scene_billing
是什么:T+1 计费闭合。为何:财务要不可变日分区。机制:Airflow→dbt→CH。坑:重跑不幂等。指标:分区产出时间、行数环比。深读:scene-billing
scene_realtime
是什么:分钟级大屏/风控。为何:运营要快反馈。机制:Kafka→Flink→CH。坑:把流当关账。指标:lag、p99。深读:scene-realtime
scene_reconcile
是什么:流批一致。为何:Lambda 双路径必对账。机制:日批权威+差异 SQL。坑:两套 SQL。指标:差异率。深读:scene-reconcile
scene_cdc
是什么:OLTP 入仓。为何:明细近实时。机制:binlog→Kafka。坑:全增量切换。指标:CDC lag。深读:scene-cdc
scene_attribution
是什么:转化归因窗口。为何:点击与成交乱序。机制:event time+Watermark+批补。坑:processing 窗口。指标:窗口闭合延迟。深读:scene-attribution
scene_scd
是什么:维表历史版本。为何:报表要 as-of。机制:dbt snapshot。坑:全量重算事实。指标:快照行数。深读:scene-scd
scene_backfill
是什么:历史分区重跑。为何:逻辑纠错。机制:有界 dt+pool。坑:与日常抢资源。指标:回填并发、集群 CPU。深读:scene-backfill
scene_dr
是什么:灾备多活。为何:RPO/RTO。机制:异步复制+演练。坑:切换双写。指标:复制延迟。深读:scene-dr
L2 组件¶
comp_kafka
是什么:分布式 commit log。为何:解耦与重放。机制:分区+offset。坑:当数据库。指标:lag、URP。深读:comp_kafka 卡片
comp_flink
是什么:流状态计算引擎。为何:秒级聚合。机制:CK+Watermark。坑:状态无 TTL。指标:CK 时长、反压。深读:comp_flink 卡片
comp_ch
是什么:列存 OLAP。为何:ADS 扫描。机制:MergeTree part。坑:小批写。指标:parts、p99。深读:comp_ch 卡片
comp_dbt
是什么:SQL 建模工具。为何:血缘与测试。机制:ref/incremental。坑:无分区过滤。指标:test fail。深读:comp_dbt 卡片
comp_airflow
是什么:工作流调度。为何:T+1 依赖。机制:DAG+pool。坑:深度依赖连锁。指标:SLA miss。深读:comp_airflow 卡片
comp_pg
是什么:事务源库。为何:业务真相。机制:ACID+CDC。坑:当分析库。指标:复制延迟。深读:Part2 Ch.7
govern
是什么:质量血缘权限。为何:口径与安全。机制:契约+dbt test+列权限。坑:治理与开发脱节。指标:对账/审计。深读:govern
L3–L6 路径与资源¶
path_stream
是什么:无界流运行时路径。为何:实时场景。机制:offset→状态→CK→sink。坑:非幂等 sink。指标:lag、CK。深读:path-stream
path_batch
是什么:有界批路径。为何:权威报表。机制:split→shuffle→幂等写。坑:skew。指标:stage 时长。深读:path-batch
path_query
是什么:只读分析路径。为何:查询 ADS。机制:剪枝→读 part。坑:parts 多。指标:query p99。深读:path-query
path_meta
是什么:协调元数据路径。为何:进度与领导。机制:ZK/KRaft/JM。坑:会话超时抖动。指标:选举次数。深读:path-meta
L3_runtime
是什么:分布式运行时层概念。为何:统一四条 path。机制:流/批/查/元数据。坑:混谈批与流语义。指标:按 path 分项。深读:§4
L4_storage
是什么:存储引擎层。为何:持久化形态决定 IO。机制:B+/LSM/列存。坑:引擎错配负载。指标:IO、parts、compaction。深读:L4 对比表
L5_os_mem
是什么:OS 与进程内存。为何:buffer pool/cache 决定读成本。机制:页缓存、mmap、堆。坑:内存未限额查询。指标:RSS、GC。深读:§4 各路径资源段
L6_hw_net
是什么:磁盘与网络物理层。为何:顺序写 vs 随机读、跨 AZ 费。机制:NVMe、带宽、副本复制。坑:忽视跨 AZ 流量费。指标:磁盘利用率、网络 MBps。深读:§6
L7 实践¶
sym_lag
是什么:端到端晚。机制:消费/水印/sink。指标:records-lag-max。深读:sym_lag
sym_dup
是什么:重复计数。机制:至少一次。指标:幂等键重复率。深读:sym_dup
sym_loss
是什么:数据偏少。机制:副本/CK/漏分区。指标:ISR、行数环比。深读:sym_loss
sym_skew
是什么:热点倾斜。机制:key 分布。指标:分区 lag 方差。深读:sym_skew
sym_oom
是什么:内存超限。机制:状态/查询。指标:state GB。深读:sym_oom
sym_reconcile
是什么:对账超阈。机制:双口径。指标:差异率。深读:sym_reconcile
sym_stale
是什么:数据旧。机制:调度/CDC。指标:最后成功 dt。深读:sym_stale
sym_slowq
是什么:查询慢。机制:parts/merge。指标:p99、parts 数。深读:sym_slowq
ops_monitor
是什么:可观测运维。机制:指标+对账看板。坑:告警噪音无 runbook。指标:覆盖率。深读:§5 日常节奏
ops_incident
是什么:应急与复盘。机制:§0→§5→写回 QA。坑:无事故文档。深读:P15
ops_capacity
是什么:容量与演练。机制:§6 填数+季 drill。坑:从未压测峰值。深读:§6.3
ops_cost
是什么:TCO 治理。机制:季度复盘组件账单。坑:只优化存储不算人力。深读:§6.2
QA 疑问解答¶
Q1:本书体例与旧版「顶层索引」有何区别?
A1:正文 §1–§6 为干货主体;Markmap/拓扑为目录与链路;附录 A 为节点速查。旧版以提纲为主,现要求不查外链也能读场景契约与路径机制。
Q2:权威源为什么必须是日批?
A2:计费要可重跑、可审计、可闭合自然日;流受乱序与近似窗口影响,适合监控不适合关账。见 scene_billing 与 scene_reconcile。
Q3:event time 与 processing time 如何选?
A3:业务归因、对账、窗口聚合用 event time;算子健康度、系统延迟用 processing time。混用导致 P01。
Q4:parts 爆炸与 lag 暴涨先修谁?
A4:若写入仍持续,先限 Flink sink 批量(P17)再 merge;若只读慢,先查 parts(P16)。
Q5:Unbundled 和 Lakehouse 能否并存?
A5:可以;湖表作长期存储、CH 作热 ADS 是常见折中。见 §2 Lakehouse 决策段。
Q6:附录 A 与 §2 场景正文重复吗?
A6:附录是 150–250 字速查卡;§2 是 200–350 字场景全书(契约、运维节奏)。设计评审读 §2,on-call 开附录 A + §0。
Q7:Canvas 与 Markmap 以谁为准?
A7:维护顺序:Markmap → §8 → 附录 A → Canvas;语义以正文 §2–§4 为准。
Q9:#path-stream 跳不过去?
A9:确认 zero.site/mkdocs.yml 已启用 attr_list;标题使用 {#path-stream} 显式锚点。旧缓存会导致仍跳到错误位置,请硬刷新。节点 id path_stream 也可用 #path_stream(文内 <span> 别名)。
Q8:为何不展开 Raft 证明?
A8:卷一面向架构与排障;共识 只需理解 leader/多数派/会话超时 与症状关系,证明见 Part2 Ch.9 专题。
待沉淀¶
- 各场景 SLA 填数实例(计费域真实数字代入 §6)
- 云厂商单价表代入 §6 生成 TCO 电子表
- Part2/Ch 专题修订时同步检查「内联干货」是否 drift