Spark 任务开发


转至元数据结尾
转至元数据起始

 

Spark 任务开发:

开发语言:Spark 支持 Java、Scala、Python等多张语言,Spark 任务编写上,Scala 是最推荐使用的语言。

步骤:

  1. 本地开发,以local模式跑通。
  2. 提交到公司 yarn 集群,以 yarn-cluster 模式运行。(yarn-cluster模式适合production环境, yarn-client模式适合debug环境. 如果采用Yarn-Client请记住保留本地的Driver日志)

 

Spark 任务提交到yarn步骤:

  1. 本地生成jar包
  2. 拷贝到线上机器 lg09
  3. 在线上机器 lg09 上提交任务

 

Spark 任务-- WordCount (从编写到运行)

  1. clone 项目:git clone http://git.xiaomi.com:8088/miuicloud/sec/miui-sec/miui-sec-hadoop && scp -p -P 29418 liujianquan@git.xiaomi.com:hooks/commit-msg miui-sec-hadoop/.git/hooks/
  2. 导入 IDEA,IDEA 安装 Scala 插件 creating-and-running-your-scala-application
  3. 新建 Scala 文件 WordCount.scala, 编辑 pom.xml 文件,添加依赖(已添加)。

     

    package  com.xiaomi.miui.sec.example
     
    import  java.net.URI
     
    import  org.apache.hadoop.conf.Configuration
    import  org.apache.hadoop.fs.{FileSystem, Path}
    import  org.apache.spark.{SparkConf, SparkContext}
     
    /**
      * 统计文件中单词出现的个数
      * Created by Liu on 16/5/3.
      */
    object  WordCount {
         def  main(args :  Array[String]) {
     
             if  (args.length ! =  2 ) {
                 System.err.println( "Usage: WordCount <input> <output>" )
                 System.exit( 1 )
             }
     
             // 传入命令行参数, input 输入文件地址, output 输出文件地址
             val  Array(input, output)  =  args
     
             // 创建 Spark 配置并设置 AppName 为 WordCount
             val  sparkConf  =  new  SparkConf().setAppName( "WordCount" )
             sparkConf.setIfMissing( "spark.master" "local[2]" )
             // 创建 SparkContext
             val  sc  =  new  SparkContext(sparkConf)
     
             // 如果输出文件存在, 则先删除
             val  fs  =  FileSystem.get( new  URI(output),  new  Configuration())
             fs.delete( new  Path(output),  true )
     
             // Split each line into words and flatten the result.
             val  lines  =  sc.textFile(input)
             val  words  =  lines.flatMap( _ .split( " " ))
             // Map each word into a pair and count them by word (key).
             val  wc  =  words.map(w  = > (w,  1 )).reduceByKey( _  _ )
             // Save the result into text files - one per partition.
             wc.saveAsTextFile(output)
             
             sc.stop()
         }
     
    }
  4. 打包 jar 。
    mvn package -P wordCount
    target 目录下生成 miui-sec-spark-wordCount-1.1.12-pom-SNAPSHOT.jar
  5. 复制 jar 到 线上机器 lg09。
    scp liu@10.235.134.9:/Users/Liu/Projects/Xiaomi/src/miui-sec-hadoop/miui-sec-spark/target/miui-sec-spark-wordCount-1.1.12-pom-SNAPSHOT.jar    /home/work/dev/jars/
  6. 在 lg09 上运行 WordCount 任务
    local 模式
    输入文件 input.txt

    local 模式运行任务,$INFRA_CLIENT/bin/spark-submit --class com.xiaomi.miui.sec.example.WordCount --master local /home/work/dev/jars/miui-sec-spark-wordCount-1.1.12-pom-SNAPSHOT.jar file:///$PWD/input.txtfile:///$PWD/output
    其中,spark-submit 参数请查阅 submitting-applications ,infra client 使用参考infra-client使用

    输出结果 output



    yarn-cluster 模式

    把 WordCount 提交到公司的 yarn 集群(由于lg机房逐步淘汰,现在都提交到 c3 机房的集群 c3prc-hadoop,办公网访问C3集群需要设置代理,方法见 办公网访问IDC代理指南
    输入文件是 HDFS 上的 input.txt


    提交任务到 yarn

    查看 yarn 上的任务执行情况:http://c3-hadoop-prc-ct04.bj:22301/cluster/app/application_1447144693824_1536961
    查看 SparkUI 上任务执行情况:http://c3hadoopproxy.d.xiaomi.net:18900/history/application_1447144693824_1536961/1/jobs/
    (办公网需要设置代理访问)

    查看 output 结果

Spark 读写 HBase

HBase 使用参考 Xiaomi HBase BookXiaomi(0.98)和 Xiaomi HBase Book(0.94)

Spark 支持从多种数据源读取数据,进行处理,并支持输出到多种数据源中。Spark 读写 HBase 的方法,在现有的项目中有,可以直接参考。

需要注意:

公司维护的HBase有两个版本,0.94 和 0.98 版,两个版本的依赖不一样。

spark-submit 提交时需要指定--hbase 参数

 

Spark 读取其他格式文件

读取 Paruqet 文件,有两种方法

  1. 使用数据工厂的包com.xiaomi.data:commons-spark:0.0.1-SNAPSHOT
    具体参考 MapReduce/Spark读写Thrift+Paruqet/SequenceFile
  2. 使用Spark SQL
    添加spark-sql依赖

     

    < dependency >
         < groupId >org.apache.spark</ groupId >
         < artifactId >spark-sql_2.10</ artifactId >
         < version >1.5.2</ version >
         < scope >provided</ scope >
    </ dependency >

     

    读parquet文件

     

    val sqlContext =  new  org.apache.spark.sql.SQLContext(sc)
    val parquetFile = sqlContext.read.parquet(srcFile)
    val basicRDD = parquetFile.rdd.filter(row => {
         if  (row.isNullAt( 1 ) && row.isNullAt( 2 ) && row.isNullAt( 3 ))  false
         else  true
    }).mapPartitions(it => {
         for  (row <- it) yield {
             basicCounter +=  1
             (row.getString( 0 ), (row.getString( 1 ), row.getString( 2 ), row.getString( 3 )))
         }
    })

使用 Spark 过程中可能遇到的坑

  • 强烈建议:首先阅读 小米 Spark用户 QA,可以避免很多坑,了解如何 kill 任务、查看日志等。
  • 任务队列:提交任务要指定队列(–queue),不指定会分配到资源少的 default 队列。另外测试阶段可以提交到development 队列
    我们组的队列是 
    Hadoop 任务:root.production.miui_group.miuisec 
    Spark 任务:root.service.miui_group.miuisec
    一般情况,MR 任务提交到 Hadoop 队列,Spark 任务提交到 Service 队列,特殊情况也可变通。Spark 任务提交到 Hadoop 任务队列可能会被抢占。
  • HBase
    HBase 作为输入时,region的数量就是任务的数量。当 Regin size 过大时,可以考虑 Split Region,使任务数增多,单个任务处理的数据量降下来。
    Scan  HBase 可能会遇到,内存泄漏的问题,可以加入配置  conf.set("hbase.ipc.client.connection.maxidletime""3600000"),具体原因未知。。
    任务只读取行一次的情况下,关闭 CacheBlocks  scan.setCacheBlocks(false)
    合理设置Scan参数可以提高性能,参考 http://stackoverflow.com/questions/22528859/hbase-scan-performance
    需要全表scan之前,可以先指定 startRow 和 stopRow,小范围运行任务,验证结果。
  •  使用 Accumulator :使用计数器,可以方便的记录次数,并在 Spark UI 上实时查看,比查看 log 文件方便。
  • 脏数据
    脏数据很难避免,代码要足够兼容。

  • 数据倾斜
  • 合理设置RDD的Cache
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值