Spark

Spark 有着 DAG(有向无环图)执行引擎,支持离散数据流和内存计算

spark 组件:

1. Spark core :所有功能在其上进行构建

2. SQL:在 core 之上引入的一个新的数据集抽象(SchemaRDD),支持结构和半结构化数据。RDD:弹性可复原的分布式数据       集

3. Spark Streaming:平衡 spark 内核的快速调度功能执行流分析。

4. MLib:机器学习框架。

5. GraphX:Spark 之上的分布式图处理计算

Spark 有自己的集群计算基数,扩展了 Hadoop MR 模型,主要特性是内存的集群计算。

spark 部署三种模式:

1.standalone : 独立模式

2.hadoop yarn(hadoop V2)

3.spark in mapreduce (hadoop V1)

spark 安装:

1.下载 spark-2.3.2-bin-without-hadoop.tgz

2.tar | mv | ln

3.配置环境变量

    将 spark/conf/spark-env.sh.template 拷贝成 spark-env.sh ,gedit 开 spark-env.sh,添加如下内容:

export SPARK_DIST_CLASSPATH=$(hadoop classpath)

然后配置 spark 的环境变量

sudo gedit /etc/environment

 添加:

SPARK_HOME=/soft/spark
/soft/spark/bin:/soft/spark/sbin

即刻生效,spark-shell启动后,spark的查看端口是4040

4.设置日志级别

将 spark/conf/log4j.properties 修改:

log4j.rootCategory=INFO, console

改成 log4j.rootCategory=WARN, console

spark 类

1.SparkContext:

spark上下文对象,是spark程序的主入口点,负责连接到spark cluster。可用创建RDD,在集群上创建累加器                                  和广播变量。

 每个JVM只能激活一个 SparkContext 对象,创建新的 SparkContex 时必须 stop 掉原来的对象

sc 的 textFile() 方法返回一个 RDD

2.RDD:Resilient(弹性) Distributed(分布式) Dataset(数据集)

是不可变,可分区的元素集合,可进行并行操作。该类包含了可用于与收所有 RDD 之上的基本操作,如 map, filter, Persist

在 RDD 内部,每个 RDD有5个特征:

1.有一个分区列表

2.每个 split 都有一个计算函数

3.存放 parent 的 RDD 依赖列表

4.(可选)基于 key-value 的分区器

5.(可选)首选的位置列表

spark 集群中所有调度和执行都是基于这些方法

$scala>val lines = sc.textFile("/user/ubuntu/xx.txt")    //读取HDFS文件系统的文件
$scala>lines.count()

$scala>val lines = sc.textFile("files:///home/ubuntu/xx.txt")    //读取本地文件
$scala>lines.count()

spark-shell :默认使用 local 模式运行 spark 程序,没有用到 spark 的集群,类似于 hadoop 的本地模式。

spark-shell --master local [4]     4表示在本地模式下启动的线程数,模拟 spark 集群。 

使用 maven 编译和运行 scala 的 spark 程序:

val conf = new SparkConf().setAppName("wordCount") //创建 sparkConf 对象
val sc = new SparkContext(conf) //创建 SparkContext 对象
val lines = sc.textFile("file:/home/ubuntu/a.txt") //加载文件
val words = lines.flatMap(x => x.split(",") //按照 , 切割行,然后进行压扁
val counts = words.map(w => (w,1)).reduceByKey(case (x,y) => x+y) //计算单词个数
counts.saveAsTextFile("file:/home/ubuntu/b.txt")

RDD 支持两种类型的操作: 转化操作和行动操作,转化操作会由一个RDD 生成一个新的RDD,行动操作会对RDD 计算出一个结果,并把结果返回到驱动器程序中,或把结果存储到外部存储系统(如HDFS)中。

默认情况下,Spark 的RDD 会在你每次对它们进行行动操作时重新计算。如果想在多个行动操作中重用同一个RDD,可以使用RDD.persist() 让Spark 把这个RDD 缓存下来。

以下总结了常见的RDD 转化操作:

 以下总结了常见的RDD 行动操作:

可以用aggregate() 来计算RDD 的平均值:

val result = input.aggregate((0, 0))(
(acc, value) => (acc._1 + value, acc._2 + 1),//累加器 (元组累加元组结果,RDD单个元素值)=>(元组累加结果+RDD单个元素,元组累加计数+1)
(acc1, acc2) => (acc1._1 + acc2._1, acc1._2 + acc2._2))
val avg = result._1 / result._2.toDouble

假如List(1,2,3,4,5,6,7,8,9,10),对List求平均数,首先,初始值是(0,0),这个值在后面2步会用到,然后,(acc,value) => (acc._1 + value, acc._2 + 1),value即是函数定义中的T,这里即是List中的元素,所以acc._1 + value, acc._2 + 1的过程如下:
1. 0+1,  0+1
2. 1+2,  1+1
3. 3+3,  2+1
4. 6+4,  3+1
5. 10+5,  4+1
6. 15+6,  5+1
7. 21+7,  6+1
8. 28+8,  7+1
9. 36+9,  8+1
结果即是(45,9)。这里演示的是单线程计算过程,实际Spark执行中是分布式计算,可能会把List分成多个分区,假如3个,p1(1,2,3,4),p2(5,6,7,8),p3(9),经过计算各分区的的结果(10,4),(26,4),(9,1),这样,执行(acc1,acc2) => (acc1._1 + acc2._1, acc1._2 + acc2._2)就是(10+26+9,4+4+1)即(45,9).再求平均值就简单了。

使用reduceByKey() 和mapValues() 计算每个键对应的平均值

rdd.mapValues(x => (x, 1)).reduceByKey((x, y) => (x._1 + y._1, x._2 + y._2))

 combineByKey() 是最为常用的基于键进行聚合的函数。大多数基于键聚合的函数都是用它实现的。和aggregate() 一样,combineByKey() 可以让用户返回与输入数据的类型不同的返回值。

在Scala 中使用combineByKey() 求每个键对应的平均值:

val result = input.combineByKey(
(v) => (v, 1),
(acc: (Int, Int), v) => (acc._1 + v, acc._2 + 1),
(acc1: (Int, Int), acc2: (Int, Int)) => (acc1._1 + acc2._1, acc1._2 + acc2._2)
).map{ case (key, value) => (key, value._1 / value._2.toFloat) }
result.collectAsMap().map(println(_))

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值