你好,游客 登录
背景:
阅读新闻

搭建Spark所遇过的坑

[日期:2017-11-10] 来源:  作者: [字体: ]

作者:花弄影

一.经验

  1. Spark Streaming包含三种计算模式:nonstate .stateful .window
  2. kafka可通过配置文件使用自带的zookeeper集群
  3. Spark一切操作归根结底是对RDD的操作
  4. 部署Spark任务,不用拷贝整个架包,只需拷贝被修改的文件,然后在目标服务器上编译打包。
  5. kafka的log.dirs不要设置成/tmp下的目录,貌似tmp目录有文件数和磁盘容量限制
  6. ES的分片类似kafka的partition
  7. spark Graph根据边集合构建图,顶点集合只是指定图中哪些顶点有效
  8. presto集群没必要采用on yarn模式,因为hadoop依赖HDFS,如果部分机器磁盘很小,hadoop会很尴尬,而presto是纯内存计算,不依赖磁盘,独立安装可以跨越多个集群,可以说有内存的地方就可以有presto
  9. presto进程一旦启动,JVM server会一直占用内存
  10. 如果maven下载很慢,很可能是被天朝的GFW墙了,可以在maven安装目录的setting.conf配置文件mirrors标签下加入国内镜像抵制**党的网络封锁,例如:
  11. <mirror>
    
      <id>nexus-aliyun</id>
    
      <mirrorOf>*</mirrorOf>
    
      <name>Nexus aliyun</name>
    
      <url>http://maven.aliyun.com/nexus/content/groups/public</url>
    
    </mirror>
  12. 编译spark,hive on spark就不要加-Phive参数,若需sparkSQL支持hive语法则要加-Phive参数
  13. 通过hive源文件pom.xml查看适配的spark版本,只要打版本保持一致就行,例如spark1.6.0和1.6.2都能匹配
  14. 打开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
  15. kafka的comsumer groupID对于spark direct streaming无效
  16. shuffle write就是在一个stage结束计算之后,为了下一个stage可以执行shuffle类的算子,而将每个task处理的数据按key进行分类,将相同key都写入同一个磁盘文件中,而每一个磁盘文件都只属于下游stage的一个task,在将数据写入磁盘之前,会先将数据写入内存缓存中,下一个stage的task有多少个,当前stage的每个task就要创建多少份磁盘文件。
  17. 单个spark任务的excutor核数不宜设置过高,否则会导致其他JOB延迟
  18. 数据倾斜只发生在shuffle过程,可能触发shuffle操作的算子有:distinct, groupByKey, reduceByKey, aggregateByKey, join, cogroup, repartition等
  19. 运行时删除hadoop数据目录会导致依赖HDFS的JOB失效
  20. sparkSQL UDAF中update函数的第二个参数 input: Row 对应的并非DataFrame的行,而是被inputSchema投影了的行
  21. Spark的Driver只有在Action时才会收到结果
  22. Spark需要全局聚合变量时应当使用累加器(Accumulator)
  23. Kafka以topic与consumer group划分关系,一个topic的消息会被订阅它的消费者组全部消费,如果希望某个consumer使用topic的全部消息,可将该组只设一个消费者,每个组的消费者数目不能大于topic的partition总数,否则多出的consumer将无消可费
  24. 所有自定义类要实现serializable接口,否则在集群中无法生效
  25. resources资源文件读取要在Spark Driver端进行,以局部变量方式传给闭包函数
  26. DStream流转化只产生临时流对象,如果要继续使用,需要一个引用指向该临时流对象
  27. 提交到yarn cluster的作业不能直接print到控制台,要用log4j输出到日志文件中
  28. HDFS文件路径写法为:hdfs://master:9000/文件路径,这里的master是namenode的hostname,9000是hdfs端口号。
  29. 不要随意格式化HDFS,这会带来数据版本不一致等诸多问题,格式化前要清空数据文件夹
  30. 搭建集群时要首先配置好主机名,并重启机器让配置的主机名生效
  31. linux批量多机互信, 将pub秘钥配成一个
  32. 小于128M的小文件都会占据一个128M的BLOCK,合并或者删除小文件节省磁盘空间
  33. Non DFS Used指的是非HDFS的所有文件
  34. spark两个分区方法coalesce和repartition,前者窄依赖,分区后数据不均匀,后者宽依赖,引发shuffle操作,分区后数据均匀
  35. spark中数据写入ElasticSearch的操作必须在action中以RDD为单位执行
  36. 可以通过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://[email protected]: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




收藏 推荐 打印 | 录入:Cstor | 阅读:
本文评论   查看全部评论 (0)
表情: 表情 姓名: 字数
点评:
       
评论声明
  • 尊重网上道德,遵守中华人民共和国的各项有关法律法规
  • 承担一切因您的行为而直接或间接导致的民事或刑事法律责任
  • 本站管理人员有权保留或删除其管辖留言中的任意内容
  • 本站有权在网站内转载或引用您的评论
  • 参与本评论即表明您已经阅读并接受上述条款