我是学java的,上手就是java api
先说一下我对spark-yarn管理的理解,程序是driver,提交到resourcemanage中,申请资源(excutor个数,core个数等等),如果有资源,则允许运行,分配到各个worknode中,一个分区对应一个task,分区与并发有很大关系,当然并发也决定于cores
先来一个完整开发例子
SparkConf--spark有很多参数设置,你也可以不设置直接用默认的
有本地模式,yarn模式(yarn-client(可以交互),yarn-cluster(一次操作)),独立集群模式
SparkConf conf = new SparkConf().setAppName("Spark 开发开始").setMaster("local");
SparkConf conf=new SparkConf().setMaster("yarn-client").setAppName("开发任务");
构建入口
JavaSparkContext sc = new JavaSparkContext(conf);
spark进程管理:
spark.storage.safetyFraction 默认值为0.9 spark为了保证内存的足够使用,避免OOM,只允许使用JVM内存*0.9
spark.storage.memoryFraction 默认值为0.6 spark一个进程中用于storage的值,这个值是基于之前的0.9安全内存的,为总内存的0.9*0.6=0.54
shuffle使用内存情况:堆大小 * spark.shuffle.safetyFraction * spark.shuffle.memoryFraction 默认为0.2和0.8即堆大小的0.16
RDD、Transformation、Actions
RDD是数据集合
---rdd可以创建一个空的emptyRDD()
---rdd可以通过parallelize来创建,可以指定分区数量,如果不指定按spark.default.parallelism来(主要针对数字数组)--conf.set("spark.default.parallelism", "500")
---rdd textFile(读文件),可以设置分区
---rdd binaryFiles(二进制文件读取),同上
---rdd newAPIHadoopRDD(读取hbase),实际与java客户端读取没什么区别
---objectFile(读取对象?没用过)
分区很关键,分区少了,可能会执行慢,而且单个任务消耗内存多,分区太多也不好
分区直接决定了task的并行度的可能(因为还有cpu核数限制)
Transformation是数据集合转换,不会提交任务,只是记住了这个逻辑
Actions才会提交job
map(function)----将rdd重新装载一次,按你需要的格式(比如map,比如类等)
filter(function)----将rdd过滤一次,返回true的是需要的
flatMap(function)----将一条记录处理成多条记录,map完成之后数据量还是N,flatMap完成之后数据量会变成M,M>n;
mapPartitions(function)-----按分区处理数据,有几个分区就处理几次(如果每次处理都需要new一个对象,比例连数据库或者其他等等,这个时候用这个就合适)
mapToPair(function)----将元素映射为
tranformation 和 action
transformation 的输入是RDD,输出也是RDD。action的输入是RDD,输出是一个值,通常是在Spark程序的末尾被调用,得到一个计算结果。
transformation和action最大的区别在于,transformation 遵循缓式计算(lazy evaluation), 程序内部执行tranformation调用之后,并不立即进行计算,直到某个action被调用,才会进行真正的计算。结合下文提到的DAG,优化了程序的执行效率。
Spark中大部分API提供的都是transformation操作,如代码示例中的map, filter 及 flatmap, 少数API提供action操作,如count 和 reduce