HBase
建在 HDFS 上的列式 KV,十亿行也能按 RowKey 秒查
HBase 是 Google BigTable 的开源实现:按 RowKey 排好序存在 HDFS 上,支持百万级 QPS 的随机读写和几十亿行数据。它不是“另一个 MySQL”,不会 SQL,也不做多表 JOIN,查询只能顺着 RowKey 走。
它解决什么问题
MySQL 单表过亿就难扛,分库分表后又没法按任意维度查;HDFS 能存但不能随机查。中间这块“海量数据 + 按 key 随机读写”的空白需要有人填。
真实场景:典型场景:用户行为明细每天写几亿条,按「用户ID + 时间戳」做 RowKey,查某个用户最近三个月的记录就是一次范围扫描。
核心概念
每个概念一句话 + 一个类比。点击卡片看更详细的解释。
RowKey
每行的唯一 ID,也是唯一的索引,按字典序排好
类比:字典里的词条,查什么全靠它
看概念详情Column Family
列的上级分组,建表时定好,物理上同族存在一起
类比:档案袋,同一类的材料装在一个袋子里
看概念详情Region
按 RowKey 范围切成的数据分片,一个 Region 由一个 RegionServer 管
类比:字典按 A-C、D-F 分册
看概念详情MemStore
写入先进内存并记 WAL,写满再刷成磁盘文件
类比:先在草稿纸上记,攒够一页再誊到正式本子上
看概念详情LSM 树
只追加不原地改,靠后台合并把多个文件整理成有序大文件
类比:快递驿站的包裹堆,定期统一上架整理
看概念详情数据流转动画
跟着步骤看一条数据从进入系统到被处理完的完整路径,可以暂停、重播和调速。
一次写入是怎么落盘、又怎么被读到的
← 左右滑动查看完整流程图 →
客户端用 RowKey 查 hbase:meta 表,算出这行属于哪个 Region、在哪台 RegionServer 上。
提示:写入先落 WAL 保证不丢,再进 MemStore;MemStore 满了才刷成 HFile,后台还会不断合并。 悬停图中的节点可以看概念解释。
优劣势
短句说清适合什么、不适合什么,选型时先看这一栏。
- 十亿行级别仍能按 RowKey 毫秒级随机读写
- 列族存储,稀疏数据不浪费空间
- 水平扩展:Region 分裂后自动迁移,加机器就扩容
- 强一致(单行),读写都走同一份数据
- 只有 RowKey 一个索引,换个维度查就是全表扫
- 不支持 SQL、JOIN、二级索引(Phoenix 能补但有限)
- 依赖 HDFS + ZooKeeper,组件多、运维重
- RowKey 设计一旦错了,后面几乎无法补救
常见使用场景
每个场景都配一句「为什么用它」。
用户行为与消息明细
按「用户ID + 反转时间戳」做 RowKey,存聊天记录、操作日志、订单流水。
为什么用它:天然按用户聚簇,查某个用户最近 N 条是一次连续扫描。
画像与标签存储
每个用户一行,列族放不同类目的标签,随时加列不用改表。
为什么用它:列族 + 稀疏存储,标签上千个也只有实际写入的才占空间。
时序数据的原始层
IoT 设备上报数据按「设备ID + 时间」写入,供离线分析。
为什么用它:写入量大、按设备范围查询,正好匹配 HBase 的模型。
常见问题
上手第一个月最容易卡住的地方。
Q1RowKey 怎么设计才不踩坑?
三条原则:一是长度短(几十字节内),二是散列均匀避免热点(加盐、哈希前缀、反转时间戳),三是把最常用的查询条件放前面。比如查「某用户最近记录」用 userId + (Long.MAX_VALUE - ts),而不是 ts + userId。
Q2HBase 和 MySQL 分库分表怎么选?
要事务、要 JOIN、数据量在千万到几亿,继续用 MySQL 分库分表;数据几十亿行、只按 key 查、写入量极大、能接受没有 SQL,才考虑 HBase。多数团队用 HBase 是因为 MySQL 真的扛不住了。
Q3为什么写 HBase 比读快很多?
写是顺序追加 WAL + 内存写 MemStore,几乎没有随机 IO;读要合并 MemStore 和多个 HFile,还要判断布隆过滤器、读 block cache,路径长得多。所以 HBase 适合写多读少或按 key 精确读。
Q4Region 热点怎么办?
预分区(建表时按 RowKey 范围切好 Region)+ RowKey 打散(加随机前缀、哈希)。如果已经出现热点,可以用 split 手动切分,或者把热点 RowKey 改成加盐形式重写数据。