2. 数据采集与存储:数据源类型、采集策略与存储格式
做数据回放,第一步就是搞定数据从哪里来、怎么拿、存成什么样。这三个问题没想清楚,后面回放的时候全是坑。我这些年踩过的雷,十有八九都跟数据源和存储格式有关。
2.1 数据源类型:传感器、日志、数据库
数据回放的数据源,说白了就三大类。每一类脾气都不一样,得区别对待。
传感器数据
传感器数据是物联网场景的主力。温度、湿度、振动、电流……这些信号通常以高频时序数据的形式出现。我个人习惯把传感器数据分成两类:
- 周期性采样数据:比如每100ms采集一次温度值,数据量稳定,结构简单
- 事件触发数据:比如振动超过阈值才记录,数据稀疏但价值高
我在项目中遇到过一个问题:某工厂的振动传感器每秒采集1000次,一天下来就是8600万条记录。如果全量存储,存储成本直接爆炸。后来我们做了个策略——只保留超过阈值的波形片段,其他时间只存统计特征。嗯,这个思路后来成了我们团队的标配。
日志数据
日志数据是最常见的回放数据源。应用日志、系统日志、安全日志……格式五花八门。你想想看,一个微服务架构的系统,每天产生的日志量可能上TB。
日志数据有个特点:半结构化。时间戳、日志级别、消息体,这些字段基本都有,但消息体里的内容千奇百怪。我建议在采集阶段就做一次结构化解析,把关键字段提取出来,否则回放的时候你会疯掉。
数据库数据
数据库作为数据源,通常用于回放历史业务状态。比如订单状态变更、用户行为轨迹等。这里要注意的是:
- 全量快照:某个时间点的完整数据状态,适合做基准回放
- 增量变更:通过CDC(Change Data Capture)捕获的变更日志,适合做连续回放
我个人更推荐增量方式。全量快照虽然简单,但数据量大了以后,每次回放都要加载几TB数据,效率太低了。
2.2 数据采集策略
采集策略决定了数据回放的完整性和实时性。我总结了三类常用策略:
| 策略类型 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| 全量采集 | 数据量小、需要完整历史 | 数据完整,回放无遗漏 | 存储成本高,采集时间长 |
| 增量采集 | 数据量大、关注变化 | 存储效率高,实时性好 | 需要维护状态,回放需合并 |
| 采样采集 | 高频数据、趋势分析 | 大幅降低数据量 | 丢失细节,不适合精确回放 |
实际项目中,我通常采用分层采集策略:
- 边缘层:在数据源附近做初步过滤和聚合,减少传输量
- 传输层:使用消息队列(如Kafka)缓冲数据,防止丢失
- 存储层:根据数据特征选择不同的存储格式
2.3 数据存储格式:Parquet、Avro、CSV
存储格式的选择,直接影响回放性能。我见过太多团队用CSV存所有数据,结果回放时慢到怀疑人生。来,我们逐个分析。
CSV
CSV是最简单的格式,人类可读,任何工具都能打开。但它的缺点也很明显:
- 无压缩:同样的数据,CSV体积通常是Parquet的3-5倍
- 无Schema:字段类型全靠猜,回放时容易解析错误
- 不支持嵌套:复杂数据结构只能拍平,丢失语义
我建议:CSV只用于小数据量的调试场景。生产环境?别想了。
Avro
Avro是行式存储格式,特点是Schema内嵌。每个文件都带着自己的数据结构定义,解析时不需要外部Schema文件。这在数据回放中特别有用——你永远不用担心Schema版本不匹配的问题。
Avro的压缩率也不错,而且支持多种编程语言。我在做实时数据回放时,经常用Avro作为Kafka消息的序列化格式。
// Avro Schema示例
{
"type": "record",
"name": "SensorReading",
"fields": [
{"name": "device_id", "type": "string"},
{"name": "timestamp", "type": "long"},
{"name": "temperature", "type": "float"},
{"name": "humidity", "type": "float"}
]
}
Parquet
Parquet是列式存储格式,也是我最推荐的回放存储格式。为什么?
- 列式压缩:相同类型的数据放在一起,压缩率极高
- 谓词下推:回放时只读取需要的列,IO量大幅减少
- 支持复杂嵌套:原生支持JSON-like数据结构
举个例子:假设你有100列数据,但回放只需要时间戳和温度两列。用Parquet,你只需要读取这两列的数据;用CSV,你得把100列全读进来再过滤。速度差距可能是100倍。
2.4 知识体系总览
下面这张图,是我对数据采集与存储整个环节的理解。你可以把它当作一个快速参考。
这张图把三个核心环节串起来了。从上到下,数据源决定了采集策略,采集策略又影响存储格式的选择。三者环环相扣,缺一不可。
好了,这一章的内容就到这里。数据采集与存储是数据回放的基石,花时间把这块搞扎实了,后面的回放逻辑才能跑得顺畅。