数据密集型软件
Data-Intensive Applications
当数据量大到单机装不下,存储引擎、复制、分区成为核心问题。
数据密集型应用是系统的大部分功能都与数据相关的应用——数据量、数据复杂度、数据变化速度是主要挑战。核心子系统包括:存储引擎(B+树 vs LSM-Tree,OLTP vs OLAP)、复制(单主/多主/无主,同步/异步)、分区(按范围/哈希/二级索引)、事务(ACID、隔离级别、MVCC)、一致性模型(线性一致、顺序一致、因果一致、最终一致)。典型组件:关系数据库(PostgreSQL、MySQL)、NoSQL(Redis、MongoDB、Cassandra)、消息队列(Kafka、RabbitMQ)、搜索引擎(Elasticsearch)、缓存(Memcached、Redis)。
单机存储和计算能力有限。当数据量超过单机内存/磁盘容量,或 QPS 超过单机处理能力时,必须将数据分布到多台机器。这引入了新问题:数据如何在节点间复制?如何保证一致性?如何处理节点故障?如何跨节点查询?存储引擎的选择(B+树适合读多写少,LSM-Tree 适合写多读少)直接影响系统性能。一致性模型的选择(强一致 vs 最终一致)影响系统的可用性和延迟。
程序员通过数据库驱动/客户端库与存储系统交互。SQL 用于关系数据库,REST/gRPC 用于 NoSQL。理解数据密集型系统有助于理解:为什么选择 PostgreSQL 而不是 MongoDB(数据模型决定);为什么缓存层能提升性能(减少数据库压力);为什么消息队列解耦服务(异步通信);为什么分布式事务如此复杂(跨节点一致性)。Martin Kleppmann 的《DDIA》是该领域的经典参考。
Bottom-up:由下层如何构建
本层建立在以下层级之上:
Top-down:向上暴露什么接口
Programmer View:程序员视角
我能操作吗?
通过数据库驱动(JDBC、pg、redis-py)和客户端库直接操作。SQL/NoSQL API 提供数据访问接口。连接池管理并发连接。
成本模型
| 指标 | 量级 | 备注 |
|---|---|---|
| 关系数据库查询 | ~0.1-10 ms | 取决于索引和查询复杂度 |
| Redis 读写 | ~0.1-0.5 ms | 内存数据库,亚毫秒级 |
| Kafka 写入 | ~1-10 ms | 顺序写入磁盘,高吞吐 |
| 全文搜索 | ~10-100 ms | 倒排索引,取决于数据量 |
| 跨数据中心复制 | ~50-200 ms | 受网络延迟约束 |
常见陷阱
- !缓存与数据库一致性:缓存更新策略(Cache-Aside / Write-Through / Write-Behind)各有取舍,缓存穿透/雪崩/击穿是常见问题
- !分布式事务代价高:两阶段提交(2PC)阻塞且单点故障,跨服务应尽量使用最终一致性(Saga 模式)替代强一致事务
- !N+1 查询问题:ORM 延迟加载导致循环中逐条查询数据库,应使用 JOIN 或批量查询(Eager Loading)