目录
HBase是如何做到表中数据量达到TB级或PB级时数据读取可以做到毫秒级
前言
HBase是如何做到表中数据量达到TB级或PB级时数据读取可以做到毫秒级
实现表中数据的快速访问,通用的做法是数据保持有序并尽可能的将数据保存在内存里。HBase也是这样实现的。
HBase面对于海量级的数据如何解决存储的问题
数据存储上, HBase将表切分成小一点的数据单位 region,托管到 RegionServer上,和以前关系数据库分区类似。但比关系数据库分区、分库易用。这一点在数据访问上,HBase 对用户是透明的。数据被切分成多个 Region。
用户在访问数据时是如何找到该条数据对应的 Region 呢
1、HBase 0.96 以前
HBase 0.96 版本以前,HBase内维护了两个特殊的表,-Root- 和 .Meta. ,用来查找各种表的 region 位置在哪。
-Root- 和 .Meta. 也像 HBase中其他表一样会切分成多个 region。 -Root- 表比 .Meta. 更特殊一些,永远不会切分超过一个 region。
-Root- 表的 region 位置信息存放在 Zookeeper 中,通过 Zookeeper 可以找到 -Root- region 托管的 RegionServer。
通过 -Root- 表就可以找到 .Meta. 表 region 位置。.Meta. 表中存放着表切分 region 的信息。
(1)当客户端访问一个表的时候,首先去咨询 Zookeeper
Zookeeper 会告诉客户端 -root-Region 所在的 RegionServer
(2)公共表 .meta.
是一张普通表,但是由 HBase 自己维护
(3)公共表 -root-
1、是一张普通的表,但是由 Hbase 自己维护。
2、它的机构和meta一模一样,但是它只维护meta表的切分信息
3、理论上-root-表不会被切分(数据量)
(4)查询流程
2、HBase 0.96以后
-ROOT- 表被移除,直接将 .Meta. 表 region 位置信息存放在 Zookeeper 中。Meta 表更名为 hbase:meta。
(1)查询流程
读取数据流程
-
Client 访问 zookeeper ,获取 hbase:meta 所在 RegionServer 的节点信息
-
Client 访问 hbase:meta 所在的 RegionServer,获取 hbase:meta 记录的元数据后先加载到内存中,然后再从内存中根据需要查询的 RowKey 查询出 RowKey 所在的 Region 的相关信息( Region 所在 RegionServer)
-
Client 访问 RowKey 所在 Region 对应的 RegionServer ,发起数据读取请求
-
RegionServer 构建 RegionScanner ( 需要查询的 RowKey 分布在多少个 Region 中就需要构建多少个 RegionScanner ),用于对该 Region 的数据检索
-
RegionScanner 构建 StoreScanner ( Region 中有多少个 Store 就需要构建多少个 StoreScanner,Store 的数量取决于 Table 的 ColumnFamily 的数量),用于对该列族的数据检索
-
多个 StoreScanner 合并构建最小堆(已排序的完全二叉树)StoreHeap:PriorityQueue
-
StoreScanner 构建一个 MemStoreScanner 和一个或多个 StoreFileScanner (数量取决于 StoreFile 数量)
-
过滤掉某些能够确定所要查询的 RowKey 一定不在 StoreFile 内的对应的StoreFileScanner 或 MemSotreScanner
-
经过筛选后留下的 Scanner 开始做读取数据的准备,将对应的 StoreFile 定位到满足的 RowKey 的起始位置
-
将所有的 StoreFileScanner 和 MemStoreScanner 合并构建最小堆 KeyValueHeap:PriorityQueue,排序的规则按照 KeyValue 从小到大
-
从 KeyValueHeap:PriorityQueue 中经过一系列筛选后一行行的得到需要检查的 KeyVlaue。
写入数据流程
-
首先客户端和 RegionServer 建立连接
-
然后将 DML 要做的操作写入日志 wal-log
-
然后将数据的修改更新到 memstore 中,然后本次操作结束
-
一个 region 由多个 store 组成,一个 store 对应一个 CF (列族),store 包括位于内存中的 memstore 和位于磁盘的 storefile ,写操作先写入 memstore。
-
-
当 memstore 数据写到阈值之后,创建一个新的 memstore
-
旧的 memstore 数据写成一个独立的 storefile,regionserver 会启动flashcache 进程写入 storefile,每次写入形成单独的 一个 storefile ,存放到 hdfs
-
当 storefile 文件的数量增长到一定阈值后,系统会进行合并 (minor compaction、major compaction)
-
在合并过程中会进行版本合并和删除工作,形成更大的 storefile
-
当一个 region 所有 storefile 的大小和数量超过一定阈值后,会把当前的 region 分隔为两个,并由 hmaster 分配到相应的 regionserver 服务器,实现负载均衡
-
Store 负责管理当前列族的数据
-
当我们进行数据 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 和 RegionServer 除了包含一些 HRegions之外,还处理两种类型的文件用于数据存储。
-
HLog 预写日志文件,也叫做 WAL(write-ahead log)
-
HFile 是 HDFS 真实存在的数据存储文件
-
底线。。。