我有一份工作,就像我所有的Hadoop工作一样,从我在Hadoop界面中看到的运行时,它总共有2个map任务。但是,这意味着它正在加载如此多的数据,以至于我得到了Java Heap Space错误。
我尝试在我的Hadoop集群中设置许多不同的conf属性,以使作业分成更多任务,但似乎没有任何效果。
我已尝试设置mapreduce.input.fileinputformat.split.maxsize
,mapred.max.split.size
,dfs.block.size
,但似乎没有任何效果。
我正在使用0.20.2-cdh3u6,并尝试使用cascading.jdbc运行作业 - 作业无法从数据库中读取数据。我认为这个问题可以通过增加分割数量来解决,但无法解决如何做到这一点!
请帮忙!疯了!
2013-07-23 09:12:15,747 FATAL org.apache.hadoop.mapred.Child: Error running child : java.lang.OutOfMemoryError: Java heap space
at com.mysql.jdbc.Buffer.<init>(Buffer.java:59)
at com.mysql.jdbc.MysqlIO.nextRow(MysqlIO.java:1477)
at com.mysql.jdbc.MysqlIO.readSingleRowSet(MysqlIO.java:2936)
at com.mysql.jdbc.MysqlIO.getResultSet(MysqlIO.java:477)
at com.mysql.jdbc.MysqlIO.readResultsForQueryOrUpdate(MysqlIO.java:2631)
at com.mysql.jdbc.MysqlIO.readAllResults(MysqlIO.java:1800)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2221)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2618)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2568)
at com.mysql.jdbc.StatementImpl.executeQuery(StatementImpl.java:1557)
at cascading.jdbc.db.DBInputFormat$DBRecordReader.<init>(DBInputFormat.java:97)
at cascading.jdbc.db.DBInputFormat.getRecordReader(DBInputFormat.java:376)
at cascading.tap.hadoop.MultiInputFormat$1.operate(MultiInputFormat.java:282)
at cascading.tap.hadoop.MultiInputFormat$1.operate(MultiInputFormat.java:277)
at cascading.util.Util.retry(Util.java:624)
at cascading.tap.hadoop.MultiInputFormat.getRecordReader(MultiInputFormat.java:276)
at org.apache.hadoop.mapred.MapTask.runOldMapper(MapTask.java:370)
at org.apache.hadoop.mapred.MapTask.run(MapTask.java:324)
at org.apache.hadoop.mapred.Child$4.run(Child.java:266)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.Subject.doAs(Subject.java:415)
at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1278)
at org.apache.hadoop.mapred.Child.main(Child.java:260)
答案 0 :(得分:1)
您应该查看内存管理的设置,例如io.sort.mb
或mapred.cluster.map.memory.mb
,因为堆空间错误通常是由于分配问题而不是映射编号。
如果要强制使用地图编号,则必须考虑某些值先于其他值使用。例如mapreduce.input.fileinputformat.split.maxsize
即使您将mapred.tasktracker.map.tasks.maximum
设置为较小的值,如果小则会生成大量的广告。
dfs.block.size
仅在生成的地图编号大于mapreduce.input.fileinputformat.split.maxsize
答案 1 :(得分:0)
我的工作是从表中读取数据,其中1,000行相当于大约1MB。这项特殊的工作是尝试阅读753,216个网址。原来每个任务进程的Java堆空间上限为200MB。正如Brugere在我的问题评论中指出的那样,我可以在mapred.child.java.opts
中设置mapred-site.xml
属性来控制堆空间(http://developer.yahoo.com/hadoop/tutorial/module7.html)。
我发现我还必须在配置文件中为此属性设置<final>true</final>
,否则将值重置为200MB(是否可能在代码中的某处重置?可能在cascading.jdbc中?)。
当我检测到它需要更大的堆空间时,我会考虑在设置作业时在我的代码中设置此堆空间属性,从而使一般的Hadoop配置设置使用默认的200MB。