Spark安装 测试

来源:互联网 发布:阿里云国际版试用 编辑:程序博客网 时间:2024/05/21 13:55

Spark与Mapreduce对比

MapReduce Spark 数据存储结构:磁盘hdfs文件系统的split 使用内存构建弹性分布式数据集RDD, 对数据进行运算和cache 编程范式: Map + Reduce DAG(有向无环图): Transformation + action 计算中间数据落磁盘, io及序列化、 反序列化代价大 计算中间数据在内存中维护, 存取速度是磁盘的多个数量级 Task以进程的方式维护, 任务启动就有数秒 Task以线程的方式维护, 对小数据集的读取能达到亚秒级的延迟

spark1.x源码编译

环境要求:
Maven:3.3.3+
Java:1.7+
Scala:2.10.4

将当前3.0.5的版本更换为3.3.3的版本,
Maven的安装:http://blog.csdn.net/haoyuexihuai/article/details/52985796
进入~/.m2目录将repository-1.6.1.tar.gz(maven包) 解压到当前目录:tar -zxvf repository-1.6.1.tar.gz ~/.m2

编译:
前提:安装好Maven、Scala、Java

  1. 解压
    1. tar -zxvf /opt/software/spark-1.6.1.tar.gz -C /opt/tools/workspace
  2. 进入目录
    1. cd /opt/tools/workspace/spark-1.6.1
  3. 修改:make-distribution.sh文件

    1. vim make-distribution.sh ## 修改130行开始的四个属性的值
    2. YARN
    3. 原始:
      这里写图片描述

      VERSION=1.6.0SCALA_VERSION=2.10.4SPARK_HADOOP_VERSION=2.5.0 / 2.5.0-cdh5.3.6SPARK_HIVE=1

      修改为:
      这里写图片描述

  4. 修改pom文件:vim pom.xml
    1. 使用/2.10.5 查询 修改为2.10.4。文件中有两处需要修改
  5. 放依赖服务

    tar -zxvf /opt/software/scala-2.10.4.tgz -C /opt/tools/workspace/spark-1.6.1/build/tar -zxvf /opt/software/zinc-0.3.5.3.tgz -C /opt/tools/workspace/spark-1.6.1/build/

    这里写图片描述

  6. CDH编译源码

    ./make-distribution.sh --tgz \-Phadoop-2.4 \-Dhadoop.version=2.5.0-cdh5.3.6 \-Pyarn \-Phive -Phive-thriftserver  

    这里写图片描述

    编译结束后在目录下生成一个:spark-1.6.0-bin-2.5.0-cdh5.3.6.tgz

  7. Apache编译

    ./make-distribution.sh --tgz \-Phadoop-2.4 \-Dhadoop.version=2.5.0 \-Pyarn \-Phive -Phive-thriftserver  

Spark安装部署:

Spark四种运行模式

  • Local:本地运行模式,主要用于开发、测试
  • Standalone:使用Spark自带的资源管理框架运行Spark程序,30%左右
  • Yarn: 将spark应用程序运行在yarn(资源管理框架)上,绝大多数使用情况,60%左右
  • Mesos:国内不常用

将spark-1.6.1.tar.gz解压,并添加到IDEA中,将文件夹的结构转换为代码的结构。
这里写图片描述

查询的默认快捷键:Ctrl + N ,Ctrl+F12

  1. 使用Ctrl+N 搜索:SparkContext
    这里写图片描述
  2. Ctrl+F12搜索:textFile
    这里写图片描述

Local模式安装

使用自己编译产生的tgz压缩包
步骤:
前提:安装Scala(2.10.4)和JDK(1.7.x+),之前已经安装
这里写图片描述
1. 解压到cdh-5.3.6目录
进入目录:cd /opt/cdh-5.3.6
解压tar:-zxvf /opt/tools/workspace/spark-1.6.1/spark-1.6.0-bin-2.5.0-cdh5.3.6.tgz
创建软连接:ln -s spark-1.6.0-bin-2.5.0-cdh5.3.6/ spark
这里写图片描述
2. 修改相关参数
cd /opt/cdh-5.3.6/spark/conf
mv spark-env.sh.template spark-env.sh
mv spark-defaults.conf.template spark-defaults.conf
修改:vim spark-env.sh
内容:

```JAVA_HOME=/opt/modules/jdk1.7.0_67SCALA_HOME=/opt/modules/scalaHADOOP_CONF_DIR=/opt/cdh-5.3.6/hadoop-2.5.0-cdh5.3.6/etc/hadoopSPARK_LOCAL_IP=hadoop-senior01.ibeifeng.com```

3. 启动HDFS
sbin/start-dfs.sh
4. 测试
进入启动目录:cd /opt/cdh-5.3.6/spark/bin
删除所有以cmd(Windows下使用)结尾的文件:rm *cmd
启动:./spark-shell
这里写图片描述

