HMaster是Hbase主服务的进程实例,HMaster负责监听Hbase集群所有的RegionServer实例,而且他还负责元数据的修改、与ZK,HDFS之间的交互,在一个分布式集群中,
HMaster
通常与NameNode
运行在同一个节点。HMaster可以实现高可用,但是在启动Hbase集群的时候,所有的节点都可能成公启动active的HMaster,集群之间是存在竞争关系的,一旦active的HMaster节点与ZK失去联系后,负责standby的Hmaster就会马上变成active,并且从ZK获取元数据的位置,然后维护整个集群的正常运行。
HMaster还给客户端暴露HMasterInterface
接口,用来进行元数据相关的操作,具体可以进行的操作类型级别有。
Admin.dsiableTable()
方法时,实际上就是调用Master的接口服务。实际上HMaster后台运行着2个重要的线程,LoadBalancer,CatalogJanitor
.
LoadBalancer会定时检查region的状态,假如一个regionserver挂掉之后,该regionserver管理的region此时都处于offline的状态,或者过渡区没有region的情况下,此时loadbalancer会将这些regions重新分配到其它可用的regionserver,从而均衡集群的负载。
LoadBalancer相关的配置可参考官网:Hbase负载均衡配置
Region-RegionServer上的分配,可以参考:region在regionserver上的分配
CatalogJanitor负责定期检查和清理元数据表hbase:meta
HMaster记录者核心的操作与集群的运行状态,例如:处理阻塞的服务、创建表以及其它的DDL操作,HMaster会将这些状态写入到相应的WAL file中,这些WAL files会被存储在MasterProcWALs
目录下面;
Master的WAL与RegionServer的 WAL不同,保留Master的WALs让我们能在Hmaster的Failures后能弹性的进行恢复,举个例子:当主Master在创建表的中途挂掉了,此时另外一个备用的Master就会接管之前Master的工作,从WAL中获取状态与命令信息,完成该表的创建;
所有的从Hbase-2.0.0开始,引入了
AssignmentManager
,Master的所有操作状态信息全部通过该组件写入MasterProcWAL,而不是像Hbase-1.x那样将WALs写入到Zookeeper中。
hbase.procedure.store.wal.periodic.roll.msec
hbase.procedure.store.wal.roll.threshold
hbase.procedure.store.wal.warn.threshold
默认 64
代表当WAL files的数量达到64个,HMaster的日志中会提示Warn信息
procedure WALs count=xx above the warning threshold 64. check running procedures to see if something is stuck.
hbase.procedure.store.wal.max.retries.before.roll
默认为3
将wal记录同步到底层存储HDFS的最大失败重试次数
unable to sync slots, retry=xx
hbase.procedure.store.wal.sync.failure.roll.max
HRegionServer是Hbase Region服务的进程实例,它的主要功能是服务和管理regions,通常在一个分布式集群中,RegionServer与DataNode运行在同一节点上。
HRegionServer也向外暴露相关的APIHRegionServerInterface
,主要职责如下:
Admin.majorCompact()
方法,实际上就是调用RegionServerInterface相关的服务。
在HRegionServer后台运行着大量的重要的线程实例。
主要负责region的split检查和minor compaction;
检查major compaction;
定时将写入到MemStore的数据刷写到StoreFile(HFile);
定时检查并滚动RegionServer的WAL;
协处理器是在Hbase-0.92的时候引入的,具体协处理器相关的的Blog可以参考:Hbase-Coprocessor。
虽然Hbase对Hadoop MapReduce作了有效的集成,但是如果是一些简单的操作,例如sum\count等简单聚合操作,如果将MR代码嵌入到每个RegionServer上执行,这种方式相比Hbase原生的高效scan性能,很明显牺牲太大。所以才引入了自定义的Coprocessor,通过Hbase协处理器,除了高效的并行计算,还可以实现二级索引、谓词下推
等功能。
系统协处理器
;表协处理器
为了给Hbase的协处理器行为提供足够的灵活性,Hbase框架提供了2个不同的扩展方面。
名称 | Observer | EndPoint |
---|---|---|
介绍 | 类似于常规数据库中的触发器 | 类似于存储过程的动态端点 |
从Hbase中读取数据的过程,其实不是直接从Hfile中读取,然后返回给Client,正确的步骤是
客户端尝试从MemStore中读取,如果没有,那么从BlockCache中读取,如果没有直接从HFIle中读取,从HFile中读取的结果不会直接返回给客户端,而是先缓存在BlockCache的内存中,然后客户端直接从BlockCache中读取对应的数据。
Hbase中提供了2种不同的BlockCache的实现
LruBlockCache属于原生的BlockCache,完全基于java heap内存,BucketCache是否开启是一个可选的操作,如果我们选择开启BucketCache,那么此时Hbase就开启了2层缓存系统,这里称为L1、L2,但是在Hbase-2.0.0的时候该术语已经被标识成过时,L1层直接指向一个LruBlockCache,L2层则指向一个堆外的BucketCache;当开启BucketCache时,所有从HFile种读取的的Data-Block全部缓存在BucketCache层,而MetaData-Block以及Index和Bloom-Block全部被缓存在LruBlockCache中
LruBlockCache与BucketCache这2层缓存的管理以及他们之间的block的移动往往是由CombinedBlockCache来决定。
除了BlockCache本身的实例之外,我们还可以通过配置的形式对BlockCache的不同option进行配置,来进行性能调优。
具体参考地址可以参考:org.apache.hadoop.hbase.io.hfile.CacheConfig
LruBlockCache属于LRU的高速缓存,能够被ColumnFamily以及scan所使用;该缓存实例实际上有3种不同的Block缓存优先级
In-Memory
,那么无论该Block的访问次数为多少,该Block的访问优先级都是最高的,同时也是驱逐时最后考虑的一部分;将一个ColumnFamily标记成in-memory
,可以使用
HColumnDescriptor.setInMemory(true);
或者
hbase(main):003:0> create 't', {NAME => 'f', IN_MEMORY => 'true'}
默认情况下,所有的Block都启用LruBlockCache块缓存,这意味着所有的读取Block都将进入LRU高速缓存,对于部分场景可能默认的配置能满足,但是通常需要通过进一步的调整才能获取更好的性能;
这里有一个很重要的概念,如何评估Hbase集群可用的缓存内存?通常可以使用以下方式进行评估。
number of region servers * heap size * hfile.block.cache.size * 0.99
通常情况下,你所读取的Block并不是BlockCache种的唯一的成员,这里有一些因素需要考虑进来:
Catalog-table
hbase:meta被强制缓存在BlockCache中,且优先级为in-memory
,所以很难被驱逐,它是BlockCache中的常客,通常hbase:meta的大小取决于Hbase数据库中region的数量,因为hbase:meta中存储粒度为region级别。
HFile Index
HFile存储在HDFS上,每个HFile都包含自身的多层Index,它保证Hbase不需要读取整个文件就能获取所需数据,这些索引的大小默认是64KB,对于大数据集群,每个Regionserver上有1GB的index数据是很平常的,尽管并非所有的index数据都会被缓存,因为LRU会驱逐未使用的索引Index数据。
Keys
BLOOM Filters
想要获取更多的使用考虑因素,请参考**LRU Usage**
可以参考 off-heap usage