关于spark各种蛋疼的事

spark作为UC Berkeley开源的一个计算框架,现在已经是0.7.0版本了,但还不是特别成熟,离实际生产使用还有些距离。最近花了一周左右时间折腾了下,终于顺利的搭建好了一个6台机器的集群,并能顺利跑些大点数据,现在把过程中各种蛋疼的事记下来,以免忘记了又要折腾很久


安装

spark依赖scala,并且要自己编译源代码,这个可以参考http://rdc.taobao.com/team/jm/archives/1823

另外,spark 0.6之后可以不依赖Mesos,可以自己管理资源,所以在con/spark-env.sh中不需配置Mesos,直接通过bin/start-all.sh就可以启动。这里主要记录下要访问hdfs的需要做哪些。

首先,编译源代码前修改spark-0.7.0/project/SparkBuild.scala依赖的hadoop包版本,改成与你访问的hdfs版本一致,然后再编译打包。

      // Hadoop version to build against. For example, "0.20.2", "0.20.205.0", or
     // "1.0.4" for Apache releases, or "0.20.2-cdh3u5" for Cloudera Hadoop.
     //val HADOOP_VERSION = "0.20.2-cdh3u1"
     //val HADOOP_MAJOR_VERSION = "1" 
   
     // For Hadoop 2 versions such as "2.0.0-mr1-cdh4.1.1", set the HADOOP_MAJOR_VERSION to "2" 
     val HADOOP_VERSION = "2.0.0-mr1-cdh4.1.2"
     val HADOOP_MAJOR_VERSION = "2"

不然可能会报诸如:客户端与服务端版本不一致的问题

其次,编译好了并不代表就可以访问hdfs了,通常作为客户端访问hdfs需要一个core-site.xml类似的配置文件,包含账号/密码、压缩等配置。可以把这个配置文件放在spark-0.7.0/conf下,或者单独建立自己的应用程序时添加进去(后面会将怎样建一个scala的工程并提交运行)。然后运行./spark-shell,

       scala> val distFile = sc.textFile("hdsf://...")
       scala> distFile.count()

能正常运行说明能访问hdfs了。另外对于hadoop 2.0版本,core-site.xml文件里必需包含

     <property>
          <name>fs.hdfs.impl</name>
          <value>org.apache.hadoop.hdfs.DistributedFileSystem</value>
     </property>

不然可能会报诸如:不认识hdfs文件系统之类的错误

另外,编译完了后用sbt/sbt assembly,把spark依赖的jar都打到spark-0.7.0/core/target/spark-core-assembly-0.7.0.jar里,后面建立自己工程时会需要

安装好了就需要建立自己的工程项目然后写程序提交job,spark支持java,scala和python,现在简单讲下建一个scala项目:


scala Job开发

先安装scala build工具sbt:sudo rpm -ivh http://scalasbt.artifactoryonline.com/scalasbt/sbt-native-packages/org/scala-sbt/sbt//0.12.2/sbt.rpm

以一个小程序为例:一个访问hdfs上文件,并计算单词格式,并输出到hdfs上,工程名:hdfs_test 工程的目录结构:

   hdfs ---
     |-- hdfs_test.sbt
     |-- lib
           |--spark-core-assembly-0.7.0.jar (把上面spark 打包的jar复制过来)
     |-- src 
           |--main
                |--resources
                       |--core-site.xml (访问hdfs的客户端配置)
                |--scala
                       |--HdfsTest.scala (你的程序)

hdfs_test.sbt内容

 name := "hdfs test"
 version := "1.0"
 scalaVersion := "2.9.2"

HdfsTest.scala内容

  import spark._
  import SparkContext._
  object HdfsTest {
    def main(args: Array[String]) {
       val sc = new SparkContext("spark://10.232.42.75:7077", "HdfsTest",
       System.getenv("SPARK_HOME"), Seq("/home/admin/project/hdfs_test/target/scala-2.9.2/hdfs-test_2.9.2-1.0.jar"))
       val file = sc.textFile("hdfs://search042092.sqa.cm4:9000/app/network_mining/link/30days_trade_link/20130319")
       var mapped = file.flatMap(line => line.split("\t")).map(word => (word,1))
       var counts = mapped.reduceByKey(_ + _)
       counts.saveAsTextFile("hdfs://search042092.sqa.cm4:9000/app/network_mining/test_file");
       System.exit(0)
    }
 }

编译打包:sbt package 运行:要提交一个job运行,还是比较蛋疼的,尝试过各种方式后,终于决定看下examples和run脚本,然后把run脚本做了些修改

Image:Spark_run_1.jpg

Image:Spark_run_2.jpg

简单来说:run脚本接受-jar参数,并把jar放到classpath 执行spark-0.7.0/run -jar /home/admin/project/hdfs_test/target/scala-2.9.2/hdfs-test_2.9.2-1.0.jar HdfsTest即可运行


优化

spark原本的配置跑大量数据的时候会有一些,尤其是jvm gc,默认的采用串行gc,slave一下就挂了,可以改成采用CMS,在spark-env.sh中添加如下配置:

 SPARK_JAVA_OPTS="-Dspark.storage.blockManagerHeartBeatMs=60000 -Dspark.local.dir=$SPARK_LOCAL_DIR -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:$SPARK_HOME/logs/gc.log  -XX:+UseConcMarkSweepGC  -XX:+UseCMSCompactAtFullCollection -XX:CMSInitiatingOccupancyFraction=60"

spark.storage.blockManagerHeartBeatMs 设置心跳时间,原来貌似是5m,太短了,一旦发生full gc就timeout了

spark.local.dir 是每个节点计算保存临时数据的目录,默认在/tmp下,如果/tmp不够大很容易满

其它就是cms的配置,设置后效果还是很明显的。但观察每个节点隔两分钟左右仍然会因为full gc而hang住。增大旧生代后可能会有效果。


最后,google的spark用户组是个好地方,碰到的很多问题都可以在里面找到,有专人负责解答

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值