搭建Spark所遇过的坑
作者:花弄影
一.经验
- Spark Streaming包含三种计算模式:nonstate .stateful .window
- kafka可通过配置文件使用自带的zookeeper集群
- Spark一切操作归根结底是对RDD的操作
- 部署Spark任务,不用拷贝整个架包,只需拷贝被修改的文件,然后在目标服务器上编译打包。
- kafka的log.dirs不要设置成/tmp下的目录,貌似tmp目录有文件数和磁盘容量限制
- ES的分片类似kafka的partition
- spark Graph根据边集合构建图,顶点集合只是指定图中哪些顶点有效
- presto集群没必要采用on yarn模式,因为hadoop依赖HDFS,如果部分机器磁盘很小,hadoop会很尴尬,而presto是纯内存计算,不依赖磁盘,独立安装可以跨越多个集群,可以说有内存的地方就可以有presto
- presto进程一旦启动,JVM server会一直占用内存
- 如果maven下载很慢,很可能是被天朝的GFW墙了,可以在maven安装目录的setting.conf配置文件mirrors标签下加入国内镜像抵制**党的网络封锁,例如:
-
<mirror> <id>nexus-aliyun</id> <mirrorOf>*</mirrorOf> <name>Nexus aliyun</name> <url>http://maven.aliyun.com/nexus/content/groups/public</url> </mirror>
- 编译spark,hive on spark就不要加-Phive参数,若需sparkSQL支持hive语法则要加-Phive参数
- 通过hive源文件pom.xml查看适配的spark版本,只要打版本保持一致就行,例如spark1.6.0和1.6.2都能匹配
- 打开Hive命令行客户端,观察输出日志是否有打印“SLF4J: Found binding in [jar:file:/work/poa/hive-2.1.0-bin/lib/spark-assembly-1.6.2-hadoop2.6.0.jar!/org/slf4j/impl/StaticLoggerBinder.class]”来判断hive有没有绑定spark
- kafka的comsumer groupID对于spark direct streaming无效
- shuffle write就是在一个stage结束计算之后,为了下一个stage可以执行shuffle类的算子,而将每个task处理的数据按key进行分类,将相同key都写入同一个磁盘文件中,而每一个磁盘文件都只属于下游stage的一个task,在将数据写入磁盘之前,会先将数据写入内存缓存中,下一个stage的task有多少个,当前stage的每个task就要创建多少份磁盘文件。
- 单个spark任务的excutor核数不宜设置过高,否则会导致其他JOB延迟
- 数据倾斜只发生在shuffle过程,可能触发shuffle操作的算子有:distinct, groupByKey, reduceByKey, aggregateByKey, join, cogroup, repartition等
- 运行时删除hadoop数据目录会导致依赖HDFS的JOB失效
- sparkSQL UDAF中update函数的第二个参数 input: Row 对应的并非DataFrame的行,而是被inputSchema投影了的行
- Spark的Driver只有在Action时才会收到结果
- Spark需要全局聚合变量时应当使用累加器(Accumulator)
- Kafka以topic与consumer group划分关系,一个topic的消息会被订阅它的消费者组全部消费,如果希望某个consumer使用topic的全部消息,可将该组只设一个消费者,每个组的消费者数目不能大于topic的partition总数,否则多出的consumer将无消可费
- 所有自定义类要实现serializable接口,否则在集群中无法生效
- resources资源文件读取要在Spark Driver端进行,以局部变量方式传给闭包函数
- DStream流转化只产生临时流对象,如果要继续使用,需要一个引用指向该临时流对象
- 提交到yarn cluster的作业不能直接print到控制台,要用log4j输出到日志文件中
- HDFS文件路径写法为:hdfs://master:9000/文件路径,这里的master是namenode的hostname,9000是hdfs端口号。
- 不要随意格式化HDFS,这会带来数据版本不一致等诸多问题,格式化前要清空数据文件夹
- 搭建集群时要首先配置好主机名,并重启机器让配置的主机名生效
- linux批量多机互信, 将pub秘钥配成一个
- 小于128M的小文件都会占据一个128M的BLOCK,合并或者删除小文件节省磁盘空间
- Non DFS Used指的是非HDFS的所有文件
- spark两个分区方法coalesce和repartition,前者窄依赖,分区后数据不均匀,后者宽依赖,引发shuffle操作,分区后数据均匀
- spark中数据写入ElasticSearch的操作必须在action中以RDD为单位执行
- 可以通过hive-site.xml修改spark.executor.instances, spark.executor.cores, spark.executor.memory等配置来优化hive on spark执行性能,不过最好配成动态资源分配。
二.基本功能
0.常见问题:
1如果运行程序出现错误:Exception in thread “main” java.lang.NoClassDefFoundError: org/slf4j/LoggerFactory,这是因为项目缺少slf4j-api.jar和slf4j-log4j12.jar这两个jar包导致的错误。 2如果运行程序出现错误:java.lang.NoClassDefFoundError: org/apache/log4j/LogManager,这是因为项目缺少log4j.jar这个jar包 3错误:Exception in thread “main” java.lang.NoSuchMethodError: org.slf4j.MDC.getCopyOfContextMap()Ljava/util/Map,这是因为jar包版本冲突造成的。
1.配置spark-submit (CDH版本)
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/hadoop/fs/FSDataInputStream at org.apache.spark.deploy.SparkSubmitArguments.handleUnknown(SparkSubmitArguments.scala:451) at org.apache.spark.launcher.SparkSubmitOptionParser.parse(SparkSubmitOptionParser.java:178) at org.apache.spark.deploy.SparkSubmitArguments.<init>(SparkSubmitArguments.scala:97) at org.apache.spark.deploy.SparkSubmit$.main(SparkSubmit.scala:113) at org.apache.spark.deploy.SparkSubmit.main(SparkSubmit.scala) Caused by: java.lang.ClassNotFoundException: org.apache.hadoop.fs.FSDataInputStream at java.net.URLClassLoader$1.run(URLClassLoader.java:366) at java.net.URLClassLoader$1.run(URLClassLoader.java:355) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:354) at java.lang.ClassLoader.loadClass(ClassLoader.java:425) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308) at java.lang.ClassLoader.loadClass(ClassLoader.java:358) ... 5 more
解决方案:
在spark-env.sh文件中添加:
export SPARK_DIST_CLASSPATH=$(hadoop classpath)
2.启动spark-shell时,报错
INFO cluster.YarnClientSchedulerBackend: Registered executor: Actor[akka.tcp://sparkExecutor@services07:34965/user/Executor#1736210263] with ID 1 INFO util.RackResolver: Resolved services07 to /default-rack INFO storage.BlockManagerMasterActor: Registering block manager services07:51154 with 534.5 MB RAM
解决方案:
在spark的spark-env配置文件中配置下列配置项:
将export SPARK_WORKER_MEMORY, export SPARK_DRIVER_MEMORY, export SPARK_YARN_AM_MEMORY的值设置成小于534.5 MB
3.启动spark SQL时,报错:
Caused by: org.datanucleus.store.rdbms.connectionpool.DatastoreDriverNotFoundException: The specified datastore driver ("com.mysql.jdbc.Driver ") was not found in the CLASSPATH. Please check your CLASSPATH specification, and the name of the driver.
解决方案:
在$SPARK_HOME/conf/spark-env.sh文件中配置:
export SPARK_CLASSPATH=$HIVE_HOME/lib/mysql-connector-java-5.1.6-bin.jar
4.启动spark SQL时,报错:
java.sql.SQLException: Access denied for user 'services02 '@'services02' (using password: YES)
解决方案:
检查hive-site.xml的配置项, 有以下这个配置项
<property> <name>javax.jdo.option.ConnectionPassword</name> <value>123456</value> <description>password to use against metastore database</description> </property>
看该密码与与MySQL的登录密码是否一致
5.启动计算任务时报错:
报错信息为:
org.apache.spark.rpc.RpcTimeoutException: Futures timed out after [120 seconds]. This timeout is controlled by spark.rpc.askTimeout
解决方案:
分配的core不够, 多分配几核的CPU
6.启动计算任务时报错:
不断重复出现
status.SparkJobMonitor: 2017-01-04 11:53:51,564 Stage-0_0: 0(+1)/1 status.SparkJobMonitor: 2017-01-04 11:53:54,564 Stage-0_0: 0(+1)/1 status.SparkJobMonitor: 2017-01-04 11:53:55,564 Stage-0_0: 0(+1)/1 status.SparkJobMonitor: 2017-01-04 11:53:56,564 Stage-0_0: 0(+1)/1
解决方案:
资源不够, 分配大点内存, 默认值为512MB.
7.启动Spark作为计算引擎时报错:
报错信息为:
java.io.IOException: Failed on local exception: java.nio.channels.ClosedByInterruptException; Host Details : local host is: "m1/192.168.179.201"; destination host is: "m1":9000; at org.apache.hadoop.net.NetUtils.wrapException(NetUtils.java:772) at org.apache.hadoop.ipc.Client.call(Client.java:1474) Caused by: java.nio.channels.ClosedByInterruptException at java.nio.channels.spi.AbstractInterruptibleChannel.end(AbstractInterruptibleChannel.java:202) at sun.nio.ch.SocketChannelImpl.connect(SocketChannelImpl.java:681) 17/01/06 11:01:43 INFO retry.RetryInvocationHandler: Exception while invoking getFileInfo of class ClientNamenodeProtocolTranslatorPB over m2/192.168.179.202:9000 after 9 fail over attempts. Trying to fail over immediately.
解决方案:
出现该问题的原因有多种, 我所遇到的是使用Hive On Spark时报了此错误,解决方案是: 在hive-site.xml文件下正确配置该项
<property> <name>spark.yarn.jar</name> <value>hdfs://ns1/Jar/spark-assembly-1.6.0-hadoop2.6.0.jar</value> </property>
8.启动spark集群时报错,启动命令为:start-mastersh
报错信息:
Exception in thread "main" java.lang.NoClassDefFoundError: org/slf4j/Logger at java.lang.Class.getDeclaredMethods0(Native Method) at java.lang.Class.privateGetDeclaredMethods(Class.java:2701) at java.lang.Class.privateGetMethodRecursive(Class.java:3048) at java.lang.Class.getMethod0(Class.java:3018) at java.lang.Class.getMethod(Class.java:1784) at sun.launcher.LauncherHelper.validateMainClass(LauncherHelper.java:544) at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:526) Caused by: java.lang.ClassNotFoundException: org.slf4j.Logger at java.net.URLClassLoader.findClass(URLClassLoader.java:381) at java.lang.ClassLoader.loadClass(ClassLoader.java:424) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331) at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ... 7 more
解决方案:
将/home/centos/soft/hadoop/share/hadoop/common/lib目录下的slf4j-api-1.7.5.jar文件,slf4j-log4j12-1.7.5.jar文件和commons-logging-1.1.3.jar文件拷贝到/home/centos/soft/spark/lib目录下
9.启动spark集群时报错,启动命令为:start-mastersh
报错信息:
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/hadoop/conf/Configuration at java.lang.Class.getDeclaredMethods0(Native Method) at java.lang.Class.privateGetDeclaredMethods(Class.java:2570) at java.lang.Class.getMethod0(Class.java:2813) at java.lang.Class.getMethod(Class.java:1663) at sun.launcher.LauncherHelper.getMainMethod(LauncherHelper.java:494) at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:486) Caused by: java.lang.ClassNotFoundException: org.apache.hadoop.conf.Configuration at java.net.URLClassLoader$1.run(URLClassLoader.java:366) at java.net.URLClassLoader$1.run(URLClassLoader.java:355) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:354) at java.lang.ClassLoader.loadClass(ClassLoader.java:425) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308) at java.lang.ClassLoader.loadClass(ClassLoader.java:358) ... 6 more
解决方案:
官网资料: https://spark.apache.org/docs/latest/hadoop-provided.html#apache-hadoop
编辑/home/centos/soft/spark/conf/spark-env.sh文件,配置下列配置项:
export SPARK_DIST_CLASSPATH=$(/home/centos/soft/hadoop/bin/hadoop classpath)
10.启动HPL/SQL存储过程时报错:
报错信息:
2017-01-10T15:20:18,491 ERROR [HiveServer2-Background-Pool: Thread-97] exec.TaskRunner: Error in executeTask java.lang.OutOfMemoryError: PermGen space at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClass(ClassLoader.java:800) 2017-01-10T15:20:18,491 ERROR [HiveServer2-Background-Pool: Thread-97] ql.Driver: FAILED: Execution Error, return code -101 from org.apache.hadoop.hive.ql.exec.spark.SparkTask. PermGen space 2017-01-10T15:20:18,491 INFO [HiveServer2-Background-Pool: Thread-97] ql.Driver: Completed executing command(queryId=centos_20170110152016_240c1b5e-3153-4179-80af-9688fa7674dd); Time taken: 2.113 seconds 2017-01-10T15:20:18,500 ERROR [HiveServer2-Background-Pool: Thread-97] operation.Operation: Error running hive query: org.apache.hive.service.cli.HiveSQLException: Error while processing statement: FAILED: Execution Error, return code -101 from org.apache.hadoop.hive.ql.exec.spark.SparkTask. PermGen space at org.apache.hive.service.cli.operation.Operation.toSQLException(Operation.java:388) at org.apache.hive.service.cli.operation.SQLOperation.runQuery(SQLOperation.java:244) at org.apache.hive.service.cli.operation.SQLOperation.access$800(SQLOperation.java:91) Caused by: java.lang.OutOfMemoryError: PermGen space at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClass(ClassLoader.java:800)
解决方案:
参考资料: http://blog.csdn.net/xiao_jun_0820/article/details/45038205
出现该问题是因为Spark默认使用全部资源, 而此时主机的内存已用, 应在Spark配置文件中限制内存的大小. 在hive-site.xml文件下配置该项:
<property> <name>spark.driver.extraJavaOptions</name> <value>-XX:PermSize=128M -XX:MaxPermSize=512M</value> </property>
或在spark-default.conf文件下配置:
spark.driver.extraJavaOptions -XX:PermSize=128M -XX:MaxPermSize=256M
时间:2018-10-09 22:42 来源: 转发量:次
声明:本站部分作品是由网友自主投稿和发布、编辑整理上传,对此类作品本站仅提供交流平台,转载的目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,不为其版权负责。如果您发现网站上有侵犯您的知识产权的作品,请与我们取得联系,我们会及时修改或删除。
相关文章:
相关推荐:
网友评论: