HBase中列族(Column Family)和列限定符(Column Qualifier)
在 HBase 的数据模型中,列族(Column Family)和列限定符(Column Qualifier)是构建其“宽列(Wide-Column)”存储结构的核心概念。理解它们是掌握 HBase 数据建模和性能调优的基础。
简单来说,它们组合在一起构成了 HBase 中的“列”,标准格式为:列族:列限定符(例如:info:name,info:age)。
以下是它们的详细解析及对比:
1. 列族(Column Family)
列族是 HBase 表的物理和逻辑上的核心分组。
- 必须预先定义: 在创建 HBase 表时,必须明确指定包含哪些列族(Schema 是静态的)。例如:
create 'user_table', 'info', 'contact'。 - 物理存储隔离: 这是列族最重要的特性。HBase 是按列族进行物理存储的。 同一个列族的数据在底层的 HDFS 上会被存储在同一个文件夹(Store)中的同一批 HFile 里。不同列族的数据是物理隔离的。
- 权限与属性控制: HBase 的很多核心属性都是配置在列族级别上的,而不是表或具体列级别。例如:
- 数据保留版本数(VERSIONS)
- 数据存活时间(TTL - Time To Live)
- 数据压缩算法(COMPRESSION)
- 布隆过滤器(BLOOMFILTER)
- 数量限制: 官方强烈建议一个表的列族数量不要太多(通常建议 1~3 个)。因为 HBase 刷写(Flush)内存数据到磁盘时是以 Region 为单位的,一个列族刷写会引发其他列族也跟着刷写,列族过多会导致产生大量碎片化的 HFile,严重影响性能。
2. 列限定符(Column Qualifier)
列限定符是列族内部的具体列名,用于进一步定位数据。
- 动态扩展(Schema-less): 与列族不同,列限定符不需要在建表时预先定义。你可以在插入数据(Put)时随时动态增加新的列限定符。
- 极度灵活: 同一个表、同一个列族下,不同的行(RowKey)可以拥有完全不同的列限定符。
- Row 1 只有
info:name - Row 2 可以有
info:name,info:age,info:gender
- Row 1 只有
- 不存 Null 值: 如果某一行没有某个列限定符,HBase 根本不会为它分配存储空间(这与关系型数据库中存 NULL 占据空间完全不同)。
- 数量无上限: 一个列族下可以包含数百万甚至数千万个不同的列限定符,非常适合存储稀疏数据。
3. 图解与类比说明
为了更好理解,我们可以把 HBase 的数据结构看作是一个多层嵌套的 Map(字典):
json
// RowKey -> { ColumnFamily -> { ColumnQualifier -> { Timestamp -> Value } } }
"user_001": {
"info": {
"name": { "T1": "张三" },
"age": { "T1": "25" }
},
"contact": {
"phone": { "T2": "13800138000" },
"email": { "T1": "zhangsan@test.com" }
}
}
user_001是 RowKey。info和contact是 列族(Column Family)。name,age,phone,email是 列限定符(Column Qualifier)。
4. 读写机制与性能影响
- 查询优势: 如果你执行查询只需获取用户的联系方式,你只需要读取
contact列族。HBase 底层只会去读取contact列族对应的 HFile 文件,完全不需要触碰info列族的数据。这极大地减少了磁盘 I/O,这就是“列式存储”的优势。 - 命名规范: 列族和列限定符的名称应该尽可能短。 因为在 HBase 底层的存储中,每一个数据单元(Cell)都会完整地保存一份
RowKey + ColumnFamily + ColumnQualifier + Timestamp。如果列名太长(比如叫personal_information:user_first_name),会导致严重的数据冗余,浪费大量存储空间和网络带宽。最好简写为i:fn。
5. 总结对比表
| 特性 | 列族 (Column Family) | 列限定符 (Column Qualifier) |
|---|---|---|
| 定义时机 | 建表时必须静态定义 | 插入数据时动态生成(随时增减) |
| 数量限制 | 建议很少(通常 1~3 个) | 理论上无上限(百万、千万级均可) |
| 物理存储 | 同一列族存放在同一个 Store (HFile 集合) 中 | 存在于所属的列族文件中,依附于列族 |
| 属性配置 | 可以在此级别配置 TTL、版本数、压缩等 | 继承所属列族的配置,无法单独配置 |
| 一致性 | 表中所有行共享相同的列族 | 每一行可以拥有完全不同的列限定符 |
| 示例 | info |
name, age, address |