Q: Spark 作业报错 "Container killed by YARN for exceeding memory limits." 或者 MapReduce 作业报错 "Container is running beyond physical memory limits."

A:App 提交时申请的内存量较低,但 JVM 启动占用了更多的内存,超过了自身的申请量,导致被 NodeManager kill;特别是 Spark 类型作业,可能会占用较多的堆外内存,很容易被 kill。对于 Spark 作业,尝试提高 spark.yarn.driver.memoryOverheadspark.yarn.executor.memoryOverhead;对于MapReduce 作业,尝试提高 mapreduce.map.memory.mbmapreduce.reduce.memory.mb

Q: "Error: Java heap space"

A: 作业 Task 处理的数据量较大,但同时 Task JVM 申请的内存量不足,JVM 内存不足从而抛出 OutOfMemoryError。对于 Tez 作业,尝试提高 Hive 参数 hive.tez.java.opts;对于 Spark 作业,尝试提高 spark.executor.memoryspark.driver.memory;对于 MapReduce 作业,尝试提高 mapreduce.map.java.opts或mapreduce.reduce.java.opts

Q: "No space left on device"

A: Master 或 Worker 节点空间不足,导致作业失败。同时磁盘空间满也会导致本地 Hive 元数据库(MySQL Server)异常,Hive Metastore 连接报错。建议清理 Master 节点磁盘空间,特别是系统盘的空间,清理 HDFS 空间。

Q: 访问 OSS 或 LogService 报错 ConnectTimeoutException 或者 ConnectionException

A: OSS endpoint 配置为公网地址,但 EMR worker 节点并无公网 IP,所以无法访问。一个典型的场景是 Hive SQL:select * from tbl limit 10 可以正常运行,但是Hive SQL: select count(1) from tbl 报错。

将OSS endpoint 地址修改为内网地址,比如 oss-cn-hangzhou-internal.aliyuncs.com 等。或者使用 EMR metaservice 功能,不用指定 endpoint。
alter table tbl set location "oss://bucket.oss-cn-hangzhou-internal.aliyuncs.com/xxx"
alter table tbl partition (pt = 'xxxx-xx-xx') set location "oss://bucket.oss-cn-hangzhou-internal.aliyuncs.com/xxx"

Q: 读取 Snappy 文件时报错 OutOfMemoryError

A: LogService 等服务写入的标准 Snappy 文件和 Hadoop 的 Snappy 文件格式不同,EMR 默认处理的是 Hadoop 修改过的 Snappy 格式,处理标准格式时会抛出 OutOfMemoryError。对于 Hive 配置set io.compression.codec.snappy.native=true;对于 MapReduce 配置-Dio.compression.codec.snappy.native=true;对于 Spark 作业配置spark.hadoop.io.compression.codec.snappy.native=true

Q: 访问 RDS 时报错 Invalid authorization specification, message from server: “ip not in whitelist or in blacklist, client ip is xxx”

A: EMR 集群访问 RDS 需要设置白名单,如果没有配置集群各节点的 IP 到白名单,特别是扩容后忘记添加新增加节点的 IP 到白名单,会出现访问 RDS 出错。

Q:"Exception in thread main java.lang.RuntimeException: java.lang.ClassNotFoundException: Class com.aliyun.fs.oss.nat.NativeOssFileSystem not found”

A:在 Spark 作业中读写 OSS 数据时,需要将 E-MapReduce 提供的 SDK 打进作业 jar 包中,具体操作请参考:准备工作

Q:Spark 接 Flume 时出现内存超用问题

A:检查是否是以 Push-based 方式接收数据,若不是,请尝试改成 Push-based 方式接收数据。参考文档

Q:"Caused by: java.io.IOException: Input stream cannot be reset as 5242880 bytes have been written, exceeding the available buffer size of 524288"

A:(OSS)网络连接重试时缓存不足的 BUG,请使用 1.1.0 版本以上的 emr-sdk。

Q:"Failed to access metastore. This class should not accessed in runtime.org.apache.hadoop.hive.ql.metadata.HiveException: java.lang.RuntimeException: Unable to instantiate org.apache.hadoop.hive.ql.metadata.SessionHiveMetaStoreClient"