启动后创建了一个metastore_db

这里写图片描述
17/02/14 10:37:23 INFO ui.SparkUI: Started SparkUI at http://192.168.66.141:4040
这里写图片描述
17/02/14 10:37:49 INFO repl.SparkILoop: Created sql context (with Hive support)..
SQL context available as sqlContext.
这里写图片描述

创建路径:bin/hdfs dfs -mkdir -p /beifeng/spark/
上传文件:bin/hdfs dfs -put /opt/cdh-5.3.6/spark/README.md /beifeng/spark/
这里写图片描述

Standalone结构配置

Standalone模式是Spark自身管理资源的一个模式,类似Yarn
Yarn的结构:

  • ResourceManager: 负责集群资源的管理
  • NodeManager:负责当前机器的资源管理
  • CPU&内存
    SparkStandalone的结构:

  • Master: 负责集群资源管理

  • Worker: 负责当前机器的资源管理
  • CPU&内存

配置安装:

  • 前提:基于Local模式下的进行修改安装
  • 前提2:所有机器以及完成SSH免密码登录

安装步骤:

  1. 修改spark-env.sh:vim spark-env.sh

    SPARK_MASTER_IP=hadoop-senior01.ibeifeng.comSPARK_MASTER_PORT=7070SPARK_MASTER_WEBUI_PORT=8080SPARK_WORKER_CORES=3 ## 一个work分配的cpu数量SPARK_WORKER_MEMORY=3g ## 一个work分配的内存数量SPARK_WORKER_PORT=7071SPARK_WORKER_WEBUI_PORT=8081SPARK_WORKER_INSTANCES=2 ## 一台机器允许同时存在的work的数量
  2. 修改slaves.template,给定work节点的hostname

    mv slaves.template slavesvim slaves ## 一行一个hostname
  3. 启动服务:cd /opt/cdh-5.3.6/spark

    1. sbin/start-all.sh
    2. 日志位于:/opt/cdh-5.3.6/spark/logs文件夹中
      访问页面:http://hadoop-senior01.ibeifeng.com:8080/
      这里写图片描述
  4. 测试wordcount程序

    1. bin/spark-shell --master spark://hadoop-senior01.ibeifeng.com:7070

      sc.textFile("/input/wc.input").  filter(_.length > 0).   flatMap(_.split(" ").map((_,1))).  reduceByKey(_ + _).  top(3)(ord = new scala.math.Ordering[(String,Int)](){    // 自定义数据排序类    override def compare(x: (String,Int), y: (String,Int)) = {      val tmp = x._2.compare(y._2)      if (tmp != 0) tmp      else -x._1.compare(y._1)    }  })

      这里写图片描述


Spark Shell测试

// 前提:spark集成hdfs
// textFile默认是HDFS上的路径,除非给定特定的schema(HDFS://)
val textFile = sc.textFile(“/beifeng/spark/README.md”)
/*
textFile: org.apache.spark.rdd.RDD[String] = /beifeng/spark/README.md MapPartitionsRDD[1] at textFile at :27 */

textFile.count()
/*
res2: Long = 95
*/
textFile.first()
/*
res3: String = # Apache Spark
*/

过滤
val linesWithSpark = textFile.filter(line => line.contains(“Spark”))
linesWithSpark.take(3)
/*
res4: Array[String] = Array(# Apache Spark, Spark is a fast and general cluster computing system for Big Data. It provides, rich set of higher-level tools including Spark SQL for SQL and DataFrames,)
*/

linesWithSpark.count()

/*
res5: Long = 17
*/

SparkCore开发

步骤:
1. 数据加载
val rdd = sc.textFilexxx
2. 数据处理
val rdd2 = rdd.xxxx
3. 结果输出
rdd2.xxx

SparkCore WordCount

MapReduce:  MapTask:    数据过滤、数据转换(转换为word和次数<word,1>)  Shuffle:    数据排序 + 数据分组  ReduceTask:    数据的聚合

// Step1: 读取HDFS上的文件/input/wc.input

val rdd = sc.textFile("/input/wc.input")

这里写图片描述

// Step2: 数据过滤
/*
Return a new RDD containing only the elements that satisfy a predicate.
def filter(f: T => Boolean): RDD[T]
T: 此时是String
最终返回的RDD中的数据是执行f函数后返回结果为true的数据
*/

val filterRDD = rdd.filter(len => len.length > 0)

这里写图片描述

// Step3: 数据转换
/*
def map[U: ClassTag](f: T => U): RDD[U]
f:从T到U类型的一个数据转换函数
map的最终返回的RDD中的数据类型是f函数返回的数据类型
def flatMap[U: ClassTag](f: T => TraversableOnce[U]): RDD[U]
f: 从T到集合类型的一个数据转换函数,集合中的数据类型是U
flatMap的最终返回的RDD中的数据类型是f函数返回的集合中的具体的数据类型,比如U
flatMap和map函数的区别:
flatMap在map函数的基础上进行一次数据扁平化的操作
数据扁平化:将集合中的数据进行一个提升,删除集合
*/

val mapperRDD = filterRDD.flatMap(line => line.split(" ").map(word => (word,1)))

这里写图片描述

// Step4: 数据的分组,相同的word分配到一组
/*
def groupBy[K](f: T => K)(implicit kt: ClassTag[K]): RDD[(K, Iterable[T])]
f: 是一个从T到K进行转换的一个函数
返回RDD的内部数据类型是一个二元组,第一个元素是K类型的数据,第二个元素是是一个T元素数据的迭代器
原理:将K相同的数据放到一起
*/

val groupRDD = mapperRDD.groupBy(tuple => tuple._1)

这里写图片描述

查看一下数据格式:groupRDD.foreach(println)
这里写图片描述

// Step5 数据聚合 => 数据的一个累计计算/就是一个转换

val wordCountRDD = groupRDD.map(tuple => {  val word = tuple._1 // 单词  // val sum = tuple._2.toList.map(tuple => tuple._2).sum  val sum = tuple._2.toList.foldLeft(0)((a,b) => a+b._2)  // 返回结果  (word,sum)})

这里写图片描述

// Step6数据结果输出

wordCountRDD.foreach(println) 

这里写图片描述

wordCountRDD.foreachPartition(iter => iter.foreach(println)) // 一个分区一个分区的进行处理wordCountRDD.saveAsTextFile("/beifeng/wordcount/output02")

// wordcount简化 ==> 链式编程

sc.textFile("/input/wc.input").  // 数据过滤  filter(_.length > 0).   // 数据的转换  flatMap(_.split(" ").map((_,1))).  // 分组  groupByKey().  // 统计计数  map(tuple => (tuple._1, tuple._2.toList.sum)).  // 结果输出  saveAsTextFile("/beifeng/wordcount/output03")

// Wordcount最优的一种

sc.textFile("/input/wc.input").  // 数据过滤  filter(_.length > 0).   // 数据的转换  flatMap(_.split(" ").map((_,1))).  // 统计计数  reduceByKey(_ + _).  // 结果输出  saveAsTextFile("/beifeng/wordcount/output04")

/*
选择使用reduceByKey函数的主要原因是:reduceByKey中存在combiner
不使用groupByKey的主要原因:在大规模的数据下,数据分布不均匀的情况下,可能导致OOM
As currently implemented, groupByKey must be able to hold all the key-value pairs for any key in memory. If a key has too many values, it can result in an [[OutOfMemoryError]].

*/

sc.textFile("/input/wc.input").  filter(_.length > 0).   flatMap(_.split(" ").map((_,1))).  reduceByKey(_ + _).  collect()

// Array[(String, Int)] = Array((mapreduce,2), (hello,1), (yarn,1), (spark,1), (hadoop,4), (hdfs,1))

// 排序:最终结果按照count数量从大到小排序

sc.textFile("/input/wc.input").  filter(_.length > 0).   flatMap(_.split(" ").map((_,1))).  reduceByKey(_ + _).  sortBy(tuple => tuple._2,ascending = false).  collect()

// Array[(String, Int)] = Array((hadoop,4), (mapreduce,2), (hello,1), (yarn,1), (spark,1), (hdfs,1))

sc.textFile("/input/wc.input").  filter(_.length > 0).   flatMap(_.split(" ").map((_,1))).  reduceByKey(_ + _).  map(tuple => (tuple._2,tuple._1)).  sortByKey(ascending = false).  map(tuple => (tuple._2,tuple._1)).  collect()

// res33: Array[(String, Int)] = Array((hadoop,3), (hbase,3), (hive,2), (sqoop,2), (spark,1), (oozie,1))

// TOP K
// 作业:MapReduce TOP K的实现伪代码

sc.textFile("/input/wc.input").  filter(_.length > 0).   flatMap(_.split(" ").map((_,1))).  reduceByKey(_ + _).  map(tuple => (tuple._2,tuple._1)).  sortByKey(ascending = false).  map(tuple => (tuple._2,tuple._1)).  take(3)
sc.textFile("/input/wc.input").  filter(_.length > 0).   flatMap(_.split(" ").map((_,1))).  reduceByKey(_ + _).  top(3)(ord = new scala.math.Ordering[(String,Int)](){    // 自定义数据排序类    override def compare(x: (String,Int), y: (String,Int)) = {      val tmp = x._2.compare(y._2)      if (tmp != 0) tmp      else -x._1.compare(y._1)    }  })
0 0
原创粉丝点击