基于本文回答

播面 播面

文图音视,全方位拆解八股文
0
评论

HBase中列族(Column Family)和列限定符(Column Qualifier)

在 HBase 的数据模型中,列族(Column Family)列限定符(Column Qualifier)是构建其“宽列(Wide-Column)”存储结构的核心概念。理解它们是掌握 HBase 数据建模和性能调优的基础。

简单来说,它们组合在一起构成了 HBase 中的“列”,标准格式为:列族:列限定符(例如:info:nameinfo: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
  • 不存 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。
  • infocontact列族(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
00:00
00:00