A:首先,Spark 处理 Hive 数据需要作业的执行模式为 yarn-client(local 也行),不能为yarn-cluster,否则会报上述异常。其次,作业 jar 中引入一些第三方的包也有可能导致 Spark 运行期间报上述异常。

Q:Spark 程序中使用 OSS SDK 出现 "java.lang.NoSuchMethodError:org.apache.http.conn.ssl.SSLConnetionSocketFactory.init(Ljavax/net/ssl/SSLContext;Ljavax/net/ssl/HostnameVerifier)"

A:OSS SDK依赖的 http-core 和 http-client 包与 Spark 和 Hadoop 的运行环境存在版本依赖冲突,不建议在代码中使用 OSS SDK,否则需要手动解决依赖冲突问题,比较麻烦。如果有需要对 OSS 中的文件做一些基础操作例如 list 等等,可以参照这里的用法进行操作。

Q:"java.lang.IllegalArgumentException: Wrong FS: oss://xxxxx, expected: hdfs://ip:9000"

A: 因为在操作 OSS 数据的时候,使用 HDFS 的默认的 fs,所以在初始化的时候,要使用 OSS 的路径来初始化fs,这样在后续的操作中,才能使用这个 fs 来操作 OSS 源上的数据。
Path outputPath = new Path(EMapReduceOSSUtil.buildOSSCompleteUri("oss://bucket/path", conf));        org.apache.hadoop.fs.FileSystem fs = org.apache.hadoop.fs.FileSystem.get(outputPath.toUri(), conf);        
if (fs.exists(outputPath)) {
  fs.delete(outputPath, true);        
}

Q: 作业长时间 GC 导致作业运行较慢

A: 作业的 JVM heap size 设置过小,可能会引起长时间的 GC,影响作业性能。建议提升 Java Heap Size,对于 Tez,尝试提高 Hive 参数 hive.tez.java.opts;对于 Spark,尝试提高 spark.executor.memoryspark.driver.memory;对于 MapReduce,尝试提高 mapreduce.map.java.opts或mapreduce.reduce.java.opts

Q: AppMaster 调度启动 Task 的时间过长

A: 作业 Task 数目过多(或 Spark Executor 数目过多),AppMaster 调度启动 Task 的时间过长,单个 Task 运行时间较短,作业调度的 overhead 较大。建议减少 Task 数目,使用 CombinedInputFormat;或者提高前序作业产出数据的 block size(dfs.blocksize);或者提高 mapreduce.input.fileinputformat.split.maxsize;对于 Spark 作业,减少 executor 数目(spark.executor.instances)或者降低并发数(spark.default.parallelism

Q: 资源申请时间较长,导致作业等待

A: 作业提交之后,AppMaster 需要申请资源启动 Task,在这个过程中如果集群比较繁忙,资源申请时间较长,导致作业等待。建议检查资源组配置配置是否合理,是否当前资源组较为繁忙,但集群整体资源还有富余。在这种情况下,可以适当提高关键资源组的资源占比。或者扩容集群

Q: 一小部分 Task 执行时间超长,作业整体运行时间变长(数据倾斜)

A: 作业的某个 stage 中 Task 数据分布不均衡,导致大部分 Task 很快执行完成,一小部分 Task 因为数据量过大,执行时间超长,作业整体运行时间变长。建议使用 Hive 的 mapjoin 并设置set hive.optimize.skewjoin = true

Q: 失败的 Task attempt 导致作业运行时间变长

A: 一个作业有失败的 Task attempt 或失败的 Job attempt,虽然作业可能正常结束,但失败的 attempt 延长了作业运行时间。建议寻找 Task 失败的原因,做针对性的优化,减少作业运行时间;失败原因可以参考本页其他常见问题。

Q: Spark作业报错 "java.lang.IllegalArgumentException: Size exceeds Integer.MAX_VALUE"

A: 在 shuffle 时,partition 数量过少使得一个 block size 过大,超过最大值 Integer.MAX_VALUE(2 G)。您可以尝试增大 partition 数目,增大 spark.default.parallelismspark.sql.shuffle.partitions 或者在 shuffle 前执行repartition。