3、特征存储选型:HBase vs Redis vs MySQL
特征存储选型,说白了就是给你的特征数据找个合适的家。我见过不少团队,一上来就拍脑袋选 Redis,理由是“快”。结果呢?存储成本飙升,冷数据占着热内存,查询模式还跟业务对不上。嗯,今天咱们就聊聊这件事。
3.1 三种存储引擎的核心差异
先看一张对比表,把 HBase、Redis、MySQL 的底牌亮出来:
| 维度 | HBase | Redis | MySQL |
|---|---|---|---|
| 数据模型 | 宽表、稀疏列族 | KV、Hash、Set 等 | 关系型表、行存储 |
| 读写模式 | 写吞吐极高、随机读慢 | 读写都极快(内存) | 读写均衡、事务强 |
| 扩展性 | 原生水平扩展 | 集群模式、分片复杂 | 主从、分库分表 |
| 存储成本 | 低(HDFS 冷存储) | 高(全内存) | 中(SSD) |
| 典型场景 | 大规模离线特征、时序特征 | 实时特征、高并发在线服务 | 元数据、配置、小规模特征 |
我个人习惯,选型时先问三个问题:
- 特征数据有多大? 百亿级?还是百万级?
- 延迟要求多高? 毫秒级?还是秒级可以接受?
- 冷热数据怎么分? 历史特征要不要保留?
我在项目中遇到过一家金融公司,他们把所有用户画像特征都塞进 Redis,结果内存成本一个月烧掉 20 万。后来我们把 90 天前的冷特征迁移到 HBase,Redis 只保留最近 7 天的热数据,成本直接砍掉 70%。
3.2 特征存储的读写模式
特征存储的读写模式,跟业务场景强相关。我把它拆成三种典型模式:
模式一:在线实时读取(Online Serving)
模型推理时,需要毫秒级拿到特征。这种场景下,Redis 是首选。但要注意,不是所有特征都适合放 Redis。
模式二:批量离线写入(Batch Ingestion)
每天凌晨跑批任务,把加工好的特征写入存储。这种场景下,HBase 的写吞吐优势就体现出来了。
// 伪代码:批量写入 HBase
HTable table = new HTable(conf, "feature_table");
List<Put> puts = new ArrayList<>();
for (FeatureRecord record : batchRecords) {
Put put = new Put(Bytes.toBytes(record.getRowKey()));
put.addColumn(CF_DEFAULT, QUALIFIER, record.getValue());
puts.add(put);
if (puts.size() >= 1000) {
table.put(puts);
puts.clear();
}
}
table.put(puts);
你想想看,如果换成 MySQL 做批量写入,每秒几千条就卡住了。HBase 可以轻松扛到每秒几十万条。
模式三:点查与范围扫描(Point Lookup & Scan)
特征服务最常见的操作就是根据 entity_id 查特征。Redis 的点查是 O(1),HBase 的点查依赖 RowKey 设计,设计不好就是全表扫描。
3.3 冷热数据分离策略
冷热数据分离,是特征存储成本控制的核心手段。说白了,就是把访问频率高的热数据放在高速存储上,把访问频率低的冷数据放在廉价存储上。
我常用的策略是“三级分层”:
- 热层(L1):Redis — 最近 7 天的特征,毫秒级响应。
- 温层(L2):HBase — 7 天到 90 天的特征,秒级响应。
- 冷层(L3):HDFS / 对象存储 — 90 天以上的特征,分钟级响应,用于离线回溯。
来看一张我画的架构图:
这张图的核心思想是:对业务层透明。特征服务 API 不关心数据存在哪,只负责根据时间戳和访问频率自动路由。
冷热分离的实现要点
- 数据迁移策略: 我习惯用 TTL + 定时任务。Redis 设置 7 天 TTL,到期后自动淘汰。HBase 设置 90 天 TTL,到期后归档到 HDFS。
- 查询路由: 特征服务先查 Redis,没命中再查 HBase,还没命中就去 HDFS 拉取。这个逻辑用“缓存穿透保护”兜底。
- 成本控制: 冷数据压缩比很高。HDFS 上我用 Snappy 压缩,特征文件能压缩到原始大小的 20%。
3.4 选型决策矩阵
最后,我整理了一个决策矩阵,帮你快速判断:
| 业务场景 | 推荐存储 | 理由 |
|---|---|---|
| 实时推荐、广告 CTR 预估 | Redis + HBase | 热数据 Redis 扛 QPS,冷数据 HBase 兜底 |
| 离线批量特征计算 | HBase | 写吞吐高,支持大规模批量写入 |
| 特征元数据管理 | MySQL | 事务支持好,适合存储特征定义、版本、血缘 |
| 小规模特征(百万级) | MySQL + Redis 缓存 | 架构简单,运维成本低 |
| 超大规模特征(百亿级) | HBase + HDFS | 水平扩展能力强,存储成本可控 |
嗯,选型没有银弹。我见过用 MySQL 扛住百亿特征的团队(靠分库分表和 SSD),也见过用 Redis 存全量特征结果内存爆掉的案例。关键还是想清楚你的业务特征:数据量、延迟要求、成本预算,这三者决定了最终方案。