文章目录
整体架构
Master
实现类为 HMaster。
负责监控集群中所有的 RegionServer 实例。
(1)管理元数据表格 hbase:meta,接收用户对表格创建修改删除的命令并执行
(2)监控 region 是否需要进行负载均衡,故障转移和 region 的拆分。
通过启动多个后台线程监控实现上述功能:
负载均衡器
周期性监控 region 分布在 regionServer 上面是否均衡,由参数 hbase.balancer.period 控 制周期时间,默认 5 分钟。
元数据管理器
定期检查和清理 hbase:meta 中的数据。
预写日志处理器
把 master 需要执行的任务记录到预写日志 WAL 中,如果 master 宕机,让 backupMaster 读取日志继续干。
Region Server
实现类为 HRegionServer,
(1)负责数据 cell 的处理,例如写入数据 put,查询数据 get 等
(2)拆分合并 region 的实际执行者,有 master 监控,有 regionServer 执行。
Zookeeper
进行 master 的高可用、记录 RegionServer 的部署信息、并且存储有 meta 表的位置信息。
HBase 对于数据的读写操作时直接访问 Zookeeper 的,在 2.3 版本推出 Master Registry 模式,客户端可以直接访问 master。
HDFS
为 Hbase 提供最终的底层数据存储服务,同时为 HBase 提供高容错的支持。
Master架构
Meta 表格
元数据表管理器 定期管理版本
hbase:meta,只是在 list 命令中被过滤掉了,本质上和 HBase 的其他表格一样。
RowKey:
([table],[region start key],[region id]) 即 表名,region 起始位置和 regionID。
列:
info:regioninfo 为 region 信息,存储一个 HRegionInfo 对象。
info:server 当前 region 所处的 RegionServer 信息,包含端口号。 info:
serverstartcode 当前 region 被分到 RegionServer 的起始时间。
如果一个表处于切分的过程中,即 region 切分,还会多出两列 info:splitA 和 info:splitB, 存储值也是 HRegionInfo 对象,拆分结束后,删除这两列。
注意:
在客户端对元数据进行操作的时候才会连接master。
如果对数据进行读写,直接连接 zookeeper 读取目录/hbase/meta-region-server 节点信息,会记录 meta 表格的位置。直接读 取即可,不需要访问 master,这样可以减轻 master 的压力,相当于 master 专注 meta 表的 写操作,客户端可直接读取 meta 表。
在 HBase 的 2.3 版本更新了一种新模式:Master Registry。客户端可以访问 master 来读取 meta 表信息。加大了 master 的压力,减轻了 zookeeper 的压力。
RegionServer 架构
MemStore
写缓存。
由于 HFile 中的数据要求是有序的,所以数据是先存储在 MemStore 中,排好序后,等到达刷写时机才会刷写到 HFile,每次刷写都会形成一个新的 HFile,写入到对应的 文件夹 store 中。一个写缓存对应一个store文件夹。
WAL
由于数据要经 MemStore 排序后才能刷写到 HFile,但把数据保存在内存中会有很高的概率导致数据丢失。
为了解决这个问题,数据会先写在一个叫做 Write-Ahead logfile 的文件 中,然后再写入 MemStore 中。所以在系统出现故障的时候,数据可以通过这个日志文件重建。
BlockCache
读缓存
每次查询出的数据会缓存在 BlockCache 中,方便下次查询。
读写流程
HFile结构
HFile 是存储在 HDFS 上面每一个 store 文件夹下实际存储数据的文件。
存储数据本身(keyValue 键值对)、元数据记录、文件信息、数据索引、元数据索引和 一个固定长度的尾部信息(记录文件的修改情况)。
键值对按照块大小(默认 64K)保存在文件中.
数据索引按照块创建,块越多,索引越 大。
每一个 HFile 会维护一个布隆过滤器(就像是一个很大的地图,文件中每有一种 key, 就在对应的位置标记,读取时可以大致判断要 get 的 key 是否存在 HFile 中)。大致是因为可能有哈希碰撞。
KeyValue 内容如下:
rowlength -----------→ key 的长度
row -----------------→ key 的值
columnfamilylength --→ 列族长度
columnfamily --------→ 列族
columnqualifier -----→ 列名
timestamp -----------→ 时间戳(默认系统时间)
keytype -------------→ Put
可通过 HBase 提供的命令来查看存 储在 HDFS 上面的 HFile 元数据内容。
bin/hbase hfile -m -f /hbase/data/命名空间/表名/regionID/列族/HFile 名
写流程
(1)首先访问 zookeeper,获取 hbase:meta 表位于哪个 Region Server;
(2)访问对应的 Region Server,获取 hbase:meta 表,将其缓存到连接中,作为连接属性 MetaCache,由于 Meta 表格具有一定的数据量,导致了创建连接比较慢;
之后使用创建的连接获取 Table,这是一个轻量级的连接,只有在第一次创建的时候会检查表格是否存在访问 RegionServer,之后在获取 Table 时不会访问 RegionServer;
(3)调用Table的put方法写入数据,此时还需要解析RowKey,对照缓存的MetaCache, 查看具体写入的位置有哪个 RegionServer;
(4)将数据顺序写入(追加)到 WAL,此处写入是直接落盘的,并设置专门的线程控制 WAL 预写日志的滚动(类似 Flume);
(5)根据写入命令的 RowKey 和 ColumnFamily 查看具体写入到哪个 MemStory,并且 在 MemStory 中排序;
(6)向客户端发送 ack;
(7 )等达到 MemStore 的刷写时机后,将数据刷写到对应的 store 中。
读操作
优先访问 Block Cache,查找是否之前读取过,并且可以读取 HFile 的索引信息和 布隆过滤器。
不管读缓存中是否已经有数据了(可能已经过期了),都需要再次读取写缓存和 store 中的文件。
最终将所有读取到的数据合并版本,按照 get 的要求返回即可。