`
lc_koven
  • 浏览: 349949 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

hbase中regionserver常见的oom原因分析

阅读更多
    首先要清楚reginserver中内存是如何使用的。

    reginserver中内存总体分成三部分:blocksize专供读使用的内存,memstore供读写使用的内存,其它内存。

    其中前两者的大小在配置中分别通过hfile.block.cache.size以及hbase.regionserver.global.memstore.upperLimit来控制,两者的大小之和被hbase硬编码为不可以大于等于0.8。所以如果发生了oom,那么一定是这里的其它内存使用过多造成的。

    其它内存包括哪些呢?最主要的部分是接收临时数据、flush时产生的snapshot,以及compact产生的内存等。以目前我的运维经验来看,大多数oom是发生在compact期间。所以当发生oom时,可以优先查看一下是否包含compact失败。

    compact的原理是将hdfs上原有的相应列数据按行读入内存,再写回hdfs。不幸的是有时候由于version或宽表的原因,导致某一个rowkey非常巨大,引起了内存消耗。此时,compact消耗的内存就由最大的rowkey来决定。

    另外,代码org.apache.hadoop.hbase.HTableDescriptor中有方法
public void setMaxFileSize(long maxFileSize)
,该方法比hbase.hregion.max.filesize优先级要高,所以代码里面如果进行了这个设置,会优先使用代码中的值。在发生oom的时候也要检查下代码中是否进行了该项设置。
1
0
分享到:
评论
9 楼 uestzengting 2011-12-09  
regionserver compact消耗的内存主要决于三个因素:
1.同一时间点regionserver上正在进行compact操作的region数
2.region一次compact过程中输入的storefile文件个数
3.一行kv记录本身的大小

控制好这三项,regionserver在compact的过程中才不会发生oom

第1项hbase本身有防范措施,就是在做major compact操作的时间间隔上不是一个固定值,默认是24小时的正负20%的时间范围内随机进行compact,这样可以避免同一时间点都有一批region都在做compact

第2项可以通过控制flush的效率来控制storfile的文件个数,文件个数越少越不容易溢出。

第3项就通过应用来控制了。
8 楼 杨俊华 2011-10-11  
lc_koven 写道
杨俊华 写道
是的。
compaction其实是是通过storefile的read将store file文件以stream形式读入,再合并的。所以,不是一下子加载到内存里面的。
所以,hbase.hregion.max.filesize 的大小不会影响内存的占用。
在《hbase definition》中,建议可以调大到1G。
调大filesize的大小,有助于减少region的数目,减低split的频率。

但是,filesize增大,对compact的影响,我认为主要在IO上,而且是网络IO。因为 storefile里面的文件是在hdfs上面。


己经修改了文章。
不过一般网络IO的影响会随着hdfs集群的扩大而减小,所以尽量使用更多的datanode节点吧。


datanode的数目 >= regionserver的数目。



7 楼 杨俊华 2011-10-11  
是的,很大的行的确是一个问题。
有可能一行就导致OOME。
这种情况就不仅仅在compaction.如果一行过大,客户端读取的时候,哪怕HBase不挂,客户端也会挂。
理论上要避免造成很大行的情况。在插入数据的时候就要有意避免。可以考虑不要放在一个行的多version,而是用不同的rowkey分割为多行。而多version仅仅给数据比较小得列使用。

HBase 0.90有一个 intrarow scan,可以解决客户端读取过大row OOME的问题。

https://issues.apache.org/jira/browse/HBASE-1537
To continue scaling numbers of columns or versions in a single row, we need a mechanism to scan within a row so we can return some columns at a time. Currently, an entire row must come back as one piece.

但是,依然无法解决compaction读过大行OOME的问题。

Very wide rows -- 30M plus -- cause us OOME
https://issues.apache.org/jira/browse/HBASE-3421
这个bug要到Hbase-0.90.5才fix。

但是还是建议不要存那么大得行。你读出来不费劲吗。
我们以前也遇到过,后来就让application自己想办法避免大行。

6 楼 lc_koven 2011-10-11  
AntyRao 写道
lc_koven 写道
AntyRao 写道
引用
    compact的原理是将hdfs上原有的相应列数据读入内存,然后在内存中做一次merge,再写回hdfs。compact消耗的内存是由hbase.hregion.max.filesize值决定的,这个值的意思是当某一个region的任何一列下的storefile总大小大于该值后,就会发生split,而split之后相应的compact的大小就降下去了。因此当hbase.hregion.max.filesize设置为256MB(默认值)时,内存中最多会申请512MB,调大这个值内存使用量会继续上升。


这一点不认同。

你好,你的意思是?


compaction过程,由于每个SSTable本身内部是排序的,这个compaction过程是一个merge-sort过程,
引用
compact的原理是将hdfs上原有的相应列数据读入内存,然后在内存中做一次merge

所以并不需要将数据都读入内存中来排序吧,只需要一定的缓存就可以了吧?


引用
compact消耗的内存是由hbase.hregion.max.filesize值决定的


compaction消耗的内存不是由hbase.hregion.max.filesize来决定的吧?IMHO,compaction消耗的内存与以下几方面有关:1)文件缓存的大小(HDFS层面上)2)compaction涉及到的文件数目吧。

谢谢!之前没有仔细看compact的代码。不过compaction消耗的内存也可能会很大,因为有时候用户会使用很多个version,这时会导致产生很大的row,读入内存就会发生oom了
5 楼 lc_koven 2011-10-11  
杨俊华 写道
是的。
compaction其实是是通过storefile的read将store file文件以stream形式读入,再合并的。所以,不是一下子加载到内存里面的。
所以,hbase.hregion.max.filesize 的大小不会影响内存的占用。
在《hbase definition》中,建议可以调大到1G。
调大filesize的大小,有助于减少region的数目,减低split的频率。

但是,filesize增大,对compact的影响,我认为主要在IO上,而且是网络IO。因为 storefile里面的文件是在hdfs上面。


己经修改了文章。
不过一般网络IO的影响会随着hdfs集群的扩大而减小,所以尽量使用更多的datanode节点吧。
4 楼 杨俊华 2011-10-11  
是的。
compaction其实是是通过storefile的read将store file文件以stream形式读入,再合并的。所以,不是一下子加载到内存里面的。
所以,hbase.hregion.max.filesize 的大小不会影响内存的占用。
在《hbase definition》中,建议可以调大到1G。
调大filesize的大小,有助于减少region的数目,减低split的频率。

但是,filesize增大,对compact的影响,我认为主要在IO上,而且是网络IO。因为 storefile里面的文件是在hdfs上面。

3 楼 AntyRao 2011-10-11  
lc_koven 写道
AntyRao 写道
引用
    compact的原理是将hdfs上原有的相应列数据读入内存,然后在内存中做一次merge,再写回hdfs。compact消耗的内存是由hbase.hregion.max.filesize值决定的,这个值的意思是当某一个region的任何一列下的storefile总大小大于该值后,就会发生split,而split之后相应的compact的大小就降下去了。因此当hbase.hregion.max.filesize设置为256MB(默认值)时,内存中最多会申请512MB,调大这个值内存使用量会继续上升。


这一点不认同。

你好,你的意思是?


compaction过程,由于每个SSTable本身内部是排序的,这个compaction过程是一个merge-sort过程,
引用
compact的原理是将hdfs上原有的相应列数据读入内存,然后在内存中做一次merge

所以并不需要将数据都读入内存中来排序吧,只需要一定的缓存就可以了吧?


引用
compact消耗的内存是由hbase.hregion.max.filesize值决定的


compaction消耗的内存不是由hbase.hregion.max.filesize来决定的吧?IMHO,compaction消耗的内存与以下几方面有关:1)文件缓存的大小(HDFS层面上)2)compaction涉及到的文件数目吧。
2 楼 lc_koven 2011-10-08  
AntyRao 写道
引用
    compact的原理是将hdfs上原有的相应列数据读入内存,然后在内存中做一次merge,再写回hdfs。compact消耗的内存是由hbase.hregion.max.filesize值决定的,这个值的意思是当某一个region的任何一列下的storefile总大小大于该值后,就会发生split,而split之后相应的compact的大小就降下去了。因此当hbase.hregion.max.filesize设置为256MB(默认值)时,内存中最多会申请512MB,调大这个值内存使用量会继续上升。


这一点不认同。

你好,你的意思是?
1 楼 AntyRao 2011-10-08  
引用
    compact的原理是将hdfs上原有的相应列数据读入内存,然后在内存中做一次merge,再写回hdfs。compact消耗的内存是由hbase.hregion.max.filesize值决定的,这个值的意思是当某一个region的任何一列下的storefile总大小大于该值后,就会发生split,而split之后相应的compact的大小就降下去了。因此当hbase.hregion.max.filesize设置为256MB(默认值)时,内存中最多会申请512MB,调大这个值内存使用量会继续上升。


这一点不认同。

相关推荐

Global site tag (gtag.js) - Google Analytics