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。

我的经验: 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 设计,设计不好就是全表扫描。

避坑指南: 我曾经见过一个团队,把 HBase 的 RowKey 设计成自增 ID,结果查询时根本没法定位到 Region,每次都要扫描多个 RegionServer。后来改成“entity_id + 时间戳倒序”作为 RowKey,查询效率提升了 10 倍。

3.3 冷热数据分离策略

冷热数据分离,是特征存储成本控制的核心手段。说白了,就是把访问频率高的热数据放在高速存储上,把访问频率低的冷数据放在廉价存储上。

我常用的策略是“三级分层”:

  1. 热层(L1):Redis — 最近 7 天的特征,毫秒级响应。
  2. 温层(L2):HBase — 7 天到 90 天的特征,秒级响应。
  3. 冷层(L3):HDFS / 对象存储 — 90 天以上的特征,分钟级响应,用于离线回溯。

来看一张我画的架构图:

特征存储冷热分离架构 特征存储冷热分离架构 特征计算引擎 冷热分流决策 L1: Redis 最近 7 天 · 毫秒级 L2: HBase 7-90 天 · 秒级 L3: HDFS 90 天以上 · 分钟级 统一特征服务 API 在线推理 / 离线回溯 冷热数据对业务透明 统一 API 屏蔽存储差异

这张图的核心思想是:对业务层透明。特征服务 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 存全量特征结果内存爆掉的案例。关键还是想清楚你的业务特征:数据量、延迟要求、成本预算,这三者决定了最终方案。