本研究针对HBase 0.94.* 及以上版本的系统。
RegionServer
本目标主要集中分析在RegionServer提供的相关Metrics接口。在0.94新版本中,Metrics包括:RegionServerMetrics、JvmMetrics、以及RegionServerDynamicMetrics。下面分别进行介绍。
1、RegionServerMetrics
这是延续了以前版本的Metrics。它主要是以RegionServer为单位的基本功能的监控信息的收集,主要包括:
1)通用信息的收集。例如RS内store个数、storefiles的个数等。
2)与RS整体读写性能指标相关的参数。例如Cacheblock相关的信息、RS内读写请求个数、写操作相关的性能、以及读操作相关的性能。
3)功能性调整的参数个数。如Compaction、Split等。
下面细化这些参数的含义。(ps:参数名省略了前两位的hbase.regionserver.,例如如果blockCacheCount,那么Metrics上实际名字是hbase.regionserver.blockCacheCount)
- 与BlockCache相关的参数。
blockCacheCount | RegionServer中缓存到blockcache中block的个数。 | 如果有大规模的scan操作或者随机读比较频繁,该值往往偏高。 |
blockCacheFree | 返回block cache中空闲的内存大小。计算方法为:getMaxSize() – getCurrentSize(),单位是Byte | 该值反映出当前BlockCache中还有多少空间可以被利用。 |
blockCacheSize | 当前使用的blockCache的大小。BlockCache. getCurrentSize(),单位是Byte | 该值反映出BlockCache的使用状况。 |
blockCacheHitCount | 被BlockCache命中的getBlock操作。 | 该值反映出RegionServer上Region的访问特性。 |
blockCacheMissCount | BlockCache未命中的getBlock操作。 | 该值反映出RegionServer上Region的访问特性。 |
blockCacheEvictedCount | BlockCache中被换出的Block的个数。 | 该值反映出RegionServer上Region的访问特性。 |
blockCacheHitRatio | getBlock操作中命中缓存的百分比。 | 该值越高,对于读服务就更加高效。这是优化读服务的一种衡量标准。 |
blockCacheHitCachingRatio | hitCachingCount的含义是指那些因为读block不存在,而把block加入缓存时,会认为这是一次hitCaching操作(直接翻译:正在进行Caching,然后才命中)。 | 一般如果对于大表进行Scan操作,会造成该值升高。 |
blockCacheHitRatioPastNPeriods | 在过去的N个周期内平均的命中率。(默认的过去周期窗口个数是5) | 在CacheStats类中,会有PastN大小的数组,记录在N个周期内的hitCount大小。RegionServer每次取数据时,都会rollMetricsPeriod,从而记录当前hitCount到对应PastN的数组中。 |
blockCacheHitCachingRatioPastNPeriods | 在过去的N个周期内平均CachingBlock的命中率。(默认的过去周期的窗口为5) | 同上。 |
- 与hdfs本地性相关的参数。
hdfsBlocksLocalityIndex | 统计RegionServer所在机器的数据本地化的概率。 | HDFSBlocksDistribution用来计算RegionServer下的所有数据的分散度。 |
- 基本配置信息的相关参数
stores | RegionServer包含的Store的个数 | 每一个HRegion会根据ColumnFamily的个数设置同数目的Store,每个Store下有一个MemStore和若干个StoreFiles组成。因此,stores的个数其实是RegionServer的一种数据组织管理单元。 |
storefiles | RegionServer中所有的Storefiles的个数 | 如上,每一个Store会包含若干个StoreFiles,每个StoreFile是HFile结构。StoreFiles很多的RegionServer,在一定程度上可以反应出写操作频繁。 |
memstoreSize | RegionServer中所有HRegion中的memstore大小的总和 | 该值的变化,可以反应出一个RegionServer上写请求的负载状况。可以观察memstoreSize的变化率,如果在单位时间内变化比较抖动,可以近似认为Put操作频繁。 |
numPutsWithoutWAL | RegionServer中不写WAL(Write-Ahead-Log)的Put操作的个数 | 表示RegionServer中有多少次”不安全”的put操作。这里的不安全是指,如果Put操作只写入MemStore,而不执行Hlog.append操作。 |
dataInMemoryWithoutWAL | RegionServer中不写WAL的Put操作的数据在Memstore占用的空间 | 表示RegionServer中不安全的put操作占用的Memstore的大小,该值是具体的存储空间的大小。 |
readRequestsCount | RegionServer从启动到统计时刻期间内读请求的个数。 | 该值表示自从HRegionServer启动到目前为止所有Region的读请求的总和。如下操作会触发HRegion的读请求+1:
1)getClosestRowBefore:定位Row时用到,客户端上的HConnectionManager定位row到Region位置的过程。由于在HConnectionManager上有缓存, 因此不是所有的row定位Region的过程中,都需要执行这个操作。 2)getScanner:客户端段换取scanner实例的过程,会记录一次读请求 3)scanner执行一次next(list)操作,会记录一次读请求。ps:如果10000个数据,client的每次next取1,则调用next 10000次, readRequestCount +=10000 如果client 按照每次next取10000个数据,则只会记录一次读请求。 总结:readRequestCount与客户端读取数据的个数不等价,而且大部分情况下readRequestCount 远小于客户端读取数据个数 |
writeRequestCount | RegionServer从启动到统计时刻期间内写请求得个数。 | 该值表示自从HRegionServer启动到目前为止所有Region的写请求的总和。如下操作会触发HRegion的写请求的个数+1:
1) 单一Delete操作。写请求个数+1 2)单一Put操作。写请求个数+1 3)batchMutate操作。虽然大部分操作都是批量操作(多Row),但是每次批量操作只会记录一次写请求。 4)checkAndMutate操作。写操作+1,操作的范围是单Row。 5)append(Append)操作,Append是对于单行操作的聚集。只记录一次写操作。 6)incrementColumnValue操作。columnValue的必须是64bit long型值,每次操作记录写操作+2 7)bulkLoadHFiles操作。写请求的个数+1,与导入的hfile文件数无关。 总结:writeRequestCount与客户端写操作个数不完全等价,大部分情况下writeRequestCount远小于客户端写操作的个数(尤其批量写频繁的情况下)。 |
requestCount | RegionServer从启动到统计时刻期间内请求的总个数 | 该值不等于writeRequestCount + readRequestCount的和。它统计的操作是在HRegionServer对象上的操作,因此比HRegion的操作更靠近Client端,统计的内容有:1)getRegionInfo 获得HRegion的相关信息。 +1
2)getClosestRowBefore 帮助HConnectionManager定位row对应的Region位置。+1 3)get操作,单行读操作。 +1 4)exists()操作,单行操作,判断Get是否存在。+1 5)put操作,单行写操作。+1 6)put(List<Put>)操作,批量写操作。+ list.size() 7) checkAndMutate 操作,单行操作。 +1 8)openScanner操作,打开一个scanner。 +1 9)scanner next(nbrows)操作,从scanner读取nbrows行数据,+nbrows 10) close() 操作,RegionServer下线前的操作。+1 11)delete操作,单行操作。+1 12)delete(List<Delete>)操作,批量删除操作。+ list.size() 13) lockRow操作。HTable提供了对于单行的客户端加锁服务。+1 14)unlockRow操作。HTable提供了对于单行的客户端解锁服务。+1 15)mutateRow操作。单行复合操作。+1 16)append操作。单行操作 +1 17)increment操作。单行操作 +1 18) incrementColumnValue操作。单行操作 +1 19) Multi(MultiAction<R〉 multi) ,批量操作,大部分的ThriftServer调用的批量操作的入口函数。+multi.size() 20 )execCoprocessor, 执行一次Coprocessor,+1 21) getCompactionState,获取Region的compaction信息, +1 总结:requestCount在很大程度上反映了RegionServer的负载状况。如果对于该Count的值进行分解,按照功能可以分为如下几类:
|
这里 补充一下在hbase监控页面上看到的每个RegionServer的Request实时计算流程。
RegionServer会定期(hbase.regionserver.msginterval)执行操作,这主要包括:
1)更新RegionServerMetrics对象 。其中
this.metrics.incrementRequests(this.requestCount.get());
this.metrics.requests.intervalHeartBeat();RegionServerMetrics.requests 属于MetricsRate,也就是每次event时,会在累加count,然后等待执行一次intervalHeartBeat就会把计算在相近的连续两次ntervalHeartBeat之间的速度。request_between_interval/interval。
显然每次执行metrics时,regionserver就会更新这个值到Metrics上。
2)RegionServer向Master报告当前的负载信息 。
会创建成一个HServerLoad,其中有两个参数,一个是当前RegionServer上RegionRequest的个数,是在(hbase.regionserver.msginterval)期间内的所有的request个数,另外一个是metrics刚刚更新的requestCountRate。
其中第一个值用来做HMaster的统计使用,第二个值就是我们在页面上每次刷新看到的最新的request值。
3)RegionServer的RequestCount归零。
因此 ,从这个可以看出,如果在Table层次上做统计Table,需要细化到每一个Region的RequestCount,目前未开发的RegionServerMetrics还无法满足这种需求。总结一下,可以继续开发完善的点有 :
1) 按照读写操作区分requestCount的统计,实时掌握以RegionServer为监控对象的负载状况。
2)借助writeRequestCount和readRequestCount的值,在数据收集过程中,按照Table为单位重新整合。如果必要的话,需要对其收集数据的方式进行重算,保证每行的操作能够得到统计。这样可以实时统计每个Table的读写负载状况。(需要较大的开发量)
- 与HLog、HFile有关的Metrics
storefileIndexSizeMB | 在RegionServer内所有Store下对应的 StoreFile文件都会有一个Reader, 该Reader中包含了dataBlockIndexReader 和 metaBlockIndexReader两类
indexSize=dataBlockIndexReader.heapSize() + metaBlockIndexReader.heapSize() |
该值与HFile的数目以及大小有关,基本上是StoreFile数目越多,该值就会越大。因此,可以通过该值来推断出RegionServer上Store的规模来。 |
totalStaticIndexSize | HRegionServer上每个HFile文件的IndexSize的大小,这是指未压缩的,不带有其它信息的所有HFileBlockIndex信息的总和 。 | 该值是HFileBlock Index 的总大小,可以反映出RegionServer上HFileBlock的总规模。 |
rootIndexSizeKB | 内容与storefileIndexSizeMB等同 | |
totalStaticBloomSizeKB | 所有Store上的Bloom Filter大小的总和。 | 可以衡量Bloom Filter占用的存储资源状况。 |
fsWriteLatency | 当前每次写HLog操作的平均Latency | 可以反映出写数据的性能状况。 |
fsWriteSize | 当前每次写HLog操作的平均长度 | 可以结合参数numPutsWithoutWAL,如果numPutsWithoutWAL比较小的情况下,可以一定程度上反映出当前每行的大小。 |
fsSyncLatency | 当前HLog的sync操作的延迟状况 | 可以在一定程度上反映出HBase所依赖的HDFS 写数据的状态。如果出现过高,此时,监控系统应该给出报警信息。 |
slowHLogAppendTime | 该值反映出RS的Append Hlog操作超过1000ms的平均延迟情况 | 可以时刻掌握Append HLog性能异常点的状况,可以通过该值分析出,在哪些时间段内的Append Hlog操作的问题较多。 |
slowHLogAppendCount | 当前RS进行Append Hlog操作中,延迟超过1000ms的个数。 | 实时掌握节点内Append HLog插入异常的状况,如果在一定时间内,发现该值处于不断增长的状况,说明插入的数据有了新问题。 |
fsReadLatency | 当前RS进行的HFile读取操作的平均延迟。 | 可以实时掌握每一个时间点的延迟情况 |
fsPReadLatency | 同上,不同之处,这里统计的是PositionRead的平均延迟。与fsReadLatency是互斥的。 | 同上。 |
checksumFailuresCount | HFile进行checksum过程中出错次数。 | 可以检查HDFS读写数据异常或者网络状况的异常。 |
fsReadLatencyHistogram | 是一种概率统计fsReadLatency,例如99.9%的latency的大小是多少。 | 借助MetricsHistogram可以更好地分析Latency的状况。HBase性能分析中,可能受到outlier影响比较大,因此,统计大部分的操作的延迟更合理一些。 |
fsWriteLatencyHistogram | 同上,统计写延迟。 | 同上。 |
fsPreadLatencyHistogram | 同上,统计PostionRead的延迟。 | 同上。 |
- 功能性参数。
compactionTime | 平均执行一次Compaction的时间 | Compaction的性能会影响到读写数据性能。 |
compactionSize | 平均执行一次Compaction操作文件的大小 | 可以衡量出Compaction处理的数据量。 |
flushTime | 当前flush一次MemStore需要使用的时间。 | 衡量出MemStore到HFile的过程 |
flushSize | 当前flush一次需要的时间。 | 衡量出MemStore flush的大小。 |
regionSplitSuccessCount | Split成功的次数 | Split操作的状况。 |
regionSplitFailureCount | Split出错的次数 | Split操作的状况。 |
updatesBlockedMs | 因为MemStore不足需要进行Flush操作,而阻塞正常写操作的时间。 | 反映出因为阻塞式Flush而造成的写阻塞状况 |
updatesBlockedSecondsHighWater | 当前阻塞的时间积累。 | 相当于目前已经有多长时间的阻塞。 |
From Binospace, post HBase Metrics参数详解
文章的脚注信息由WordPress的wp-posturl插件自动生成