hbase regionserver挂掉报错has too many store files delaying flush up to 90000ms

今天在使用datax同步数据到hbase的时候,随着同步的数据越来越多,发现同步的速度越来越慢,且慢慢的出现同步数据为0的情况,以及regionserver间歇性挂掉,最后完全挂掉了。

首先说一下,使用的hbase是单节点的,自己用来测试的。没有做过多的配置。

hbase的表只设置了一个列族,列数不到30列。机器内存16G。

当数据写到500万之后,开始变慢。最后写到800万regionserver崩溃。

2020-05-25 10:31:53,453 INFO  [RpcServer.default.FPBQ.Fifo.handler=29,queue=2,port=16020] regionserver.HRegion: writing data to region trans014744559352592,1590373894580.120ac4998d1fe3f32ca7aa15b39cc231. with WAL disabled. Data may be lost in the event of a crash.

 2020-05-25 10:32:01,013 WARN  [MemStoreFlusher.1] regionserver.MemStoreFlusher: 120ac4998d1fe3f32ca7aa15b39cc231 has too many store files(17000 ms
2020-05-25 10:32:02,705 INFO  [JvmPauseMonitor] util.JvmPauseMonitor: Detected pause in JVM or host machine (eg GC): pause of approximately
GC pool 'ParNew' had collection(s): count=1 time=43ms

 2020-05-25 10:33:58,204 WARN  [regionserver/xxx:16020] compactions.CompactionProgress: totalCompactingKVs=10657607 less tha3712
2020-05-25 10:34:01,230 WARN  [regionserver/xxx:16020] compactions.CompactionProgress: totalCompactingKVs=10657607 less tha7289
2020-05-25 10:34:04,388 WARN  [regionserver/xxx:16020] compactions.CompactionProgress: totalCompactingKVs=10657607 less tha2330
2020-05-25 10:34:07,689 WARN  [regionserver/xxx:16020] compactions.CompactionProgress: totalCompactingKVs=10657607 less tha7035

看资料,说是flush,导致store file数量过多,来不及compact,进而导致写阻塞。。。

之前对这几个原理有一些模棱两可,现在整理一下。

flush刷写

如果一个region有n个列族,那么就对应有n个store,每个store都有一个memstore和若干个storefile(memstore每flush一次就生成一个storefile持久化到hdfs磁盘)。

默认情况下,memstore有三种触发flush的机制:

  1. 刷写的最小单元是region,一个region中如果某个memstore占用的内存达到刷写阙值hbase.hregion.memstore.flush.size(默认128M)时就会触发此region下所有memstore的刷写。
  2. 除此之外,当一个regionserver下所有的memstore占用的内存总和达到hbase.regionserver.global.memstore.upperLimit设定的值时,会触发当前regionserver下所有region的所有memstore刷写。刷写顺序按照各个region的MemStore的大小降序刷写的,就是先刷写memstore大的region。直到全局的memstore低于hbase.regionserver.global.memstore.lowerLimit时,结束刷写。
  3. 或者是当一个regionserver的预写日志WAL的数量达到hbase.regionserver.max.logs指定的值时,也会触发当前regionserver下所有region的所有memstore刷写。这种方式的刷写顺序是按照时间升序进行的,也就是memstore越老的region,先刷写,直到WAL数量小于hbase.regionserver.max.logs时结束刷写。

根据第一条flush机制可知,如果没有预分区,且只有一个列族的时候,所有的数据都会往一个memstore中写,导致memstore迅速增大,导致频繁flush。

 

 

compact合并

随着数据的不断增加,一个store下的storefile会越来越多。为了提高读性能,需要将众多的小storefile进行compact合并。但是compact是资源密集型的操作,可以在很多方面影响性能(可能提高性能,也可能降低性能)。 

compact的触发条件也有多个,其中一个是当storefile数量至少达到3个时才可以进行一次小合并。

因此,在频繁flush时,必然对应频繁的compact。

当写请求非常多,导致不断生成HFile,但compact的速度远远跟不上HFile生成的速度,这样就会使HFile的数量会越来越多,导致读性能急剧下降。为了避免这种情况,在HFile的数量过多的时候会限制写请求的速度:在每次执行MemStore flush的操作前,如果HStore的HFile数超过hbase.hstore.blockingStoreFiles (默认7),则会阻塞flush操作hbase.hstore.blockingWaitTime时间,在这段时间内,如果compact操作使得HStore文件数下降到回这个值,则停止阻塞。另外阻塞超过时间后,也会恢复执行flush操作。这样做就可以有效地控制大量写请求的速度,但同时这也是影响写请求速度的主要原因之一。

参考:

https://blog.csdn.net/zyc88888/article/details/79666846

split切分

当一个region下的storefile达到一定阙值时,就会对此region进行split切分成两个region。

split是为了对region进行负载均衡到多个regionserver。

split的触发机制有多种,2.x版本采用的切分策略是SteppingSplitPolicy

SteppingSplitPolicy策略

当region的最大一个store达到一个阈值时触发split,不过这个阈值不是固定的,而是根据regionServer管理的同属一张表的region个数有关:

  1. region个数为1时,maxFilesize = flushSize * 2
  2. region个数为0或者大于100:maxFilesize的选取为hbase.hregion.max.filesize设置的值(默认10G)
  3. region个数在2~100之间:有一个initialSize,这个值由hbase.incresing.policy.initial.size配置;若没有配置这个值,则initialSize = 2 * MEMSTORE_FLUSHSIZE(table元数据);若table没有元数据或initialSize小于0,则initialSize = 2 * hbase.hregion.memstore.flush.size(默认128M)。拿到initialSize后,maxFilesize = min (initialSize * region个数的3次方, 10G)。

根据默认的split策略规则可以看到,如果没有设置预分区,那么一开始region的数量从1开始split,且会频繁split(因为maxFilesize = min (initialSize * region个数的3次方, 10G))。

 

具体可以看下面的第二个参考博客。

参考:

https://www.jianshu.com/p/53459997c814

https://www.cnblogs.com/cnblogs-syui/p/12566642.html

通过重新理解上面几个概念,可以大概知道,出现这个报错是因为持续往一个region写数据,导致频繁flush,频繁compact。而compact是比较重的操作,会写阻塞,同时compact是将待合并的hfile锁定后复制合并成一个新的hfile,然后删除旧的。所以这个过程会有大量的磁盘io,十分影响性能。

解决办法是预分区,避免大量的数据都在一个region下,导致compact的数据量过大,影响性能。

具体优化参数可以参考上述博客。
 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值