Spark入门
Spark概述
- 专为大规模数据处理而设计的快速通用计算引擎(与hadoop的Mapreduce类似)
- Spark 对比 MapReduce
- MapReduce每一次shuffle都要写磁盘,多个MapReduce之间通过磁盘进行数据传递,Spark的shuffle结果可以保存在内存中的
- MapReduce在每一个mapper和reducer之间都要经历一次shuffle,spark可以减少不必要的Shuffle
- MapReduce的Task调度和启动开销大(进程模型),而Spark的Task(任务)运行在线程中启动开销小
- MapReduce编程不够灵活,仅支持Map和Reduce两种操作,Spark API更丰富
- Spark 对比 MapReduce
- 基于内存的分布式计算框架(只计算,不涉及存储)
- Spark框架组件丰富
- 批处理:MapReduce、Hive、Pig
- 流式计算:Storm
- 交互式计算:Impala、presto
- 机器学习: mahout
- 缺点既是内存消耗大
- 启动
- 在$SPARK_HOME/bin目录下执行
- ./pyspark
- 在$SPARK_HOME/bin目录下执行
# wordcount例子
sc = spark.sparkContext
words = sc.textFile('file:///root/tmp/word.txt') \
.flatMap(lambda line: line.split(" ")) \
.map(lambda x: (x, 1)) \
.reduceByKey(lambda a, b: a + b).collect()
RDD概述
-
RDD(Resilient Distributed Dataset)弹性分布式数据集,是Spark中最基本的数据抽象,它代表一个不可变、可分区、里面的元素可并行计算的集合.
- Dataset:一个数据集,简单的理解为集合,用于存放数据
- Distributed:它的数据是分布式存储,并且可以做分布式的计算
- Resilient:弹性的
- 数据可以保存在磁盘,也可以保存在内存中
- 数据分布式存储也是弹性的
- RDD会在多个节点上存储,与hdfs的分布式存储原理类似。hdfs文件被切分为多个block存储在各个节点上,而RDD是被切分为多个partition。不同的partition可能在不同的节点上
- spark读取hdfs的场景下,spark把hdfs的block读到内存就会抽象为spark的partition。
- spark计算结束,一般会把数据做持久化到hive,hbase,hdfs等等。以hdfs为例,将RDD持久化到hdfs上,RDD的每个partition就会存成一个文件,如果文件小于128M,一个partition对应hdfs的一个block。如果大于128M,就会被且分为多个block,一个partition就会对应多个block。
- 不可变:Rdd1变换为Rdd2时 RDD1依然存在
- 可分区:多个partition
- 并行计算
-
创建RDD
-
sparkContext创建RDD
# sc即为sparkContext(若以pyspark方式进入:sc不必创建就可使用) spark = SparkSession.builder.appName("xxx").getOrCreate() sc = spark.sparkContext
-
Parallelized 方式创建RDD
>>> data = [1, 2, 3, 4, 5] >>> distData = sc.parallelize(data,5) # 5为指定分区数(可通过ip:4040查看) >>> data [1, 2, 3, 4, 5] >>> distData ParallelCollectionRDD[0] at parallelize at PythonRDD.scala:175
- Spark会为每个分区(partition)运行一个任务(task)。通常,可以根据CPU核心数量指定分区数量(每个CPU有2-4个分区)如未指定分区数量,Spark会自动设置分区数4。
-
通过外部数据创建RDD
- PySpark可以从Hadoop支持的任何存储源创建RDD,包括本地文件系统,HDFS,Cassandra,HBase,Amazon S3等
- 支持整个目录、多文件、通配符
- 支持压缩文件
>>> rdd1 = sc.textFile('file:///root/tmp/word.txt') >>> rdd1.collect()
-
RDD常用算子
RDD的三类算子包括 transformation、 action 和 persist, 前两种进行数据处理, persist处理数据存储相关操作
-
transformation 算子
# 以下RDD均为sc.parallelize(data) RDD.map(func) --> 将func作用到数据集每个元素上,生成一个新的RDD返回 RDD.filter(func) --> 选出所有func返回值为True的元素,生成一个新的RDD返回 RDD.flatMap(func) --> 先执行map,再将所有对象合并成一个(扁平化,完全拆开元素) rdd1.union(rdd2) --> 对rdd1和rdd2求并集 rdd1.intersection(rdd2) --> 对rdd1和rdd2求交集 RDD.groupByKey() --> 以元组中的第0个元素作为key,进行分组,返回一个新的RDD,value是个生成器 RDD.sortByKey() --> 按照key排序,可传参数ascending=False RDD.reduceByKey() --> 将key相同的键值对,按照Function进行计算
-
action 算子
RDD.collect() --> 返回一个包含所有元素的list(注意:此方法会将数据全部加载到内存) RDD.reduce(func) --> 所有元素通过函数计算,最终返回一个值 RDD.first() --> 返回RDD的第一个元素 RDD.take(N) --> 返回RDD的前N个元素 RDD.count() --> 返回RDD中的元素个数