本文是大数据系列第 36 篇,介绍 HBase 列族设计思路与 Shell 下的增删改查实操。

完整图文版(含截图):CSDN 原文 | 掘金

列族(Column Family)

HBase 中列的完整标识为 列族名:限定符(Column Family : Qualifier),列族是最小的物理存储单元。同一列族的数据存储在同一组 HFile 中,读写时以列族为单位刷写磁盘。

列族数量的抉择

列族数量过多会带来以下问题:

  • MemStore 刷写频繁:每个列族都有独立的 MemStore,小列族触发 flush 时会连带刷写其他列族,产生大量小文件。
  • Compaction 开销增大:文件数量增多,后台合并压力随之上升。
  • Region 分裂复杂:多列族分裂策略需要额外协调。

最佳实践:通常设计 1-3 个列族,将访问频率、TTL、压缩策略相近的列归入同一列族。

设计示例

create 'user_profile',
  {NAME => 'base',   COMPRESSION => 'LZ4',  BLOCKSIZE => '65536',  TTL => 31536000},
  {NAME => 'detail', COMPRESSION => 'ZSTD', BLOCKSIZE => '131072', TTL => 7776000},
  {NAME => 'stat',   BLOOMFILTER => 'ROW',  VERSIONS => 5}
  • base:高频核心字段,LZ4 压缩兼顾速度与压缩比,TTL 1 年。
  • detail:低频大字段(如详情文本),ZSTD 压缩率更高,TTL 90 天。
  • stat:派生统计指标,保留 5 个版本以支持时序查询。

启动 HBase Shell

hbase shell

进入 Shell 后可通过 help 查看所有命令分类。

创建表

# 创建表 wzk,包含两个列族
create 'wzk', 'base_info', 'extra_info'

插入数据

put 'wzk', 'rk1', 'base_info:name', 'icu'
put 'wzk', 'rk1', 'base_info:age',  30
put 'wzk', 'rk1', 'extra_info:city', 'Beijing'

put 语法:put '表名', '行键', '列族:列名', '值'。每次 put 都会写入一个带时间戳的新版本。

查询数据

# 查询整行
get 'wzk', 'rk1'

# 查询指定列族
get 'wzk', 'rk1', 'base_info'

# 使用过滤器查询
get 'wzk', 'rk1', {FILTER => "ValueFilter(=, 'binary:icu')"}

批量扫描使用 scan

scan 'wzk'
scan 'wzk', {STARTROW => 'rk1', STOPROW => 'rk3'}

更新数据

HBase 没有独立的 update 操作,再次 put 同一行键+列即可写入新版本,查询时默认返回最新版本:

put 'wzk', 'rk1', 'base_info:age', 31

删除数据

# 删除指定列
delete 'wzk', 'rk1', 'base_info:name'

# 删除整行
deleteall 'wzk', 'rk1'

# 删除表(需先 disable)
disable 'wzk'
drop 'wzk'

性能与维护要点

操作建议
批量写入使用 BufferedMutator 而非逐条 put
大范围扫描设置 STARTROW/STOPROW 缩小扫描范围
版本控制默认保留 1 个版本,统计类列族可设置更多
TTL 清理为冷数据列族设置 TTL,减少存储占用
BloomFilter随机读场景开启 ROW 级 BloomFilter,降低磁盘 IO