HBase数据存储模型 #

一、LSM Tree概述 #

HBase基于LSM Tree(Log-Structured Merge Tree)实现数据存储,这是一种针对写入优化的数据结构。

1.1 LSM Tree原理 #

text
┌─────────────────────────────────────────────────────────────────────┐
│                         LSM Tree 原理                                │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  写入流程:                                                         │
│  ┌─────────┐      ┌──────────┐      ┌───────────────────────────┐  │
│  │  Write  │ ───► │ MemStore │ ───► │      StoreFile (HFile)    │  │
│  │ Request │      │  (内存)   │      │         (磁盘)            │  │
│  └─────────┘      └──────────┘      └───────────────────────────┘  │
│                         │                    │                      │
│                         │ Flush              │ Compaction           │
│                         ▼                    ▼                      │
│                   ┌──────────┐         ┌───────────┐                │
│                   │   WAL    │         │  合并文件  │                │
│                   │ (日志)   │         │  清理数据  │                │
│                   └──────────┘         └───────────┘                │
│                                                                     │
│  优势:                                                             │
│  - 写入性能高(顺序写)                                             │
│  - 支持大数据量存储                                                 │
│  - 自动合并优化查询                                                 │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

1.2 LSM Tree vs B+ Tree #

特性 LSM Tree B+ Tree
写入方式 顺序写 随机写
写入性能 极高 较低
读取性能 需合并查询
空间利用 有写放大 较高
适用场景 写多读少 读写均衡

二、MemStore #

2.1 MemStore概述 #

MemStore是HBase的内存写缓存,所有写入操作首先写入MemStore。

text
┌─────────────────────────────────────────────────────────────────────┐
│                         MemStore 结构                               │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  RegionServer                                                       │
│  ┌───────────────────────────────────────────────────────────────┐ │
│  │  Region                                                        │ │
│  │  ┌─────────────────────────────────────────────────────────┐  │ │
│  │  │  Store (Column Family)                                  │  │ │
│  │  │  ┌─────────────────────────────────────────────────────┐│  │ │
│  │  │  │  MemStore                                           ││  │ │
│  │  │  │  ┌───────────────────────────────────────────────┐  ││  │ │
│  │  │  │  │  SkipList (有序数据结构)                       │  ││  │ │
│  │  │  │  │  ┌─────┐                                       │  ││  │ │
│  │  │  │  │  │row3 │ cf:col → value3                       │  ││  │ │
│  │  │  │  │  ├─────┤                                       │  ││  │ │
│  │  │  │  │  │row2 │ cf:col → value2                       │  ││  │ │
│  │  │  │  │  ├─────┤                                       │  ││  │ │
│  │  │  │  │  │row1 │ cf:col → value1                       │  ││  │ │
│  │  │  │  │  └─────┘                                       │  ││  │ │
│  │  │  │  └───────────────────────────────────────────────┘  ││  │ │
│  │  │  └─────────────────────────────────────────────────────┘│  │ │
│  │  └─────────────────────────────────────────────────────────┘  │ │
│  └───────────────────────────────────────────────────────────────┘ │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

2.2 MemStore特性 #

text
MemStore特性
├── 数据结构
│   └── SkipList(跳表),保证有序性
│
├── 内存管理
│   ├── 默认128MB刷新阈值
│   └── 占用堆内存比例可配置
│
├── 数据排序
│   └── 按RowKey、CF、CQ、Timestamp排序
│
└── 刷新触发条件
    ├── MemStore大小达到阈值
    ├── RegionServer全局内存压力
    ├── 手动触发
    └── 时间间隔触发

2.3 MemStore配置 #

xml
<!-- hbase-site.xml -->

<!-- MemStore刷新阈值 -->
<property>
    <name>hbase.hregion.memstore.flush.size</name>
    <value>134217728</value>  <!-- 128MB -->
</property>

<!-- RegionServer全局MemStore大小比例 -->
<property>
    <name>hbase.regionserver.global.memstore.size</name>
    <value>0.4</value>
</property>

<!-- 低水位比例 -->
<property>
    <name>hbase.regionserver.global.memstore.size.lower.limit</name>
    <value>0.95</value>
</property>

<!-- MemStore本地聚合缓冲区 -->
<property>
    <name>hbase.hregion.memstore.mvcc.max</name>
    <value>10</value>
</property>

2.4 Flush流程 #

