高阶面试-hbase的整理

背景

冷热分离需要用到hbase,冷数据较多,需求:

  1. 存放上亿数据
  2. 支持简单的组合关键字查询
  3. 存放数据不需要变更

基本存储数据结构

HBase可以被看作是一个稀疏的多维度Map(映射),稀疏的、分布式、多维的Map,将行键(Row Key)、列族(Column Family)、列限定符(Column Qualifier)和时间戳(Timestamp)映射到一个值(Value)

数据模型

如下数据如何存储?表users,包含两个列族personal_infocontact_info

![[Pasted image 20240612235231.png]]

实际存储结构:

复制代码
Row Key: user1
    Column Family: personal_info
        Column Qualifier: name -> Value: Alice
        Column Qualifier: age -> Value: 30
    Column Family: contact_info
        Column Qualifier: email -> Value: alice@example.com
        Column Qualifier: phone -> Value: 123-456-7890

Row Key: user2
    Column Family: personal_info
        Column Qualifier: name -> Value: Bob
        Column Qualifier: age -> Value: 25
    Column Family: contact_info
        Column Qualifier: email -> Value: bob@example.com
        Column Qualifier: phone -> Value: 987-654-3210

每一个RowKey、TimeStamp以及Key-Value值就是一个Cell

  • 行键 (Row Key) : 唯一标识每一行数据,例如user1user2
  • 列族 (Column Family) : 数据按列族进行物理存储,例如personal_infocontact_info
  • 列限定符 (Column Qualifier) : 列族下的具体列,例如nameageemailphone
  • 时间戳 (Timestamp): 记录数据的版本,HBase支持多个版本的值,默认为服务器写入数据的时间。
  • 值 (Value) : 存储的实际数据,例如Alice30alice@example.com

ColumnFamily一开始就要定义好,类似于关系型数据库里面的列,属于schema,每个ColumnFamily可以灵活增加ColumnQualifier,ColumnQualifier不需要在创建表的时候定义

物理存储模型

根据RowKey的范围划分成多个Region

  1. 一个表会被水平切割成多个Region
  2. 一个Region会包含多个Row,包含startkey和endkey之间所有连续的行。每个Region的大小默认会控制在1GB内。每个表一开始只有二个 Region,随着数据不断插入到表中,Region 不断增大,当增大到一个阈值的时候,Region 就会等分为两个新的 Region
  3. 每个Region包含着多个Store对象。每个Store包含一个MemStore或若干StoreFile,StoreFile包含一个或多个HFile。MemStore存放在内存中,StoreFile存储在HDFS上
  4. 一个MemStore会存储一个ColumnFamily,一个MemStore会把数据写入多个HFile
  5. 一个RegionServer会服务多个Region

![[Pasted image 20240613081011.png]]

复制代码
Table: users

Region 1 (RowKey: user1 - user1000)
    |-- Store (Column Family: personal_info)
    |    |-- MemStore
    |    |-- HFile
    |
    |-- Store (Column Family: contact_info)
         |-- MemStore
         |-- HFile

Region 2 (RowKey: user1001 - user2000)
    |-- Store (Column Family: personal_info)
    |    |-- MemStore
    |    |-- HFile
    |
    |-- Store (Column Family: contact_info)
         |-- MemStore
         |-- HFile

分布式环境

Master 主要负责表 Region 的管理工作,包括分配 Region 给 Region Server,协调多个 Region Server,检测各个 Region Server 的状态,并平衡 Region Server 之间的负载。

Region Server 是 HBase 最核心的模块,包含多个 Region,负责维护 Master 分配给它的 Region 集合,并处理对这些 Region 的读写操作,Client 直接与 Region Server 连接,并经过通信获取 HBase 中的数据。Region Server 需要向 HDFS 写入数据。

Zookeeper 作用:

  1. 是 HBase Master 的高可用性(High Available,HA)解决方案,保证了至少有一个 HBase Master 处于运行状态。
  2. 负责 Region 和 Region Server 的注册,Master 就可以通过 Zookeeper 随时感知各个 Region Server 的工作状态

![[Pasted image 20240613081021.png]]

