#HashPartitioner源码分析
package cn.doit.spark.day02
/*
HashPartitioner(分区器)源码分析
*/
object HashPartitionerDemo {
def nonNegativeMod(x:Int , mod:Int): Int = {
//文件的hashcode值为x,mod为下游分区
val rawMod = x % mod
rawMod + (if (rawMod < 0) mod else 0)
}
def main(args: Array[String]): Unit = {
// val word = "spark" //1
// val word = "hadoop" //1
val word = "flume" //3
//index分到第几个区 4为下游分区
val index = nonNegativeMod(word.hashCode, 4)
println(index)
}
}
#RDD算子之Transformation 转换算子, lazy(懒加载)的,调用后生成一个新的RDD
#1. 不产生Shuffle的
map(对一条数据进行处理) filter(一条一条过滤) mapPartitionsWithIndex(获取分区编号) mapPartitions(以分区为单位进行操作) mapPartitions(连接数据库)
keys values mapvalues(dui对偶元组中的v进行处理) FlatMapValues Union(将两个RDD合并)
sparkContext
spark程序的灵魂,用来创建最开始的RDD
在创建SparkContext过程中,创建了RpcEndPoint, DAGScheduler, TaskSchdeuler, ShuffleManger, BlockMangager等, 这些统称为Dirver
一个SparkContext就对应一个Dirver
一个Application中只能有一个SparkContext
使用SparkContext创建最原始的RDD
map与mapPartitions的区别:
map是调用迭代器的map方法,将值一个一个取出来放入到函数中进行操作
mappartitions是将迭代器放入到函数中进行操作, 后期如果还需要处理就使用mappartitions
在进行数据库连接时,使用map方法需要一个值连接数据库,而mapPartitions可以一个迭代器(对应一个分区)连接一次数据库
map:做映射,处理的单位是一条数据 底层new的是MapPartitionsRDD,传入一个函数,函数有三个参数(TaskContext, Index, Interater), 对Iterater进行map,传入你指定的映射函数
filter :一条一条的过滤,返回true的保留 底层new的是MapPartitionsRDD,传入一个函数,函数有三个参数(TaskContext, Index, Interater), 对Iterater进行filter,传入你指定的过滤函数
package org.apache.spark.day02
import org.apache.spark.rdd.MapPartitionsRDD
import org.apache.spark.{SparkConf, SparkContext}
/*
map filter
对RDD进行操作,其实是对RDD中每个分区对应的迭代器进行操作,迭代器会对每一个分区内的数据进行操作
*/
object MapPartitionsRDDDemo {
def main(args: Array[String]): Unit = {
//setMaster设置为本地模式
val conf = new SparkConf().setAppName("MapDemo").setMaster(