Spark_RDD

RDD

注意:缓存有cache()和persist两种方式。查看源码发现cache()调用了persist(),继续查看persist()函数可以看到此函数内部调用了persist(StorageLevel.MEMORY_ONLY)可以看出来persist有一个StorageLevel类别的参数,这表示的是RDD的缓存级别
至此可以看出两者的区别:cache只有一个默认的缓存级别MEMORY_ONLY,而persist可以根据情况设置其他的缓存级别

弹性分布式数据集,就像Numpy array和Pandas Series,可以看作是一个有序的item集合,只不过这些item被分隔为多个partitions,分布在不同的机器上,
在spark中,对数据的所有操作不外乎创建RDD,转换RDD以及调用RDD操作进行求值。,Spark会将RDD中的数据分发到集群上,并将操作并行化执行

1.请简述RDD的含义,并写出针对RDD的两类操作(transformation与action),每类下至少三种的操作。
RDD(Resilient Distributed Datasets),弹性分布式数据集是一个容错的、可以被并行操作的元素集合弹性分布数据集。是Spark的核心,也是整个Spark的架构基础。Spark是以RDD概念为中心运行的。

RDD的一大特性是分布式存储,分布式存储在最大的好处是可以让数据在不同工作节点并行存储,以便在需要数据时并行运算。弹性指其在节点存储时,既可以使用内存,也可已使用外存,为使用者进行大数据处理提供方便

**它的特性可以总结如下:**

它是不变的数据结构存储
只读特性,维护DAG以便通过重新计算获得容错性
它是支持跨集群的分布式数据结构
可以根据数据记录的key对结构进行分区
提供了粗粒度的操作,且这些操作都支持分区
它将数据存储在内存中,从而提供了低延迟性


**常用的transformation操作:**

	map(func) 对调用map的RDD数据集中的每个element都使用func,然后返回一个新的RDD,这个返回的数据集是分布式的数据集
	filter(func) 对调用filter的RDD数据集中的每个元素都使用func,然后返回一个包含使func为true的元素构成的RDD
	flatMap(func) 和map差不多,但是flatMap生成的是多个结果,返回值是一个Seq(一个List)
	sample(withReplacement, fraction, seed) 从RDD中的item中采样一部分出来,有放回或者无放回
	union(otherDataset) 返回一个新的dataset,包含源dataset和给定dataset的元素的集合
	distinct([numTasks])) 对RDD中的item去重
	groupByKey([numTasks]): 返回(K,Seq[V]),也就是hadoop中reduce函数接受的key-valuelist
	reduceByKey(func, [numTasks]): 就是用一个给定的reduce func再作用在groupByKey产生的(K,Seq[V]),比如求和,求平均数
	sortByKey([ascending], [numTasks]) 按照key来进行排序,是升序还是降序,ascending是boolean类型
	join(otherDataset, [numTasks]) 当有两个KV的dataset(K,V)(K,W),返回的是(K,(V,W))的dataset,numTasks为并发的任务数
	cartesian(otherDataset) 笛卡尔积就是m*n
	intersection(otherDataset): 交集
	substract(otherDataset): 差集
	sortBy(keyfunc, ascending=True, numPartitions=None): Sorts this RDD by the given keyfunc

**常用的action操作:**

	reduce(func): 对RDD中的items做聚合
	collect(): 计算所有的items并返回所有的结果到driver端,接着 collect()会以Python list的形式返回结果
	count(): 返回的是dataset中的element的个数
	first(): 和上面是类似的,不过只返回第1个item
	take(n): 类似,但是返回n个item
	top(n): 返回头n个items,按照自然结果排序
	countByKey(): 返回的是key对应的个数的一个map,作用于一个RDD
	foreach(): 对dataset中的每个元素都使用func
	takeSample(): 指定采样个数,返回相应的数目
	saveAsTextFile(path): 把dataset写到一个text file中,或者hdfs,或者hdfs支持的文件系统中,spark把每条记录都转换为一行记录,然后写到file中

特别注意:Spark的核心概念是惰性计算,当你把一个RDD转换成另一个时,这些转换不会立即生效,action就是唤醒的时候