数据写入流程

  1. 写请求:客户端向HBase发送写请求。
  2. 具体client访问zk读取元数据,根据namespace、表名、rowkey找到数据对应region,访问region对应regionServer
  3. 写入WAL:数据首先写入WAL(WriteAheadLog),以确保数据不会因为RegionServer故障而丢失,每个regionServer都会维护一个WAL文件(也是基于HDFS),所有写操作现将变动添加到WAL文件末尾。
  4. 写入MemStore:数据被写入MemStore,当MemStore达到一定大小时,会触发一次flush操作。
  5. Flush到HFile:MemStore的数据被写入HFile,存储在HDFS上。
  6. Compaction:随着时间推移,HBase会执行合并操作(Compaction),将多个小的HFile合并成一个大的HFile,以提高读性能。

数据读取流程

  1. 查找MemStore:首先在MemStore中查找数据。
  2. 查找BlockCache:如果数据不在MemStore中,接下来在BlockCache中查找。
  3. 查找HFile:如果数据既不在MemStore也不在BlockCache中,则查找HFile。
  4. 返回数据:找到数据后,返回给客户端。如果在HFile中找到数据,则将数据块缓存到BlockCache中,以加快后续的读取操作

HFile的结构

数据块(Data Block)

复制代码
- 存储实际的数据,包含多个KeyValue对。
- 每个数据块都可以进行压缩,以减少存储空间和提高读写效率。
  • 索引块(Index Block)

    • 存储数据块的索引信息,用于加快数据查找。
    • HFile包含一个元索引块(Meta Index Block),指向索引块的位置。
  • 元数据块(Meta Block)

    • 存储额外的元数据信息,例如文件信息、统计信息等

      HDFS
      ├── DataNode 1
      │ ├── /hbase/data/default/users/region1/store1/hfile1
      │ ├── /hbase/data/default/users/region1/store2/hfile2
      │ └── ...
      ├── DataNode 2
      │ ├── /hbase/data/default/users/region2/store1/hfile3
      │ ├── /hbase/data/default/users/region2/store2/hfile4
      │ └── ...
      ├── DataNode 3
      │ ├── /hbase/data/default/users/region3/store1/hfile5
      │ ├── /hbase/data/default/users/region3/store2/hfile6
      │ └── ...
      └── ...

      HFile:
      ├── Data Block 1
      │ ├── KeyValue1
      │ ├── KeyValue2
      │ └── ...
      ├── Data Block 2
      │ ├── KeyValue3
      │ ├── KeyValue4
      │ └── ...
      ├── ...
      ├── Index Block
      │ ├── Index Entry 1
      │ ├── Index Entry 2
      │ └── ...
      └── Meta Block
      ├── Meta Entry 1
      ├── Meta Entry 2
      └── ...

表结构的设计

rowkey设计:
md5[cumstomeremail]+ticketId

columnFamily: ColumnFamily:i

为什么只整一个?

因为官方不推荐两个以上的columnFamily,原因:memstore刷新到HFile的动作叫flushing,flushing的操作是region级别,也就是只要有一个columnFamily满了就需要刷新,可能另外一个还很空,增加不必要的IO操作

ColumnKey: 剩余字段都设为i列簇下的Key

![[Pasted image 20240614080719.png]]

工单处理记录表,将处理记录转为json,保存在一个columnKey中

参考

https://www.cnblogs.com/zkteam/p/11877286.html

相关推荐
uhakadotcom1 天前
DuckDB相比于ClickHouse有什么不同点和优势?
后端·面试·github
一只修仙的猿1 天前
毕业三年后,我离职了
android·面试
加载中3611 天前
pnpm时代包版本不一致问题还是否存在
前端·面试·npm
学历真的很重要1 天前
Claude Code Windows 原生版安装指南
人工智能·windows·后端·语言模型·面试·go
yinke小琪1 天前
消息队列如何保证消息顺序性?从原理到代码手把手教你
java·后端·面试
007php0071 天前
某大厂MySQL面试之SQL注入触点发现与SQLMap测试
数据库·python·sql·mysql·面试·职场和发展·golang
kymjs张涛1 天前
零一开源|前沿技术周刊 #15
前端·javascript·面试
UrbanJazzerati1 天前
前端入门:vh、padding、margin、outline、pointer-events
前端·面试
沐怡旸1 天前
【底层机制】std::unordered_map 扩容机制
c++·面试
沐怡旸1 天前
【底层机制】auto 关键字的底层实现机制
c++·面试