首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Hadoop CDH5中的垃圾收集持续时间

Hadoop CDH5中的垃圾收集持续时间
EN

Stack Overflow用户
提问于 2014-07-03 14:27:18
回答 1查看 5.6K关注 0票数 4

我们有一个运行CDH5.0.2的四数据集,通过Cloudera包安装。为了将1300万用户的行导入HBase,我们编写了一个简单的Python脚本,并使用hadoop流jar。它可以像预期的那样工作,最多可达100 K行。然后..。然后,一个接一个地,所有的datanodes都会以相同的消息崩溃:

代码语言:javascript
运行
复制
The health test result for REGION_SERVER_GC_DURATION  has become bad: 
Average time spent in garbage collection was 44.8 second(s) (74.60%) 
per minute over the previous 5 minute(s). 
Critical threshold: 60.00%.

任何试图按照网络上的建议(例如[1][2][3])来解决这个问题的尝试,都不会带来任何接近解决方案的结果。“播放”java堆大小是无用的。唯一“解决”这种情况的办法是将区域服务器的垃圾收集持续时间从5‘延长到50’。可以说是一种肮脏的解决办法。

我们现在没有劳动力为我们的GC使用创建一个监视器。我们最终会的,但我想知道如何可能将1300万行导入HBase,从而导致所有区域服务器的崩溃。有干净的解决办法吗?

编辑:

Datanodes上的JVM选项是:

-XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:-CMSConcurrentMTEnabled -XX:CMSInitiatingOccupancyFraction=70 -XX:+CMSParallelRemarkEnabled

Datanodes是运行CentOS 6.5的物理机器,每台机器都有32 at和2 2GHz带30 at高速缓存的1 1Quadcore。

下面是我们运行的Python脚本的摘录。我们填充两个表:一个表具有唯一的用户ID作为行键,一个列家族包含用户的信息,另一个表包含我们可能希望作为行键访问的所有信息。

代码语言:javascript
运行
复制
#!/usr/bin/env python2.7
import sys
import happybase
import json
connection = happybase.Connection(host=master_ip)
hbase_main_table = connection.table('users_table')
hbase_index_table = connection.table('users_index_table')
header = ['ID', 'COL1', 'COL2', 'COL3', 'COL4']
for line in sys.stdin:
    l = line.replace('"','').strip("\n").split("\t")
    if l[header.index("ID")] == "ID":
        #you are reading the header
        continue
    for h in header[1:]:
        try:
            id = str(l[header.index("ID")])
            col = 'info:' + h.lower()
            val = l[header.index(h)].strip()
            hbase_table.put(id_au_bytes, {
                    col: val
                    })
            indexed = ['COL3', 'COL4']
            for typ in indexed:
               idx = l[header.index(typ)].strip()
               if len(idx) == 0:
                   continue
               row = hbase_index_table.row(idx)
               old_ids = row.get('d:s')
               if old_ids is not None:
                   ids = json.dumps(list(set(json.loads(old_ids)).union([id_au])))
               else:
                   ids = json.dumps([id_au])
               hbase_index.put(idx, {
                       'd:s': ids,
                       'd:t': typ,
                       'd:b': 'ame'
                       })
       except:
           msg = 'ERROR '+str(l[header.index("ID")])
           logging.info(msg, exc_info=True)
EN

回答 1

Stack Overflow用户

发布于 2015-01-16 16:12:33

最近很多人遇到的主要问题之一是,java应用程序可用的RAM数量已经激增,但是关于调整Java的大部分信息都是基于32位时代的经验。

最近,为了避免可怕的“长暂停”,我花了大量的时间研究GC的大型堆情况。我看了几次这个出色的演讲,最后GC和我所面临的问题开始变得更有意义了。

我对Hadoop不太了解,但我认为你可能会遇到年轻一代太小的情况。遗憾的是,关于JVM GC调优的大多数信息都没有强调您的对象最好的位置是在年轻一代中。从字面上说,在这一点上收集垃圾完全不需要时间。我不会讲细节(如果你想知道的话,看演示稿),但会发生的是,如果你的年轻一代(新一代)没有足够的空间,它就会过早地被填满。这会强制集合,一些对象将被移动到永久(旧)代中。最后,终身的一代填补了,它将需要收集。如果你有很多垃圾在你的终身代,这可能是非常慢,因为终身收集算法通常是标记扫描,这是一个非零的时间收集垃圾。

我想你在使用Hotspot。以下是针对hotspot的各种GC参数的很好的参考。JVM GC选项

我首先要大大增加年轻一代的人数。我在这里的假设是,许多短期到中等寿命的对象正在被创建。你想要避免的是让这些被提升到终身代。你这样做的方式是延长他们在年轻一代身上的时间。要做到这一点,您可以增加它的大小(因此需要更长的时间来填充),也可以增加延长的阈值(实质上是对象将保留的年轻集合的数量)。延长门槛值的问题是,在年轻一代中,移动对象需要时间。在记忆方面,增加年轻一代的规模是没有效率的,但我猜你还有很多可省的。

我在缓存服务器时使用了这个解决方案,并且在> 100 ms范围内有少量的集合,并且很少(每天少于一次)主要的集合通常在0.5s以下,堆在4GB左右。我们的对象可以活5分钟、15分钟或29天。

您可能需要考虑的另一件事是G1 (垃圾优先)收集器,它最近被添加到HotSpot中(相对地说)。

我对这个建议对你有多好感兴趣。祝好运。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24556461

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档