3. 存储介质选型:SSD vs HDD、内存数据库、对象存储的适用场景
存储选型这事儿,我做了十几年架构,踩过的坑比走过的路还多。Tick级数据有个特点——写入量巨大,但单个数据点很小。这就对存储介质提出了很刁钻的要求。今天咱们就掰开揉碎了聊聊,SSD、HDD、内存数据库、对象存储,到底该怎么选。
3.1 SSD vs HDD:延迟与吞吐的博弈
先说结论:Tick级数据的主存储,别碰HDD。这不是我偏见,是血的教训。
我曾经在一个期货交易系统里,为了省成本,用了SAS HDD做历史Tick存储。结果呢?回放数据时,磁盘寻道时间占了总延迟的70%。你想想看,Tick数据每秒可能产生几万条,HDD的随机IOPS撑死了也就200-300。根本扛不住。
核心差异点:
- 随机写入性能:SSD比HDD快2-3个数量级。Tick数据写入是典型的随机小IO,HDD的机械臂根本忙不过来。
- 延迟稳定性:SSD的P99延迟通常在1ms以内,HDD受碎片化影响,延迟抖动可能达到几十毫秒。
- 并发能力:SSD支持几十甚至上百的并发队列深度,HDD单线程串行处理。
但HDD真的一无是处吗?也不是。我个人的习惯是:冷数据归档用HDD。比如超过30天的Tick数据,压缩后丢到HDD上,成本只有SSD的1/5。关键是,你得做好分层策略。
| 维度 | SSD (NVMe) | HDD (SAS/SATA) |
|---|---|---|
| 随机IOPS | 500K - 1M | 100 - 300 |
| 延迟(P99) | < 0.5ms | 5 - 15ms |
| 写入寿命 | 有限(需关注DWPD) | 几乎无限 |
| 每GB成本 | 高 | 低 |
| 适用场景 | 热数据、实时写入 | 冷数据、大文件归档 |
避坑指南:我曾经在一个项目里,给SSD配了RAID5。结果连续写入3个月后,SSD集体写穿。为什么?RAID5的写放大效应太严重了。Tick数据这种高频写入场景,建议用RAID10或者直接单盘+副本策略。
3.2 内存数据库:Redis vs InfluxDB
内存数据库,说白了就是拿DRAM当存储。延迟能压到微秒级。但这里有个误区——很多人以为内存数据库就是快,其实它最大的价值是数据结构化处理。
Redis:适合做缓存层和实时计算
Redis我用的最多的是做实时聚合。比如计算过去1秒内的最高价、最低价、成交量。用Redis的Sorted Set或者Stream,配合Lua脚本,延迟能控制在50微秒以内。
但Redis有个硬伤——持久化能力弱。RDB和AOF在Tick级写入下,性能衰减很厉害。我建议:Redis只做热数据缓存,不做主存储。数据最终要落到SSD上。
// 伪代码:Redis实时聚合示例
// 每秒更新一次Tick数据的聚合结果
MULTI
ZADD tick:price:1s {timestamp} {price}
ZREMRANGEBYSCORE tick:price:1s -inf {timestamp - 1s}
ZREVRANGE tick:price:1s 0 0 WITHSCORES // 获取最高价
EXEC
InfluxDB:时序数据库的优等生
InfluxDB天生为时序数据设计。它的TSM存储引擎,对Tick数据做了大量优化。我实测过,单机每秒能写入50万点,而且压缩比能达到10:1。
但要注意:InfluxDB的集群版是收费的。开源版只能单机部署,高可用需要自己搭。我个人的经验是:中小规模用InfluxDB单机+冷备,大规模用ClickHouse。
我的建议:如果Tick数据量在每天10亿点以内,InfluxDB单机完全够用。超过这个量,考虑用Kafka+ClickHouse的架构。别问我怎么知道的——我有个项目,InfluxDB单机撑到每天50亿点,最后查询延迟从10ms飙升到2秒。
3.3 对象存储:S3/MinIO的降维打击
对象存储,很多人觉得它慢,不适合Tick数据。其实这是个误解。对象存储的吞吐能力极强,特别适合批量读写。
我设计过一个方案:Tick数据先写到SSD本地,然后异步上传到MinIO。本地SSD只保留最近7天的数据,历史数据全丢到对象存储里。查询时,先查本地,没命中再查MinIO。
为什么这么做?因为对象存储的延迟虽然高(10-50ms),但它的带宽可以线性扩展。你想想看,1000个并发请求同时读MinIO,只要网络带宽够,延迟几乎不变。而SSD的并发能力是有上限的。
| 特性 | S3 (AWS) | MinIO (自建) |
|---|---|---|
| 延迟 | 10-30ms | 5-15ms (内网) |
| 吞吐 | 无限扩展 | 受限于硬件 |
| 成本 | 按量付费 | 一次性硬件投入 |
| 适用场景 | 云原生、弹性伸缩 | 私有化部署、合规要求 |
核心逻辑:对象存储不适合做实时写入,但非常适合做冷热分层中的冷层。我习惯把超过7天的Tick数据,按小时打包成Parquet文件,压缩后上传到MinIO。查询时用Presto或Spark直接读,性能比从SSD上读原始数据还快。
3.4 存储分层架构总览
说了这么多,其实就一个核心思想:没有银弹,只有分层。我画了一张图,把整个存储体系串起来。
这张图我用了很多年。核心就是:热数据在内存,温数据在SSD,冷数据在对象存储,归档数据在HDD。每一层之间通过异步任务做数据迁移,保证实时写入不受影响。
一个小技巧:我习惯在SSD层和对象存储层之间加一个缓冲队列(比如Kafka)。这样即使对象存储挂了,数据也不会丢。SSD上的数据可以保留7天,足够你修复故障了。
嗯,存储选型这事儿,说到底就是成本、性能、容量的三角博弈。没有完美的方案,只有最适合你业务场景的方案。我见过有人用全内存方案,每天成本烧掉几万块;也见过有人全用HDD,查询慢到被用户骂。找到那个平衡点,才是架构师的本事。