存储系统选型最容易犯的错,是一上来就问:“Redis、HBase、ClickHouse、Doris、Hudi、Elasticsearch,到底哪个性能最好?”
这个问题其实没有答案。因为存储系统不是一条赛道。Redis 在内存里做热点 KV 很强,但拿它存多年明细数据会贵得离谱;ClickHouse 扫百亿行做聚合很强,但拿它做强事务订单库就很别扭;Kafka 吞吐很高,但它首先是事件流,不是给你随便 SQL 查询的数据库。
一、先按问题分类
我会先把常见存储拆成几大家族。这个分类比背产品名更有用,因为真实系统里经常是组合拳:Kafka 接流量,Flink 做计算,Hudi/Iceberg 存明细,Redis/HBase 服务在线特征,Doris/ClickHouse 做分析,Elasticsearch 做搜索,向量库做语义召回。
二、细化决策树:一步一步选
下面这棵决策树可以直接拿来做初筛。先看图,把候选范围缩到 2-3 个系统;再往下看每个节点的文字解释,结合团队经验、存量架构和压测结果定最终方案。
第 0 步:你要存的是“状态”,还是要传递“事件”?
- 如果核心是事件流、削峰、订阅、回放:先看 Kafka / Pulsar。它们适合把事件可靠地传给下游,不适合替代最终查询库。
- 如果核心是保存最终状态并被查询:继续往下走。比如用户画像、账户余额、订单状态、特征值、日志明细、训练样本。
- 如果两者都有:常见做法是 Kafka/Pulsar 做入口,后面落到 OLTP、OLAP、湖仓或在线 KV。
第 1 步:是否需要强事务和复杂关系?
- 需要 ACID、唯一约束、事务提交、复杂 Join、数据正确性优先:优先 MySQL / PostgreSQL。
- 数据量不大,但业务语义复杂:仍然优先关系型数据库。不要因为“未来可能很大”过早上 NoSQL。
- 写入巨大、关系很弱、主要按 key 查:进入第 2 步,考虑 KV / 宽表。
第 2 步:是否要求在线低延迟点查?
- 要求亚毫秒到毫秒级,数据能放内存,允许较高成本:Redis。适合缓存、会话、排行榜、限流、热点特征。
- 数据量很大,单条或小范围查询,延迟可以是毫秒到几十毫秒:HBase / Cassandra。适合用户维表、在线特征、设备状态、海量 key-value。
- 是在本地进程里做状态存储,而不是独立服务:RocksDB。常见于流计算状态、嵌入式 KV、LSM 存储引擎。
- 还需要 SQL 聚合和报表:不要只放在线 KV,继续进入 OLAP 分支。
第 3 步:是否主要做全文检索、日志检索或半结构化搜索?
- 关键词搜索、分词、相关性排序、模糊匹配、多字段过滤:Elasticsearch / OpenSearch。
- 日志既要检索又要聚合分析:Elasticsearch 能做,但成本可能高;如果更偏指标聚合,考虑 ClickHouse / Druid。
- 只是按 ID 查 JSON:不要为了“能搜”就上搜索引擎,关系型库、文档库或 KV 可能更简单。
第 4 步:是否主要做 SQL 分析、报表和聚合?
- 宽表扫描、聚合、明细分析,追求极致查询速度和压缩率:ClickHouse。
- 高并发 BI、用户画像、标签圈选、实时导入、需要 MySQL 协议生态:Doris。
- 事件流实时摄入,高并发看板,按时间维度 slice-and-dice:Druid。
- 数据主要在湖上,希望多引擎共享,不想把所有数据搬进专用 OLAP:S3/HDFS + Iceberg/Hudi/Delta,再配 Trino、Spark、Doris、Presto 等查询引擎。
第 5 步:是否需要低成本保存多年明细,并支持回溯训练?
- 只是存大量原始文件、日志、图片、离线明细:对象存储 / HDFS。成本低、容量大,但随机更新和低延迟查询不是强项。
- 明细数据有 Upsert、删除、CDC、增量消费:Hudi 更贴近“增量写入和更新”的问题。
- 重视开放表格式、Schema 演进、隐藏分区、多引擎共享:Iceberg。
- 团队已经深度使用 Spark / Databricks 生态:Delta Lake 通常更顺手。
第 6 步:是否是时序指标或监控数据?
- 服务监控、告警、指标标签、PromQL:Prometheus。它更像监控系统自带的时序库,不适合当通用数据仓库。
- IoT、设备指标、金融 tick、时间范围聚合:InfluxDB / TimescaleDB。
- 超大日志和指标混合分析:ClickHouse / Druid 也经常参与,但查询模型和运维方式不同。
第 7 步:是否需要语义相似度、RAG 或向量召回?
- 数据规模小,已经有 PostgreSQL,想少引入组件:pgvector。
- 向量规模大,需要独立扩展、索引类型丰富、召回性能稳定:Milvus / Weaviate。
- 希望少运维,接受云服务绑定:Pinecone 等托管向量数据库。
- 既要关键词又要语义检索:考虑 Elasticsearch / Weaviate / Milvus + 搜索引擎的混合检索方案。
三、性能、吞吐和成本矩阵
这一节不要再只看“快、慢、贵、便宜”。选型时至少要能先算一笔账:同样是 1 TiB 数据,放在对象存储、SSD 集群、Redis、Kafka、向量库里,成本可能差两个到三个数量级。
先把口径说清楚,避免数字看起来很精确,其实没法落地:
- 容量口径:按 1 TiB 逻辑数据估算,1 TiB 约等于 1024 GB;云价以 AWS us-east-1 公开 On-Demand 价格做示例。
- 时间口径:按 730 小时/月估算。美元价格只是统一量尺,不代表必须使用 AWS。
- 副本口径:在线服务通常至少 1 主 1 副本;HDFS、Kafka、Cassandra 这类系统常见 RF=3;列存和湖仓要先看压缩率。
- 未计入项:跨 AZ/跨地域流量、请求费、快照、备份、监控、运维人力、预留实例折扣、峰值冗余都没有算进去。
- 性能口径:下面是公开 benchmark、官方文档和常见工程容量规划量级,不是 SLA。真正上线前仍然要用自己的数据和查询压测。
1. 性能和吞吐的量级
| 类型 | 代表系统 | 典型延迟量级 | 吞吐量级 | 容量/索引放大 | 读数字时要注意 |
|---|---|---|---|---|---|
| 内存 KV / 缓存 | Redis | P50 常见 0.2-1 ms,P99 常见 1-5 ms;跨机房或大 value 会变差 | 官方 redis-benchmark 示例中,pipeline=16 时 SET 约 153 万 req/s,GET 约 181 万 req/s;生产容量规划通常先按单实例 10 万 req/s 量级保守估 | 内存对象本身 + jemalloc 碎片 + 副本 + 持久化;通常按 2-3 倍逻辑容量预留 | Redis 的快来自内存和简单命令;Lua、大 key、热 key、AOF fsync 都会拉低尾延迟。 |
| 关系型数据库 | MySQL / PostgreSQL | 主键/唯一索引点查常见 1-10 ms;复杂 Join、锁等待、慢 SQL 可到 100 ms 以上 | 单主库常见规划起点:5k-50k QPS 或 1k-10k TPS;强依赖 CPU、索引命中率、事务大小、磁盘 fsync | 索引、binlog/WAL、undo、备库、备份后常见 2-4 倍逻辑容量 | 它强在事务和一致性,不强在百亿行扫描。读写混合时,锁和 buffer pool 命中率比“裸 QPS”更重要。 |
| 宽表 / 分布式 KV | HBase / Cassandra | 按 row key 点查/写入常见 P99 5-30 ms;跨分区、宽行、压缩抖动会更高 | 按节点水平扩展;中等规模集群常见是数万到数十万 ops/s 量级 | RF=3 时先变 3 倍;LSM compaction、WAL、block cache 还会带来 1.3-2 倍写放大/空间放大 | key 设计决定上限。热点分区会让“集群总容量很大”变成“某几台机器被打爆”。 |
| 搜索引擎 | Elasticsearch / OpenSearch | 关键词检索/过滤常见 50-500 ms;高基数字段聚合、深分页可能到秒级 | 中等集群常见 5k-50k docs/s 写入量级;文档大小、分词、refresh_interval、replica 数影响很大 | 倒排索引、doc_values、stored fields、replica 后,常见 2-5 倍逻辑容量 | 它是搜索系统,不是最低成本 OLAP。字段全开索引很爽,账单也会很爽。 |
| 实时 OLAP | ClickHouse / Doris / Druid | 过滤聚合常见 100 ms-5 s;命中分区、预聚合、物化视图时可亚秒 | 单节点扫描常见 GB/s 量级;集群批量导入可到 100 MB/s-GB/s 量级 | 列存压缩常见 5-10 倍;ClickBench 100M 行数据中 ClickHouse 约 9.26 GiB,PostgreSQL 约 100 GiB | OLAP 的成本优势来自列裁剪、压缩和批量扫描;频繁小更新和强事务不是它的舒适区。 |
| 对象存储 / 分布式文件 | S3 / OSS / HDFS | S3 单请求常见 10-100 ms 量级;HDFS 顺序读写延迟低一些,但也不是在线点查数据库 | S3 官方口径:每个 prefix 至少 3500 PUT/COPY/POST/DELETE req/s,5500 GET/HEAD req/s;多 prefix 可继续横向扩 | S3 本身按对象计费;HDFS 默认 3 副本就是 3 倍,纠删码可降到约 1.5 倍左右 | 适合吞吐型读写和长期保存,不适合大量小文件随机更新。 |
| 湖仓表格式 | Hudi / Iceberg / Delta | 查询通常是秒到分钟级,取决于 Spark、Trino、Doris、Presto 等计算引擎 | 批量写入可到 100 MB/s-GB/s 量级;小文件、metadata、compaction 会影响稳定性 | Parquet/ORC 压缩常见 2-10 倍;快照、delete files、metadata 额外增加 5%-30% | Hudi/Iceberg/Delta 是表管理格式,不是查询引擎本身。查询慢时别只怪表格式。 |
| 事件流 | Kafka / Pulsar | 健康集群端到端常见毫秒到几十毫秒;Confluent benchmark 在 200 MB/s 负载下 p99 约 5 ms | Confluent benchmark 峰值吞吐 605 MB/s;生产吞吐主要受分区数、batch、acks、磁盘和网络限制 | 成本 = 保留数据量 × RF;RF=3 时,1 TiB 保留数据至少占 3 TiB 磁盘 | Kafka 很适合追加写和回放,不适合当通用查询数据库。 |
| 时序监控 | Prometheus / InfluxDB / VictoriaMetrics | 近期指标查询常见 10 ms-秒级;高基数、长时间范围查询会明显变慢 | 单 Prometheus 常按 10 万-100 万 samples/s 量级做规划,超过后通常分片或上 remote storage | Prometheus 官方估算:保留秒数 × samples/s × 1-2 bytes/sample | 时序库的核心敌人是高基数标签。一个 user_id 标签就可能把容量和查询打穿。 |
| 向量数据库 | Milvus / Weaviate / Pinecone / pgvector | ANN topK 查询常见 10-200 ms;过滤条件复杂、召回率要求高会更慢 | 查询吞吐取决于维度、索引类型、topK、过滤条件;写入通常比普通 KV 更重 | 原始向量 = N × dim × bytes;HNSW/IVF 等索引通常再带来 1-3 倍开销 | 100M 条 768 维 FP32 向量,光原始向量就约 286 GiB;1B 条就是约 2.86 TiB,还没算索引和副本。 |
2. 1 TiB 成本账本
下面这张表更适合做“第一版架构预算”。重点不是精确到个位数美元,而是看数量级:对象存储是几十美元,SSD 三副本是几百美元,Redis 内存化可能直接上万美元。
| 系统/介质 | 计算口径 | 1 TiB 月成本示例 | 为什么会变贵 |
|---|---|---|---|
| S3 Standard 对象存储 | $0.023/GB-month × 1024 GB | 约 $23.55/月;如果 1 TiB 原始日志压成 0.2-0.5 TiB,则约 $4.71-$11.78/月 | 请求费、跨区域流量、生命周期、S3 Tables/compaction、频繁扫描的计算费用。 |
| EBS gp3 / 通用 SSD | $0.08/GB-month × 1024 GB | 约 $81.92/月;gp3 基线含 3000 IOPS 和 125 MiB/s | 额外 IOPS、额外吞吐、多副本、快照、空闲预留容量。 |
| Redis 托管内存 | ElastiCache Redis cache.r7g.xlarge:26.32 GiB,$0.437/h,折算约 $12.1/GiB-month | 1 TiB 逻辑数据,按主副本 2 份 + 30% headroom:1024 × 2 × 1.3 × $12.1,约 $32,000/月 | 内存单价高,且还要为副本、碎片、持久化、热备和扩容 buffer 付钱。 |
| MySQL / PostgreSQL | 1 TiB 主库 + 备库 + 索引/WAL/binlog,常见 2-4 TiB 物理占用 | 仅按 gp3 存储约 $164-$328/月;数据库计算节点通常另加数百到数千美元/月 | 二级索引、事务日志、备份保留、读副本、主备高可用、峰值 CPU。 |
| HBase / Cassandra | RF=3,再乘 LSM/compaction 空间放大 1.3-2 倍,约 4-6 TiB 磁盘 | 仅按 gp3 存储约 $328-$492/月;还要加多台节点计算成本 | 副本、compaction 临时空间、WAL、block cache、热点分区冗余。 |
| Elasticsearch / OpenSearch | 倒排索引 + doc_values + 1 副本,常见 2.4-5 TiB 物理占用 | 仅按 gp3 存储约 $197-$410/月;实际常因内存和 CPU 节点变成更高 | 字段全量索引、分词、深分页、聚合、refresh、replica、热温冷分层。 |
| ClickHouse / Doris / Druid | 列存压缩 5-10 倍,2 副本后约 0.2-0.4 TiB;保守按 0.4-1.0 TiB 看 | 仅按 gp3 存储约 $33-$82/月;真正成本常在计算节点和导入/compaction | 高并发查询、物化视图、冷热分层、导入峰值、SSD/NVMe、本地副本。 |
| Hudi / Iceberg / Delta on S3 | 1 TiB 原始明细压成 0.2-0.5 TiB,metadata/snapshot/delete files 再加 5%-30% | 对象存储约 $5-$15/月;查询时 Spark/Trino/Doris 的计算费用另算 | 小文件、快照保留、compaction、delete files、元数据膨胀、全表扫描。 |
| Kafka / Pulsar | 保留量 = 写入速率 × 保留时间 × RF;1 TiB 保留数据 RF=3 就是 3 TiB | 1 TiB 保留数据按 gp3 约 $245.76/月;100 MB/s 写入保留 7 天,RF=3 时磁盘约 173 TiB,存储约 $14,000/月 | 保留周期、RF、跨 AZ、消息压缩率、consumer lag、峰值吞吐和磁盘水位。 |
| Prometheus 本地 TSDB | 官方公式:retention_seconds × samples_per_second × 1-2 bytes/sample | 200k samples/s 保留 15 天,按 2 bytes/sample 约 483 GiB;gp3 存储约 $39/月 | 高基数标签、WAL、block compaction、remote write、长期保留和查询 fan-out。 |
| 向量库 | 100M × 768 维 × FP32 4 bytes = 约 286 GiB 原始向量;索引 1-3 倍,副本再乘 | 如果按内存放 2 副本,光原始向量约 572 GiB;用上面的内存单价粗算约 $6900/月,还没算索引 | 维度、精度 FP32/FP16/INT8、索引类型、召回率、过滤条件、冷热分层。 |
四、OLAP 再细分:ClickHouse、Doris、Druid 怎么看
OLAP 是最容易混在一起的一类。ClickHouse、Doris、Druid 都能做分析,但工程气质不一样。
如果你只记一句话:ClickHouse 偏极致列式分析,Doris 偏统一实时数仓和高并发服务化查询,Druid 偏实时事件分析和高并发看板。
五、模型平台场景怎么选
如果把问题放回模型平台,存储选型会更清楚。模型平台不是一个库打天下,而是一条链路上不同阶段用不同存储。
| 场景 | 核心问题 | 候选存储 | 选型理由 |
|---|---|---|---|
| 在线特征查询 | 推理请求里按 user_id / item_id 低延迟读特征 | RedisHBaseCassandra | Redis 适合热点和低延迟;HBase/Cassandra 适合容量更大的宽表特征。 |
| 离线训练样本 | 低成本保存多年明细,支持回溯和 Point-in-Time Join | S3/HDFSHudiIcebergDelta | 对象存储和表格式适合大规模明细、版本、增量和跨引擎读取。 |
| 实时特征生产 | 事件持续进入,窗口计算后写入在线特征库 | KafkaPulsarRocksDBRedis/HBase | Kafka/Pulsar 承接流;RocksDB 常作为流计算状态;结果落 Redis/HBase。 |
| 标签服务和人群圈选 | 多条件组合过滤、聚合、Bitmap、较高并发查询 | DorisClickHouse | OLAP 列存适合多维过滤和聚合,Doris 在高并发服务化查询上更友好。 |
| 模型监控和特征漂移 | 按时间看指标、分布、异常和趋势 | PrometheusClickHouseDorisDruid | 监控指标用 Prometheus;复杂分析和长期明细更适合 OLAP。 |
| RAG 和语义召回 | 根据 embedding 找相似文本、图片或多模态对象 | pgvectorMilvusWeaviatePinecone | 小规模可贴近 Postgres;大规模或独立扩展时用专门向量库。 |
六、成本怎么想
成本不是只看机器单价,而是看“单位有效查询”的成本。一个更实用的算法是先把成本拆成公式:
- Redis 成本 = 逻辑 GiB × 副本数 × headroom × 内存单价。只要数据从 100 GiB 变成 1 TiB,成本就会从“可接受”变成“要专门评审”。
- 磁盘型集群成本 = 逻辑 GiB × 索引/压缩/compaction 放大 × 副本数 × 磁盘单价 + 计算节点。HBase、Cassandra、Elasticsearch、Kafka 都要这么算。
- 湖仓成本 = 压缩后对象存储成本 + 元数据/快照/小文件成本 + 查询计算成本。存着便宜,不代表反复扫全表也便宜。
- Kafka 成本 = 写入速率 × 保留时间 × 副本数。100 MB/s 写入看起来不夸张,保留 7 天、RF=3 后就是百 TiB 级磁盘。
- Prometheus 成本 = retention_seconds × samples_per_second × bytes_per_sample。真正要管的是 samples/s 和标签基数。
- 向量库成本 = 向量条数 × 维度 × 单维字节数 × 索引放大 × 副本数。维度从 384 到 768,成本几乎直接翻倍。
所以选型时我会先问一句很具体的话:这个数据未来一年会到 100 GiB、1 TiB、10 TiB,还是 100 TiB?如果答案是 10 TiB 以上,就不要轻易把它放进内存系统或全文索引系统;如果答案是 100 TiB 以上,湖仓和冷热分层基本是绕不开的。
七、容易选错的地方
- 把 Kafka 当数据库:Kafka 可以保留一段时间的事件日志,但它不是通用查询系统。
- 把 Redis 当低成本主存储:Redis 的速度来自内存,容量账单也来自内存。
- 把 Elasticsearch 当 OLAP:它能聚合,但强项仍然是搜索和检索相关性,不是最低成本的大规模分析。
- 把湖仓表格式当查询引擎:Hudi、Iceberg、Delta 解决表管理和事务语义,真正跑查询还要 Spark、Trino、Doris、Presto 等引擎。
- 只看单机性能,不看并发和运维:很多系统压单条查询很快,但高并发、权限隔离、扩容、冷热分层才是长期成本。
八、最后总结
存储系统选型的核心不是“哪个系统最强”,而是“哪个系统最适合这个访问模式”。
在线事务交给 MySQL/PostgreSQL,热点低延迟交给 Redis,大规模宽表点查交给 HBase/Cassandra,搜索交给 Elasticsearch,分析交给 ClickHouse/Doris/Druid,低成本明细交给对象存储和湖仓表格式,事件流交给 Kafka/Pulsar,语义召回交给向量库。真正成熟的架构不是迷信一个系统,而是让每个系统只做它擅长的事情。
参考资料
- Amazon S3 User Guide
- Amazon S3 Performance Guidelines
- Amazon S3 Pricing
- Amazon EBS gp3 Performance
- Amazon EBS Pricing
- Amazon ElastiCache Pricing
- Apache Hadoop HDFS Architecture
- Apache Hadoop HDFS Erasure Coding
- Redis Open Source Documentation
- Redis Benchmark Documentation
- Apache HBase Reference Guide
- Apache Cassandra Documentation
- ClickHouse Docs: What is ClickHouse?
- ClickHouse Engineering: Database Compression
- Apache Doris Overview
- Apache Druid Design Documentation
- Elasticsearch Reference
- Apache Hudi Overview
- Apache Iceberg Documentation
- Delta Lake Documentation
- Apache Kafka
- Apache Kafka Performance Benchmark by Confluent
- Apache Pulsar
- Prometheus Overview
- Prometheus Storage
- Milvus Documentation
- pgvector