text
┌─────────────────────────────────────────────────────────────────────┐
│                         Flush 流程                                   │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  触发条件:                                                         │
│  1. MemStore达到128MB                                               │
│  2. RegionServer全局MemStore达到高水位                              │
│  3. 手动触发 flush 'table_name'                                     │
│  4. WAL日志数量过多                                                 │
│                                                                     │
│  Flush流程:                                                        │
│  ┌──────────┐    ┌──────────┐    ┌──────────┐    ┌──────────┐      │
│  │ MemStore │ ─► │ 准备阶段 │ ─► │ 写HFile │ ─► │ 更新元数据│      │
│  │          │    │ 阻塞写入 │    │ 写磁盘   │    │ 清空内存 │      │
│  └──────────┘    └──────────┘    └──────────┘    └──────────┘      │
│                                                                     │
│  注意:                                                             │
│  - Flush期间写入会阻塞(短暂)                                      │
│  - 生成新的HFile文件                                                │
│  - 更新StoreFile列表                                                │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

三、StoreFile与HFile #

3.1 StoreFile概述 #

StoreFile是HBase中HFile的逻辑表示,每个StoreFile对应一个HFile文件。

text
Store
├── MemStore (内存)
└── StoreFiles (磁盘)
    ├── StoreFile 1 (HFile 1)
    ├── StoreFile 2 (HFile 2)
    ├── StoreFile 3 (HFile 3)
    └── ...

3.2 HFile结构 #

text
┌─────────────────────────────────────────────────────────────────────┐
│                         HFile 结构                                   │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  ┌─────────────────────────────────────────────────────────────┐   │
│  │                      HFile v3                                │   │
│  ├─────────────────────────────────────────────────────────────┤   │
│  │  ┌─────────────────────────────────────────────────────┐    │   │
│  │  │                    File Info                         │    │   │
│  │  │  - lastKey, avgKeyLen, avgValueLen                   │    │   │
│  │  │  - compression, encryption                           │    │   │
│  │  └─────────────────────────────────────────────────────┘    │   │
│  ├─────────────────────────────────────────────────────────────┤   │
│  │  ┌─────────────────────────────────────────────────────┐    │   │
│  │  │                   Data Block 1                       │    │   │
│  │  │  ┌─────┬──────────────────────────────────────┐     │    │   │
│  │  │  │ KV  │ Key | Value | Type | Timestamp      │     │    │   │
│  │  │  │ 1   │ row1| val1  | Put  | 1704067200     │     │    │   │
│  │  │  │ 2   │ row2| val2  | Put  | 1704067201     │     │    │   │
│  │  │  └─────┴──────────────────────────────────────┘     │    │   │
│  │  └─────────────────────────────────────────────────────┘    │   │
│  │  ┌─────────────────────────────────────────────────────┐    │   │
│  │  │                   Data Block 2                       │    │   │
│  │  └─────────────────────────────────────────────────────┘    │   │
│  │                          ...                                │   │
│  ├─────────────────────────────────────────────────────────────┤   │
│  │  ┌─────────────────────────────────────────────────────┐    │   │
│  │  │                   Meta Block                         │    │   │
│  │  │  - Bloom Filter Data                                │    │   │
│  │  └─────────────────────────────────────────────────────┘    │   │
│  ├─────────────────────────────────────────────────────────────┤   │
│  │  ┌─────────────────────────────────────────────────────┐    │   │
│  │  │                   Load-on-open                       │    │   │
│  │  │  - Root Data Index                                   │    │   │
│  │  │  - File Info                                         │    │   │
│  │  └─────────────────────────────────────────────────────┘    │   │
│  ├─────────────────────────────────────────────────────────────┤   │
│  │  ┌─────────────────────────────────────────────────────┐    │   │
│  │  │                   Trailer                            │    │   │
│  │  │  - File Info Offset                                  │    │   │
│  │  │  - Compression Codec                                 │    │   │
│  │  └─────────────────────────────────────────────────────┘    │   │
│  └─────────────────────────────────────────────────────────────┘   │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

3.3 HFile Block类型 #

Block类型 说明
Data Block 存储实际KV数据
Index Block 数据索引,快速定位
Bloom Block 布隆过滤器数据
Meta Block 元数据信息
File Info 文件信息

3.4 KeyValue格式 #

