RDD(Resilient Distributed Dataset)叫做弹性分布式数据集,是Spark中最基本的数据抽象,它代表一个不可变、可分区、里面的元素可并行计算的集合。这里的弹性指的是RDD可以根据当前情况自动进行内存和硬盘存储的转换
在spark中所有的计算都是围绕着RDD操作的,每个 RDD 都被分为多个分区,这些分区运行在集群中的不同节点上,并且RDD也可以缓存到内存中
RDD支持两种操作:转化操作和行动操作。
RDD 的转化操作是返回一个新的 RDD的操作,新的RDD则包含了如何从其他RDDs衍生所必需的信息,所以说RDDs之间是有依赖关系的。基于RDDs之间的依赖,RDDs会形成一个有向无环图DAG,该DAG描述了整个流式计算的流程,实际执行的时候,RDD是通过血缘关系(Lineage)一气呵成的,即使出现数据分区丢失,也可以通过血缘关系重建分区
而行动操作则是向驱动器程序返回结果或把结果写入外部系统的操作。简单点说转换操作是修改属性状态的,行动是计算数据的
Spark采用惰性计算模式(懒执行),RDD只有第一次在一个行动操作中用到时,才会真正计算。Spark可以优化整个计算过程。默认情况下,Spark 的 RDD 会在你每次对它们进行行动操作时重新计算。如果想在多个行动操作中重用同一个 RDD,可以使用 RDD.persist() 让 Spark 把这个 RDD 缓存下来。
RDD特点:分区,只读,依赖,缓存,checkpoint检查点
转换方法
map(func)
经过函数转换后变成新的RDD
mapPartitions(func)
同上,不同的是在分区上进行,函数Iterator,假设有N个元素,有M个分区,那么map的函数的将被调用N次,而mapPartitions被调用M次,一个函数一次处理所有分区
val result = data.mapPartitions(
line => {
Iterator(line.next())
}
)
mapPartitionsWithIndex(func)
类似于mapPartitions,但func带有一个整数参数表示分片的索引值,因此在类型为T的RDD上运行时,func的函数类型必须是(Int, Interator[T]) => Iterator[U]
flatMap(func)
类似map,但是是返回多个值
filter(func)
返回值是truer让输入元素组成
sample(withReplacement, fraction, seed)
采样变换根据给定的随机种子,从RDD中随机地按指定比例选一部分记录,创建新的RDD
withReplacement : Boolean , True表示进行替换采样,False表示进行非替换采样
fraction : Double, 在0~1之间的一个浮点值,表示要采样的记录在全体记录中的比例
seed :随机种子
distinct()
去重
sortBy(func):只是根据RDD排序 如果是别的使用scala排序方法
按照func对数据进行处理,然后把结果排序,第二个为true为升序,为false为降序
sortBy(_._2,false)
sortByKey([ascending], [numTasks])
根据key排序
union(otherDataset)
对源RDD和参数RDD求并集后返回一个新的RDD 不去重
subtract (otherDataset)
去除两个RDD中相同的元素,不同的RDD将保留下来
intersection(otherDataset)
对源RDD和参数RDD求交集后返回一个新的RDD
join(otherDataset, [numTasks])
在类型为(K,V)和(K,W)的RDD上调用,返回一个相同key对应的所有元素对在一起的(K,(V,W))的RDD
val foodRDD = footerData.map(
line => line.split(",")
).filter(line => line.length>13)
.map(line => (line(13),line(0)))
val addressRDD = addressData.map(
line => {
val adds = line.split(",")
(adds(0),adds(4))
}
)
foodRDD.join(addressRDD).take(10)foreach(println(_))
cogroup(otherDataset, [numTasks])
在类型为(K,V)和(K,W)的RDD上调用,返回一个(K,(Iterable<V>,Iterable<W>))类型的RDD
groupByKey()
groupByKey也是对每个key进行操作,但只生成一个序列。
collect()
数组的形式返回数据集的所有元素
计算方法
reduce(func)
每次传入两个参数通过fun 的到一个返回值,该返回值继续与后面的值进行调用fun,直到所有的数据计算完成,最后返回一个计算结果
data.reduce(
(a,b) => {
println(a)
println(b)
("和",a._2 + b._2)
}
)
两个参数分别代表RDD中的两个记录,返回值被RDD用来进行递归计算,其中a表示上一个数据
reduceByKey(func, [numTasks])
在一个(K,V)的RDD上调用,返回一个(K,V)的RDD,使用指定的reduce函数,将相同key的值聚合到一起,reduce任务的个数可以通过第二个可选的参数来设置。
countByKey()
针对(K,V)类型的RDD,返回一个(K,Int)的map,表示每一个key对应的元素个数
count()
返回元素数量
编程网站
http://cw.hubwiz.com/card/c/5449c691e564e50960f1b7a9/1/1/1/
java.lang.ArrayIndexOutOfBoundsException: 4:数组下标越界异常
def f1(data:RDD[String])={
val dataRDD = data.map(
line => {
val hotel = line.split(",")
//取出下标为4商圈数据
(hotel(4),1)
}
)
//计算
val result = dataRDD.countByKey()
//取前10行打印
result.take(10).foreach(println(_))
}
object Fooder {
def main(args: Array[String]): Unit = {
val spark = new SparkContext(new SparkConf()
.setAppName("word")
.setMaster("local")
)
val data = spark.textFile("data/A.csv")
f1(data)
}
//计算每个商圈内饭店数量
def f1(data:RDD[String])={
val dataRDD = data
.map(line => line.split(","))//分割
.filter(x => x.length>14)//过滤数组长度大于14的数组
.map(x => (x(4),1)
)
//数据最后一行不满足下标长度
//计算
val result = dataRDD.countByKey()
//取前10行打印
result.take(10).foreach(println(_))
}
}
11.44
名称,评论数,人均价格,类别,商圈,地址,推荐1,推荐2,推荐3,口味评分,环境评分,服务评分,星级,店铺ID,网址
英雄,Pick场数,总击杀,场均KDA,场均击杀,场均死亡,场均助攻,GPM,XPM,被Ban场数,胜率,出场率,Ban率,热度
店铺ID,公共交通,纬度,经度,行政区名称
store_id,city,channel,gender_group,age_group,wkd_ind,product,customer,revenue,order,quant,unit_cost