目录
0 参考列表
1 概念
2 特性
2.1 依赖关系
2.2 缓存和持久化
3 分类
3.1 创建操作
3.2 转换操作
3.2.1 单value类型的转换算子
3.2.2 双value类型的转换算子
3.2.3 KV对类型的转换算子
3.3 行为操作
3.4 缓存操作
4 共享变量
4.1 累加器
4.2 广播变量
5 开发
SparkCore入门编程https://blog.csdn.net/weixin_45682261/article/details/123765880Spak_java APIhttps://spark.apache.org/docs/latest/api/java/index.html
CSDN:java 累加器_Spark基础教程——累加器的使用(JAVA)https://blog.csdn.net/weixin_39555179/article/details/114349811
(1) 概念
①RDD(弹性分布式数据集):代表一个不可变的、多分区的、可以并行计算的数据集合.
②Pair RDD:以Key-Value形式存在的RDD.
(2) 特点
①自动容错:计算出错提供重试机制.
②缓存机制:可以临时缓存到内存或者磁盘,下游的RDD可直接从该处计算,提高查询效率.
①血缘关系:节点之间存在直接或间接依赖关系,多个节点的依赖关系构成血缘关系,每个节点都维护着本节点的血缘关系.当程序出错时,可通过血缘关系向上追溯到有数据的节点,重新计算恢复.
②窄依赖:父RDD的每个分区只被子RDD的一个分区所使用,子RDD分区通常对应一个父RDD分区.
③宽依赖:父RDD的每个分区都可能被多个子RDD分区所使用,子RDD分区通常对应所有的父RDD分区.
④Stage:根据RDD之间的依赖关系的不同将Job划分成不同的Stage,遇到一个宽依赖则划分一个Stage.Stage根据分区数划分成一个个的Task.
通过控制操作算子来实现.使用场景:①想要重用算子计算出来的数据;②某一个算子计算时间过长;③算子过多.
用于创建RDD.
(1) 直接创建
// parallelize
JavaRDD parallelize(Arrays.asList(5, 4, 3, 10);
(2) 读取文件或数据库
// textFile:读取文件来创建RDD
SparkContext.textFile("data/1.txt");
将一种类型的RDD转换成另一种类型的RDD.
(1) map
// map:将一个泛型为T的序列里的value映射成另外一个U类型的值,一对一映射
RDD[U] map(Function f)
// mapToPair:将一个泛型为T的序列里的value映射成另外一个U类型的值,以分区为单位
PairRDD[U,V] mapToPair(PairFunction f);
// flatMap:将元素扁平化,并做一一映射
RDD[U] flatMap[U](FlatFunction f)
(2) filter
// 用于过滤满足条件的数据,满足条件就返回,不满足就过滤
JavaRDD filter(f:T=>Boolean):RDD[T]
(3) group by
// groupBy:将元素按照指定的规则转成K,然后进行分组,的第二个参数是相同K对应的所有元素
rdd.groupBy[K](f:T=>K):RDD[(K,Iterator[T])]
(4) coalesce
// 收缩合并分区,减少分区的个数
JavaRDD coalesce(int numPartitions)
// unionAll:合并RDD
rdd1.unionAll(rdd2);
(1) keys
// 取出所有键值对中的key
rdd.keys()
(2) values
//values:所有键值对的value
rdd.values()
(3) mapValues
// mapValues:针对于Pair RDD,操作Value.
rdd.mapValues[U](f: V => U): RDD[(K, U)]
(4) reduceByKey
// 按照key进行分组,然后同组内的多个value做归约运算.
rdd(reduceByKey(func: (V, V) => V): RDD[(K, V)])
(5) sortByKey
// 对Key进行排序
rdd.sortByKey()
触发真正计算的算子.
(1) 无输出
foreach:用于在executor端口迭代,仅适用于Scala.
(2) 转成变量或集合
count:统计RDD里的数据量.
//collect:将 RDD 转为数组
List collect()
// first:取出第一行数据
String first()
// take:取出前n行数据
List take(int n)
(3) 保存到文件或者数据库中.
用于缓存RDD.
// cache:底层调用的是persist,存储到内存中
rdd.cache()
// persist:产生临时文件,程序结束后就释放
/* 需要设置存储级别StorageLevel
* MEMORY_ONLY:数据只保存到内存中,如果内存存不下,则存不下的那些数据丢弃
* MEMORY_AND_DISK:先使用内存,内存不够时再使用磁盘
* DISK_ONLY
* DISK_ONLY_2:存磁盘,副本2个
* MEMORY_ONLY_SER:内存并序列化
*/
rdd.persist(StorageLevel.DISK_ONLY)
// checkpoint机制:持久化保存
// 1 需要自定义存储位置
SparkContext.setCheckpointDir(path)
// 2 如果想从持久化文件中读取数据,需要配合cache方法
rdd.cache();
rdd.checkpoint();
Spark在集群的多个不同节点的多个任务上并行运行一个函数时,它会把函数中涉及到的每个变量,在每个任务上都生成一个副本.但有时需要在多个任务之间共享变量,或者在任务(Task)和任务控制节点(Driver Program)之间共享变量时,可使用共享变量.
累加器则支持在所有不同节点之间进行计数或者求和.在 Driver 程序中定义的变量,在Executor 端的每个 Task 都会得到这个变量的一份新的副本,每个 task 更新这些副本的值后,传回 Driver 端进行聚合.累加器有集合累加器, 浮点型累加器和整型累加器.
// 构建SparkSession
// 设置配置信息SparkConf
SparkConf conf = new SparkConf().setAppName("accumulator").setMaster("local[*]");
SparkSession ss = SparkSession.builder().config(conf).getOrCreate();
SparkContext sc = ss.sparkContext();
// 创建累加器
LongAccumulator la = sc.longAccumulator("la");
DoubleAccumulator da = sc.doubleAccumulator("da");
CollectionAccumulator ca = sc.collectionAccumulator("ca");
Dataset ds = ss.createDataset(Arrays.asList(5, 4, 3, 10), Encoders.INT());
// 使用累加器
Dataset mapDs = ds.map((MapFunction) x -> {
la.add(Long.valueOf(x.toString()));
da.add(Double.valueOf(x.toString()));
ca.add(x);
return x;
}, Encoders.INT());
mapDs.collect();
System.out.println("longAccumulator:" + la.value());
System.out.println("doubleAccumulator:" + da.value());
System.out.println("collectionAccumulator:" + ca.value());
每个节点的executor只拥有一份广播变量的数据,该executor上的所有的Task共用这一个只读变量.
// 由 SparkContext 调用
Broadcast broadcast(final T value)
(1) 引入依赖
3.1.1
2.3.0
2.11
org.apache.hadoop
hadoop-client
${hadoop.version}
org.apache.spark
spark-core_${scala.version}
${spark.version}
(2) 配置 log4j.properties,设置日志输出等级
# Set everything to be logged to the console
log4j.rootCategory=error,console
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.target=System.err
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%d{yy/MM/dd HH:mm:ss} %p %c{1}: %m%n
# Set the default spark-shell log level to WARN. When running the spark-shell, the
# log level for this class is used to overwrite the root logger's log level, so that
# the user can have different defaults for the shell and regular Spark apps.
log4j.logger.org.apache.spark.repl.Main=WARN
# Settings to quiet third party logs that are too verbose
log4j.logger.org.spark_project.jetty=WARN
log4j.logger.org.spark_project.jetty.util.component.AbstractLifeCycle=ERROR
log4j.logger.org.apache.spark.repl.SparkIMain$exprTyper=INFO
log4j.logger.org.apache.spark.repl.SparkILoop$SparkILoopInterpreter=INFO
log4j.logger.org.apache.parquet=ERROR
log4j.logger.parquet=ERROR
(3) 开发
// 构建 spark Context
SparkConf conf = new SparkConf().setAppName("wordcount").setMaster("local[2]");
JavaSparkContext jsc = new JavaSparkContext(conf);
// 终止
jsc.stop();