高阶面试-hbase的整理

发布于:2024-07-03 ⋅ 阅读:(13) ⋅ 点赞:(0)

背景

冷热分离需要用到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


网站公告

今日签到

点亮在社区的每一天
去签到