简单搞定Spark性能优化:常见异常解决(三)
第一部分内容链接:https://blog.csdn.net/github_36444580/article/details/117037685die
第一部分内容链接:https://blog.csdn.net/github_36444580/article/details/117037685
第二部分内容链接:https://blog.csdn.net/github_36444580/article/details/117219963
25. ERROR:Recoverable Zookeeper: Zookeeper exists failed after 4 attempts baseZNode=/hbase Unable to set watcher on znode (/hbase/...)
原因:Spark任务连接不上HBase,如果不是任务中连接参数和属性等配置的有问题,就是HBase组件限制了连接并发数。
解决方法:可参考第23点的解决方法。
26. Parquet record is malformed: empty fields are illegal, the field should be ommited completely instead
原因:数据中有Map或Array数组,其中有key为null的元素。
解决方法:增加处理key为null数据的逻辑(如将key转换为随机数或干脆丢弃该条数据),或使用ORC格式。
27. Java.io.IOException: Could not read footer for file
原因:该报错分为两种情况:
(1)虽然建表时,该hive表元信息设置的是parquet格式,但是实际写入后,对应目录里面的文件并不是parquet格式的;
(2)读到的这个文件是个空文件。
解决方法:
(1)如果对应文件在HDFS上查看后发现不是parquet格式,可以重建对应格式的表并把文件移到新表对应目录下,或者正确修改代码配置重跑一次任务,从而删除文件覆盖写入;
(2)如果是空文件,可以直接删掉该文件。
28. com.mysql.jdbc.exceptions.jdbc4.CommunicationsException:Communications link failure
原因:查看报该错误的executor日志上发现有Full GC,Full GC会导致所有其他线程暂停,包括维持MySQL连接的线程,而MySQL在一段时间连接无响应后会关闭连接,造成连接失败。
解决方法:可参考第14点方法解决。
29. java.util.concurrent.TimeoutException: Futures timed out after [300 seconds]
原因:数据量比较大,但是各executor负载压力比较大,出现彼此通信超时的状况,有时候也会伴随“Executor heartbeat timed out after xxx ms”的内容。
解决方法:
(1)检查是否有数据倾斜情况,或者是否设置的并发度参数过小,可以根据具体业务量适当增大spark.default.parallelism与spark.sql.shuffle.partitions参数,两者的值设置为一样。
(2)查看报错位置的堆栈信息,如果有下图所示的broadcast join调用:
可以将spark.sql.autoBroadcastJoinThreshold参数设置的更小(数值以B为单位),或者关闭设为-1。
(3)经过代码优化和前面参数的调整,依然效果不佳,还可以尝试适当增大spark.network.timeout参数如600s,但不宜过大。
30. Error communicating with MapOutputTracker
原因:目前遇到的情况是NameNode主备切换导致的短时间服务不可用
解决方法:检查是否HDFS的NM正在主备切换状态,切换好后再次重跑任务即可。
31. org.apache.spark.shuffle.FetchFailedException: Connection from xxx closed
原因:数据量较大,过多block fetch操作导致shuffle server挂掉,还会伴随stage中task的失败和重试,对应task的executor上还会有如下的报错内容:“ ERROR shuffle-client-7-2 OneForOneBlockFetcher: Failed while starting block fetches”,或者“Unable to create executor due to Unable to register with external shuffle server due to : java.util.concurrent.TimeoutException: Timeout waiting for task.”。
解决方法:加上--conf spark.reducer.maxReqsInFlight=10和--conf spark.reducer.maxBlocksInFlightPerAddress=10参数(具体数值根据集群情况和业务量判断),来限制block fetch并发数。或者合入Spark3中的remote shuffle service源码特性。
32. Error in query: org.apache.hadoop.hive.ql.metadata.Table.ValidationFailureSemanticException:Partition spec {statis_date=,STATIS_DATE=xxx} contains non-partition column
原因:SparkSQL会把大写SQL语句变为小写,如果用hive建表时分区字段为大写,Spark读大写分区字段名后会报错。
解决方法:将hive表分区字段名改为小写,或者修改spark源码逻辑(AstBuilder.scala),自动将读到的大写分区字段名转为小写再处理。
33.Error: Could not find or load main class org.apache.spark.deploy.yarn.ApplicationMaster
原因:HDFS上未传Spark对应版本的包,Spark程序在客户端机器(安装有spark完整目录)上提交到集群后,集群计算机器上是没有装各计算组件的,而是从HDFS上下载该application需要的Spark jar包后再开始跑,如果HDFS上没有该spark目录,就会因未下到需要的jar包而报错。
解决方法:用hadoop fs -put命令将对应版本的Spark目录上传到HDFS上对应父目录下。
34.ERROR Driver ApplicationMaster: User class threw exception: org.apache.spark.sql.catalyst.analysis.NoSuchDatabaseException: Database 'xxx' not found
原因:有两种情况:
(1)建立SparkSession对象时没有加.enableHiveSupport();
(2)Spark2开始用SparkSession封装代替SparkContext作为Application程序的入口,只允许初始化一个SparkSession对象然后用sparkSession.sparkContext来获取SparkContext,如果没有初始化SparkSession对象,也只能初始化一个SparkContext对象。这里可能是重复初始化创建了多个SparkContext。
解决方法:
(1)在SparkSession对象初始化位置的.getOrCreate()之前加上.enableHiveSupport()。
(2)删除代码中其他SparkContext初始化语句,只通过sparkSession.sparkContext来获取SparkContext。
35.Caused by: java.lang.RuntimeException: Unsupported data type NullType.
原因:使用Parquet格式读写数据时,如果表中某一列的字段值全为null,用create table xxx using parquet as select ...语句建表时,全为null的那一列会被识别为void类型,就会报错,可以参考该链接:https://stackoverflow.com/questions/40194578/getting-java-lang-runtimeexception-unsupported-data-type-nulltype-when-turning。
解决方法:尽量避免一列全为null值,比如代码中加入空值检测逻辑,赋予随机值;如果业务上要求就是要这一列全为null,可以建表时使用using orc as或stored as orc as语句。
36.Failed to create local dir in /xxxx
原因:一般是磁盘满了或者磁盘损坏。
解决方法:联系管理者修复磁盘
37.Java.lang.IllegalArgumentException:…wholeTextFiles…CharBuffer.allocation…
原因:wholeTextFile不支持一次性读入大于1G的大文件,因为是将整个文件内容变成一个Text对象,而Text对象有长度限制。
解决方法:将单个大文件分割成多个小文件读取。
38.Total size of serialized results of 2000 tasks (2048MB) is bigger than spark.maxResultSize(1024.0 MB)
原因:各Executor上的各task返回给driver的数据量超过了默认限制。
解决方法:适当增大参数spark.driver.maxResultSize,且该参数要小于--driver-memory的值。
39.Caused by: java.util.concurrent.ExecutionException: java.lang.IndexOutOfBoundsException: Index: 0
原因:查询的Hive表中对应分区或HDFS目录下有空文件。
解决方法:加上参数set spark.sql.hive.convertMetastoreOrc=true;。
40.Caused by:java.io.NotSerializableException:org.apache.kafka.clients.producer.KafkaProducer
原因:KafkaProducer对象的初始化代码是在driver端执行的,driver会将相关代码对象序列化后发送给各executor,而KafkaProducer对象不支持序列化。
解决方法:将该对象的初始化代码从通过driver初始化的位置移到让executor初始化的位置,例如如果用了foreachPartition(),就可以将KafkaProducer对象的初始化代码移动到该函数内部,可参考该链接:https://stackoverflow.com/questions/40501046/spark-kafka-producer-serializable
41.Hive表某些列的数据错位,字段值显示异常,但SQL中select字段顺序正确
原因:使用HQL或SparkSQL建表时,使用的是create table xxx as select xxx语法而未加建表格式,默认会按读写性能和压缩效率最低的Text格式来建表,且可能会因数据本身的部分特殊内容导致行、列分隔符错位,从而出现列字段值错位异常的现象。
解决方法:建hive表时可使用ORC格式,该格式有编码机制防止内容像Text那样因分隔符等原因错位,同时压缩效率比Text、RCFile高,读写性能也更好:create table xxx stored as orc as select xxx
42.java.lang.IllegalArgumentException: Can't zip RDDs with unequal numbers of partitions
原因:
(1)代码中使用了zip()等函数,该函数的要求之一是两个RDD的partition个数相同,不相同时会报错。
(2)使用了参数spark.sql.join.preferSortMergeJoin=false开启了Shuffled Hash Join,该种join会先计算各字段值的哈希值并分发到各partition中,如果两个join的表中的数据量有较大差异,导致各字段值哈希计算后生成的partition数不同,也会报错。
解决方法:
(1)根据具体业务逻辑和数据情况,选择repartition()等其他函数实现对应逻辑,或对数据本身进行针对性的分区处理。
(2)去掉spark.sql.join.preferSortMergeJoin=false这个参数,依然使用SortMergeJoin。
更多推荐
所有评论(0)