目录
- [1. DDIA 学什么?](#1. DDIA 学什么?)
- [2. 从单机程序到系统](#2. 从单机程序到系统)
- [3. Reliability:可靠性](#3. Reliability:可靠性)
- [4. Scalability:可扩展性](#4. Scalability:可扩展性)
- [5. Maintainability:可维护性](#5. Maintainability:可维护性)
- [6. Data Model:数据模型](#6. Data Model:数据模型)
- [7. Storage:存储](#7. Storage:存储)
- [8. Index:索引](#8. Index:索引)
- [9. Transaction:事务](#9. Transaction:事务)
- [10. Consistency:一致性](#10. Consistency:一致性)
- [11. Replication:复制](#11. Replication:复制)
- [12. Partitioning:分区](#12. Partitioning:分区)
- [13. Message Systems:消息系统](#13. Message Systems:消息系统)
- [14. ZMQ 应该如何理解?](#14. ZMQ 应该如何理解?)
- [15. Batch Processing:批处理](#15. Batch Processing:批处理)
- [16. Stream Processing:流处理](#16. Stream Processing:流处理)
- [17. Latency vs Throughput](#17. Latency vs Throughput)
- [18. Fault Tolerance:故障容忍](#18. Fault Tolerance:故障容忍)
- [19. Idempotency:幂等性](#19. Idempotency:幂等性)
- [20. Observability:可观测性](#20. Observability:可观测性)
- [21. AI Coding 与 DDIA](#21. AI Coding 与 DDIA)
- [22. GIS 场景中的系统设计训练](#22. GIS 场景中的系统设计训练)
- [23. 本阶段最终能力](#23. 本阶段最终能力)
- [24. 五阶段最终能力地图](#24. 五阶段最终能力地图)
第五阶段学习目标:从软件工程、代码设计、应用架构进一步进入系统设计。
核心问题:
当一个程序变成一个真正的系统,面对大量数据、多个进程、多个服务和大量用户时,应该如何设计?
1. DDIA 学什么?
DDIA 不是简单的:
"数据库教程。"
它真正讨论的是:
数据密集型系统如何可靠地存储、处理、传输和组织数据。
主要涉及:
text
数据模型
存储
数据库
事务
复制
分区
一致性
消息系统
批处理
流处理
分布式系统
可靠性
可扩展性
2. 从单机程序到系统
前面的学习大致解决:
text
一个程序
↓
模块
↓
架构
DDIA 开始解决:
text
多个进程
↓
多个服务
↓
多个机器
↓
大量数据
↓
分布式系统
3. Reliability:可靠性
系统不能只考虑:
text
正常情况
还必须考虑:
text
磁盘坏了
网络断了
服务崩了
消息丢了
数据库异常
进程重启
请求重复
数据损坏
因此系统设计需要:
- 重试
- 超时
- 故障恢复
- 持久化
- 日志
- 监控
- 数据校验
4. Scalability:可扩展性
需要区分:
功能扩展
和:
系统规模扩展。
例如:
text
100 个模型
↓
10000 个模型
↓
1000000 个模型
原来的方案可能无法继续工作。
需要考虑:
- 数据库
- 缓存
- 索引
- 分片
- 并行处理
- 异步任务
5. Maintainability:可维护性
DDIA 很重要的一点是:
系统不仅需要运行,还要能够被持续修改。
这与前面的:
text
Software Construction
Refactoring
Architecture
形成完整链条:
text
代码可维护
↓
模块可维护
↓
架构可维护
↓
系统可维护
6. Data Model:数据模型
系统设计的基础之一:
数据应该如何表示?
例如 GIS:
text
Project
├── Layer
│ ├── Raster
│ ├── Vector
│ └── Model
└── AnalysisTask
数据模型决定:
- 如何查询
- 如何保存
- 如何关联
- 如何更新
- 如何扩展
7. Storage:存储
不同数据适合不同存储方式。
例如:
text
配置
↓
JSON / SQLite
空间数据
↓
Spatial Database / File
大文件
↓
Object Storage
缓存
↓
Redis / Memory
消息
↓
Message Queue
核心不是背工具。
而是理解:
数据的访问模式决定存储方案。
8. Index:索引
如果每次查询都:
text
遍历全部数据
数据量大时会越来越慢。
索引本质是:
用额外空间换取更快查询。
GIS 中尤其重要:
- 空间索引
- R-tree
- Tile Index
- 时间索引
- 属性索引
9. Transaction:事务
事务解决:
多个操作需要保持一致。
例如:
text
创建项目
↓
写项目记录
↓
写图层记录
↓
写配置
如果中间失败:
text
项目存在
但图层不存在
系统就可能处于不一致状态。
事务可以帮助建立:
全部成功,或者全部失败。
10. Consistency:一致性
分布式系统里:
text
服务 A
↓
服务 B
↓
服务 C
数据可能在不同地方存在副本。
需要考虑:
修改之后,其他地方什么时候能看到?
这就是一致性问题。
11. Replication:复制
为了:
- 高可用
- 容灾
- 读性能
可能需要:
text
Primary
├── Replica
├── Replica
└── Replica
但复制带来新的问题:
多个副本什么时候保持一致?
12. Partitioning:分区
数据越来越大:
text
单机数据库
↓
无法继续扩展
可以按:
text
用户
地区
时间
空间
进行分区。
GIS 数据天然非常适合思考空间分区:
text
全国
↓
省
↓
市
↓
瓦片
13. Message Systems:消息系统
这是你以后学习 ZMQ 时非常重要的基础。
传统:
text
A
↓
直接调用
↓
B
消息模式:
text
A
↓
Message
↓
B
这样可以进一步实现:
- 异步
- 解耦
- 缓冲
- 重试
- 多消费者
- 任务队列
14. ZMQ 应该如何理解?
不要只学习:
text
REQ
REP
PUB
SUB
PUSH
PULL
更重要的是理解:
为什么需要消息通信?
例如:
text
Electron
↓
发送分析任务
↓
ZMQ
↓
Python / AI 服务
↓
执行
↓
返回结果
这里真正需要思考:
text
任务是否可靠?
服务崩溃怎么办?
请求超时怎么办?
重复任务怎么办?
任务取消怎么办?
结果丢失怎么办?
这才是系统设计能力。
15. Batch Processing:批处理
例如:
text
10000 景遥感影像
↓
统一处理
↓
生成结果
不应该让用户一直等待:
text
一个请求
↓
处理 3 小时
↓
HTTP 一直不返回
可以变成:
text
创建任务
↓
进入队列
↓
后台处理
↓
记录进度
↓
完成
↓
通知用户
16. Stream Processing:流处理
数据不是一次性处理完,而是:
text
数据不断产生
↓
不断处理
↓
不断输出
例如:
- 实时传感器
- 实时遥感数据
- 日志
- AI 推理流
- 实时 GIS 数据
这时候系统需要考虑:
- 延迟
- 吞吐
- 顺序
- 背压
- 容错
17. Latency vs Throughput
两个非常重要的系统指标:
Latency
一次操作需要多久。
text
请求 → 响应
100ms
Throughput
单位时间能够处理多少任务。
text
10000 tasks / hour
有时候:
更低延迟
和:
更高吞吐
并不是同一个优化方向。
18. Fault Tolerance:故障容忍
系统设计时应该假设:
故障一定会发生。
例如:
text
Python 服务崩溃
↓
Electron 是否卡死?
好的设计:
text
Electron
↓
任务系统
↓
Python
Python 挂掉以后:
text
任务失败
↓
记录状态
↓
允许重试
↓
Electron 仍然可以运行
19. Idempotency:幂等性
分布式系统中经常发生:
text
请求发送
↓
服务已经执行
↓
响应丢失
↓
客户端重试
于是任务可能执行两次。
因此某些操作应该设计成幂等:
text
执行两次
=
执行一次的最终结果
例如:
text
创建任务
可以使用:
text
requestId
防止重复创建。
20. Observability:可观测性
大型系统不能只靠:
text
console.log()
应该逐渐建立:
text
Logs
Metrics
Tracing
也就是:
Logs
发生了什么?
Metrics
系统现在怎么样?
Tracing
一个请求经过了哪些模块?
例如:
text
Electron
↓
ZMQ
↓
Python
↓
AI
↓
Database
如果任务失败,需要知道:
到底在哪一层失败。
21. AI Coding 与 DDIA
以后让 AI 帮你设计系统时,不要只问:
text
"帮我设计一个 ZMQ 架构。"
应该问:
text
请从系统设计角度分析这个方案:
1. 数据流
2. 通信方式
3. 状态管理
4. 超时
5. 重试
6. 幂等性
7. 故障恢复
8. 并发
9. 扩展性
10. 可观测性
这样 AI 才会真正参与系统设计。
22. GIS 场景中的系统设计训练
例如:
text
用户上传 10000 张遥感影像
↓
任务服务
↓
消息队列
↓
计算节点
↓
AI / 遥感算法
↓
结果存储
↓
GIS 可视化
这时已经不是简单的:
"写一个函数。"
而是:
text
数据
↓
任务
↓
消息
↓
计算
↓
存储
↓
结果
需要思考:
- 数据在哪里?
- 谁负责?
- 怎么传?
- 失败怎么办?
- 如何重试?
- 如何扩容?
- 如何监控?
这就是系统设计。
23. 本阶段最终能力
能够面对一个系统时思考:
text
数据从哪里来?
↓
存在哪里?
↓
谁处理?
↓
怎么通信?
↓
失败怎么办?
↓
数据如何保持一致?
↓
规模扩大怎么办?
↓
如何监控?
↓
如何扩展?
最终从:
"会写一个程序"
进入:
"会设计一个系统"。
24. 五阶段最终能力地图
text
MIT Software Construction
↓
可靠、可维护的代码
↓
Refactoring
↓
持续改善代码结构
↓
Design Patterns
↓
解决重复的软件设计问题
↓
Clean Architecture
↓
建立系统边界、控制依赖
↓
DDIA
↓
设计数据密集型、分布式系统
最终形成:
text
写代码
↓
构建软件
↓
设计软件
↓
设计架构
↓
设计系统
而 AI 则贯穿整个过程:
text
AI
├── 代码生成
├── 测试
├── Debug
├── Review
├── 重构
├── 架构分析
└── 系统设计辅助
真正应该提升的是:
你的判断力、设计能力和工程能力。