text
┌─────────────────────────────────────────────────────────────────────┐
│                       KeyValue 格式                                  │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  ┌───────────────────────────────────────────────────────────────┐ │
│  │ Key Length │ Value Length │ Key │ Type │ Timestamp │ Value    │ │
│  │  (4 bytes) │  (4 bytes)   │     │(1 B) │ (8 bytes) │          │ │
│  └───────────────────────────────────────────────────────────────┘ │
│                                                                     │
│  Key结构:                                                          │
│  ┌───────────────────────────────────────────────────────────────┐ │
│  │ Row Length │ RowKey │ CF Length │ CF │ CQ Length │ CQ │ TS   │ │
│  │  (2 bytes) │        │  (1 byte) │    │ (2 bytes) │    │(8 B) │ │
│  └───────────────────────────────────────────────────────────────┘ │
│                                                                     │
│  Type类型:                                                         │
│  ├── Put        - 写入                                             │
│  ├── Delete     - 删除列                                           │
│  ├── DeleteFamily - 删除列族                                       │
│  └── DeleteFamilyVersion - 删除列族版本                            │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

四、WAL(Write-Ahead Log) #

4.1 WAL概述 #

WAL是HBase的写前日志,保证数据不丢失。

text
┌─────────────────────────────────────────────────────────────────────┐
│                         WAL 机制                                     │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  写入流程:                                                         │
│                                                                     │
│  ┌─────────┐      ┌──────────┐      ┌──────────┐                   │
│  │  Write  │ ───► │   WAL    │ ───► │ MemStore │                   │
│  │ Request │      │ (磁盘)   │      │  (内存)  │                   │
│  └─────────┘      └──────────┘      └──────────┘                   │
│                         │                                           │
│                         ▼                                           │
│                   ┌──────────┐                                      │
│                   │  返回成功 │                                      │
│                   └──────────┘                                      │
│                                                                     │
│  故障恢复:                                                         │
│  RegionServer故障后,新节点读取WAL重放数据                          │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

4.2 WAL类型 #

类型 说明 适用场景
SYNC 同步写入,等待磁盘确认 强一致性要求
ASYNC 异步写入,不等待确认 高性能要求
SYNC_WAL 同步WAL 默认配置

4.3 WAL配置 #

xml
<!-- hbase-site.xml -->

<!-- WAL存储目录 -->
<property>
    <name>hbase.wal.dir</name>
    <value>/hbase/WALs</value>
</property>

<!-- WAL滚动大小 -->
<property>
    <name>hbase.regionserver.logroll.period</name>
    <value>3600000</value>  <!-- 1小时 -->
</property>

<!-- WAL最大文件数 -->
<property>
    <name>hbase.regionserver.maxlogs</name>
    <value>32</value>
</property>

五、Compaction #

5.1 Compaction概述 #

Compaction是HBase合并StoreFile的过程,分为Minor和Major两种。

text
┌─────────────────────────────────────────────────────────────────────┐
│                         Compaction 类型                              │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  Minor Compaction(小合并)                                         │
│  ┌─────────────────────────────────────────────────────────────┐   │
│  │  StoreFile 1 + StoreFile 2 + StoreFile 3 → StoreFile New    │   │
│  │                                                              │   │
│  │  特点:                                                      │   │
│  │  - 合并部分小文件                                            │   │
│  │  - 不删除过期数据                                            │   │
│  │  - 执行频率高                                                │   │
│  └─────────────────────────────────────────────────────────────┘   │
│                                                                     │
│  Major Compaction(大合并)                                         │
│  ┌─────────────────────────────────────────────────────────────┐   │
│  │  All StoreFiles → One StoreFile                             │   │
│  │                                                              │   │
│  │  特点:                                                      │   │
│  │  - 合并所有文件                                              │   │
│  │  - 删除过期数据(TTL、标记删除)                              │   │
│  │  - 执行频率低,资源消耗大                                    │   │
│  └─────────────────────────────────────────────────────────────┘   │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

5.2 Compaction触发条件 #

text
触发条件
├── Minor Compaction
│   ├── StoreFile数量达到阈值
│   ├── MemStore Flush后
│   └── 手动触发
│
└── Major Compaction
    ├── 定时触发(默认7天)
    ├── 手动触发
    └── Region合并后

5.3 Compaction配置 #

xml
<!-- hbase-site.xml -->

<!-- Minor Compaction文件数阈值 -->
<property>
    <name>hbase.hstore.compaction.min</name>
    <value>3</value>
</property>

<!-- Major Compaction间隔(毫秒) -->
<property>
    <name>hbase.hregion.majorcompaction</name>
    <value>604800000</value>  <!-- 7天 -->
</property>

