HBase读写流程
公共流程(三层索引)
- HBase中单表的数据量通常可以达到TB级或PB级,但大多数情况下数据读取可以做到毫秒级。
HBase是如何做到的呢?要想实现表中数据的快速访问,通用的做法是数据保持有序并尽可能的将
数据保存在内存里。HBase也是这样实现的。 - 对于海量级的数据,首先要解决存储的问题。数据存储上,HBase将表切分成小一点的数据单位
region,托管到RegionServer上,和以前关系数据库分区表类似。但比关系数据库分区、分库易
用。这一点在数据访问上,HBase对用户是透明的。数据表切分成多个Region,用户在访问数据
时,如何找到该条数据对应的region呢?
HBase 0.96以前
-
有两个特殊的表,-Root-和.Meta. ,用来查找各种表的region位置在哪里。-Root-和.Meta.也像
HBase中其他表一样会切分成多个region。-Root-表比.Meta更特殊一些,永远不会切分超过一个
region。-ROOT-表的region位置信息存放在Zookeeper中,通过Zookeeper可以找到-ROOT-
region托管的RegionServer。通过-ROOT-表就可以找到.META.表region位置。.META表中存放着
表切分region的信息。 -
当客户端访问一个表的时候,首先去询问Zookepper
- Zookepper会告诉客户端-root-Region所在的RegionServer
-
公共表.meta.
-
是一张普通表,但是由HBase自己维护
-
Key:
Region key的格式是:[table],[region start key],[region id]
Values:
info:regioninfo: 序列化的当前region的HRegionInfo实例。
info:server:存储这个region的regionserver的server:port
info:serverstartcode:该Regionserver拥用该region的起始时间 -
- | RowKey |info:regioninfo | info:server | info:serverstartcode
|
| ----------------- | --------------- | ----------- | --------------------
|
| student-201800-r1 | r1:info | rs03:16020 | s:201800 e:201899
|
| student-201900-r2 | r2:info | rs04:16020 | s:201900 e:201999
|
| student-202000-r3 | r3:info | rs05:16020 | s:202000 e:202099
|
| teacher-201800-r1 | r4:info | rs01:16020 | s:201800 e:201899
| - 假如我现在查询rowkey=student:201811
- 假设有3000张表,每张表3000个Region,于是.meta.有 900W条记录
- 但是:
- meta表数据量多的时候也会被切分成多个Region,位于多个RegionServer上
- 当我们询问Zookepper的时候,也会给我们多个数据让我们去找结果
- | RowKey |info:regioninfo | info:server | info:serverstartcode
-
-
公共表-root-
-
是一张普通的表,但是由HBase自己维护
-
Key:
Key的格式为:.META.,1
Values:
info:regioninfo: 序列化的hbase:meta表的HRegionInfo实例。
info:server:存储hbase:meta表的regionserver的server:port
info:serverstartcode:该Regionserver拥用hbase:meta表的起始时间 -
它的机构和meta一模一样,但是它只维护meta表的切分信息
-
理论上-root-表不会被切分(数据量)
-
RowKey info:regioninfo info:server info:serverstartcode .META.-student2018-ts s:201800 e:201899 score rs03 s:201800 e:201899 .META.-teacher2018-ts s:201900 e:201999 score rs04 s:201900 e:201999
-
-
查询流程
Client--------->zookeeper--------->-ROOT-(单region)----->.META.------------->用户表region
HBase 0.96以后
-
-ROOT-表被移除,直接将.Meta表region位置信息存放在Zookeeper中。Meta表更名为
hbase:meta -
查询流程
- Client--------->zookeeper-------->hbase:meta--------->用户表region
读取数据流程
- 01Client访问zookeeper,获取hbase:meta所在RegionServer的节点信息
- 02Client访问hbase:meta所在的RegionServer,获取hbase:meta记录的元数据后先加载到内存
中,然后再从内存中根据需要查询的RowKey查询出RowKey所在的Region的相关信息(Region所
在RegionServer) - 03Client访问RowKey所在Region对应的RegionServer,发起数据读取请求
- 04RegionServer构建RegionScanner(需要查询的RowKey分布在多少个Region中就需要构建多少
个RegionScanner),用于对该Region的数据检索 - 05RegionScanner构建StoreScanner(Region中有多少个Store就需要构建多少个StoreScanner,
Store的数量取决于Table的ColumnFamily的数量),用于对该列族的数据检索 - 06多个StoreScanner合并构建最小堆(已排序的完全二叉树)StoreHeap:PriorityQueue
- 07StoreScanner构建一个MemStoreScanner和一个或多个StoreFileScanner(数量取决于
StoreFile数量) - 08过滤掉某些能够确定所要查询的RowKey一定不在StoreFile内的对应的StoreFileScanner或
MemStoreScanner - 09经过筛选后留下的Scanner开始做读取数据的准备,将对应的StoreFile定位到满足的RowKey的
起始位置 - 10将所有的StoreFileScanner和MemStoreScanner合并构建最小堆
KeyValueHeap:PriorityQueue,排序的规则按照KeyValue从小到大排序 - 11从KeyValueHeap:PriorityQueue中经过一系列筛选后一行行的得到需要查询的KeyValue。
写入数据流程
-
首先客户端和RegionServer建立连接
-
然后将DML要做的操作写入到日志wal-log
-
然后将数据的修改更新到memstore中,然后本次操作结束
- 一个region由多个store组成,一个store对应一个CF(列族),store包括位于内存中的
memstore和位于磁盘的storefile,写操作先写入memstore.
- 一个region由多个store组成,一个store对应一个CF(列族),store包括位于内存中的
-
当memstore数据写到阈值之后,创建一个新的memstore
-
旧的memstore写成一个独立的storefile,regionserver会启动flashcache进程写入storefile,每次
写入形成单独的一个storefile,存放到hdfs -
当storefile文件的数量增长到一定阈值后,系统会进行合并(minor compaction、major
compaction) -
在合并过程中会进行版本合并和删除工作,形成更大的storefile
-
当一个region所有storefile的大小和数量超过一定阈值后,会把当前的region分割为两个,并由
hmaster分配到相应的regionserver服务器,实现负载均衡 -
Store负责管理当前列族的数据
- 1memstore+nstorefile
-
当我们进行数据DML的时候,以插入数据为例
- 我们会将数据先存储到memStore中,当memStore达到阈值(128M)
- 首先创建一个新的memstore
- 然后会将memStore中的数据写成一个storefile,storefile会存储到hdfs上(hfile)
-
随着时间的推移:
- HFile中会存放大量的失效数据(删除,修改)
- 会产生多个HFile
- 等达到阈值(时间、数量)会进行合并
- 多个HFile合并成一个大的HFile
- 合并会触发连锁反应,相邻的store也会进行合并
-
在Hbase中,表被分割成多个更小的块然后分散的存储在不同的服务器上,这些小块叫做
Regions,存放Regions的地方叫做RegionServer。Master进程负责处理不同的RegionServer之间
的Region的分发。在Hbase实现中HRegionServer和HRegion类代表RegionServer和Region。
HRegionServer除了包含一些HRegions之外,还处理两种类型的文件用于数据存储- HLog 预写日志文件,也叫做WAL(write-ahead log)
在Hbase实现中HRegionServer和HRegion类代表RegionServer和Region。
HRegionServer除了包含一些HRegions之外,还处理两种类型的文件用于数据存储 - HLog 预写日志文件,也叫做WAL(write-ahead log)
- HFile 是HDFS中真实存在的数据存储文件
- HLog 预写日志文件,也叫做WAL(write-ahead log)