#flatmap的平铺功能
sentRDD = sc.parallelize(["Hello world","My Name is zong"])
wordRDD = sentRdd.flatmap(lambda sentRDD:sentRDD.split(" "))
print(worldRDD.collect())
print(worldRDD.count())
>结果:
>["Hello', 'world","My','Name', 'is', 'zong"]
>6
#和python中对应如下操作
l=["Hello world","My Name is zong"]
ll=[]
for sent in l:
   ll=ll+sent.split(" ")
 ll

Transfoemation可以串联

def fun(x):
	if x%2==1:
		return x*2
	else:
		return x
resultRdd = (numberRDD.map(fun)
					.filter(lambda x : x>6)
					.distinct()
)
resulitRdd.collect()
>结果:
>8,10,18,14                     
2. RDD间的操作
#将多个RDD合并成一个RDD
1. rdd1.union(rdd2):所有rdd1和rdd2的item组合
2. rdd1.intersection(rdd2):rdd1和rdd2的交集
3. rdd1.substract(rdd2):所有在rdd1中但不再rdd2中的item(差集)
4. rdd1.cartesian(rdd2):两个rdd总的元素笛卡尔乘积

简单的列子如下

num1=sc.parallelize([1,2,3])
num2 = sc.parallelize([2,3,4])
num1.union(num2).collect()  
>结果
>[1,2,3,2,3,4]
num1.intersection(num2).collect()
>结果
>[2,3]
num1.subtract(num2).collect()
>结果
>【1】
num1.cartesian(num2).collect()
>结果
>[(1,2),(1,3),(1,4),(2,2),(2,3),(2,4),(3,2)(3,4),(3,3)]

特别注意:spark是一个惰性计算,当你把一个RDD转换成另一个的时候,这个转换不会立即生效,等到正真拿到转换结果的时候,才会重新组织你的transformations,这样避免了不必要的中间结果存储和通信。Action能让它真正的转换和运算

#action的列子
rdd = sc.parallerize(range(1,10+1))
rdd.reduce(lambda x:x+y)
>结果
>55
3.初始化RDD
1)初始方法1

如果本地已经有一份序列化的数据如python的list,你可以通过sc.parallelize去初始化一个RDD,当执行完这个操作之后,list中的元素会被自动分块,并把每一块送到集群上的不同机器上。

import pyspark
from pyspark import SparkConf,SparkContext
conf = SparkConf.setAppName("miniProject").setMaster("local[*]")
sc = SparkContext.getOrCreate(conf)

my_list = [1,2,3,4,5]
rdd = sc.parallelize(my_list)
rdd

#获取分片数
rdd.getNumPartitions()  #结果为本地笔记本cpu的核数
#查看分区情况。数据量太大的时候千万不能用collect,他会把rdd上的所有的数据取回本地,然后以列表的形式展示
rdd.glom().collect()  #结果【[1],[2],[3],[4,5]】

使用sc.parallelize,你可以把Python list,Numpy array 或者Pandas Series,DataFrame 转换为Spark RDD

2)初始方法2

直接把文件读到RDD,此时文件中的每一行都会被当作一个item,不过需要注意的是saprk默认读取的文件路径是HDFS的,所以如果读取本地文件时,要加入**file://**开头的全局路径

import pyspark
from pyspark import SparkConf,SparkContext
conf = SparkConf.setAppName("miniProject").setMaster("local[*]")
sc = SparkContext.getOrCreate(conf)
#显示文件的前5行
!head -5 ./name/yob1880.txt
#获取当前路径
import os
cwd = os.getcwd()
#读取本地文件
rdd = sc.textFile("file://"+cwd+"/name/yob1880.txt")
rdd.first()

也可以直接读取整个文件夹的所有文件,但这种读法,RDD中的每个item实际上是一个形如(文件名,文件所有内容)的元组,如下例

#读取整个文件家中的所有内容
rdd = sc.wholeTexeFiles("file://"+cwd+"/name")
3)其他的初始化方式
  1. HDFS上的文件
  2. Hive中的数据库与表
  3. Spark Sql 的到的结果
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值