<!-- 禁用自动Major Compaction -->
<property>
    <name>hbase.hregion.majorcompaction</name>
    <value>0</value>
</property>

<!-- Compaction线程数 -->
<property>
    <name>hbase.regionserver.thread.compaction.throttle</name>
    <value>2</value>
</property>

六、BlockCache #

6.1 BlockCache概述 #

BlockCache是HBase的读缓存,缓存HFile数据块。

text
┌─────────────────────────────────────────────────────────────────────┐
│                         BlockCache 结构                              │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  RegionServer 堆内存                                                │
│  ┌───────────────────────────────────────────────────────────────┐ │
│  │                                                                │ │
│  │  ┌────────────────────┐    ┌────────────────────┐             │ │
│  │  │    MemStore (40%)  │    │  BlockCache (40%)  │             │ │
│  │  │                    │    │                    │             │ │
│  │  │  写缓存             │    │  读缓存            │             │ │
│  │  │  存储待刷新数据     │    │  缓存热数据块      │             │ │
│  │  └────────────────────┘    └────────────────────┘             │ │
│  │                                                                │ │
│  │  ┌────────────────────────────────────────────────────────┐   │ │
│  │  │              其他内存 (20%)                             │   │ │
│  │  └────────────────────────────────────────────────────────┘   │ │
│  │                                                                │ │
│  └───────────────────────────────────────────────────────────────┘ │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

6.2 BlockCache实现 #

实现 说明 适用场景
LruBlockCache LRU算法,堆内内存 默认配置
BucketCache 堆外内存,减少GC 大内存场景
CombinedBlockCache LruBlockCache + BucketCache 平衡场景

6.3 BlockCache配置 #

xml
<!-- hbase-site.xml -->

<!-- BlockCache大小比例 -->
<property>
    <name>hfile.block.cache.size</name>
    <value>0.4</value>
</property>

<!-- 启用BucketCache -->
<property>
    <name>hbase.bucketcache.ioengine</name>
    <value>offheap</value>
</property>

<!-- BucketCache大小 -->
<property>
    <name>hbase.bucketcache.size</name>
    <value>8192</value>  <!-- MB -->
</property>

七、数据读取路径 #

7.1 读取流程详解 #

text
┌─────────────────────────────────────────────────────────────────────┐
│                         数据读取路径                                 │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  读取请求                                                           │
│      │                                                              │
│      ▼                                                              │
│  ┌──────────────────────────────────────────────────────────────┐  │
│  │  1. 检查 BlockCache                                          │  │
│  │     ├── 命中 → 返回数据                                       │  │
│  │     └── 未命中 → 继续                                         │  │
│  └──────────────────────────────────────────────────────────────┘  │
│      │                                                              │
│      ▼                                                              │
│  ┌──────────────────────────────────────────────────────────────┐  │
│  │  2. 检查 MemStore                                             │  │
│  │     ├── 找到 → 返回数据                                       │  │
│  │     └── 未找到 → 继续                                         │  │
│  └──────────────────────────────────────────────────────────────┘  │
│      │                                                              │
│      ▼                                                              │
│  ┌──────────────────────────────────────────────────────────────┐  │
│  │  3. 检查 Bloom Filter                                         │  │
│  │     ├── 可能存在 → 继续                                       │  │
│  │     └── 不存在 → 跳过该HFile                                  │  │
│  └──────────────────────────────────────────────────────────────┘  │
│      │                                                              │
│      ▼                                                              │
│  ┌──────────────────────────────────────────────────────────────┐  │
│  │  4. 查询 HFile                                                │  │
│  │     ├── 使用索引定位Block                                     │  │
│  │     ├── 读取Data Block                                        │  │
│  │     └── 放入BlockCache                                        │  │
│  └──────────────────────────────────────────────────────────────┘  │
│      │                                                              │
│      ▼                                                              │
│  ┌──────────────────────────────────────────────────────────────┐  │
│  │  5. 合并结果                                                  │  │
│  │     └── 合并多个版本,返回最新数据                            │  │
│  └──────────────────────────────────────────────────────────────┘  │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

八、总结 #

本节介绍了HBase的数据存储模型:

组件 功能
LSM Tree 写入优化的数据结构基础
MemStore 内存写缓存,有序存储
HFile 磁盘存储格式,块结构
WAL 写前日志,保证数据安全
Compaction 合并文件,优化查询
BlockCache 读缓存,加速数据访问

下一步,让我们学习Region与RegionServer!

最后更新:2026-03-27