spark学习使用记录
之前一直也在用storm与spark进行开发,最近从头梳理了一下,整个的学习使用过程,一点一点记录
我是学java的,上手就是javaapi
先说一下我对spark-yarn管理的理解,程序是driver,提交到resourcemanage中,申请资源(excutor个数,core个数等等),如果有资源,则允许运行,分配到各个worknode中,一个分区对应一个task,分区与并发有很大关系,当然并发也决定于cores
先来一个完整开发例子
SparkConf--spark有很多参数设置,你也可以不设置直接用默认的
有本地模式,yarn模式(yarn-client(可以交互),yarn-cluster(一次操作)),独立集群模式
SparkConfconf=newSparkConf().setAppName("Spark开发开始").setMaster("local");
SparkConfconf=newSparkConf().setMaster("yarn-client").setAppName("开发任务");
构建入口
JavaSparkContextsc=newJavaSparkContext(conf);
spark进程管理:
spark.storage.safetyFraction默认值为0.9spark为了保证内存的足够使用,避免OOM,只允许使用JVM内存*0.9
spark.storage.memoryFraction默认值为0.6spark一个进程中用于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")
---rddtextFile(读文件),可以设置分区
---rddbinaryFiles(二进制文件读取),同上
---rddnewAPIHadoopRDD(读取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)----将元素映射为<String,String>结构,但是很奇怪,map已经能做到相同的事情了啊,这个还有什么优势吗?
tranformation和action
transformation的输入是RDD,输出也是RDD。action的输入是RDD,输出是一个值,通常是在Spark程序的末尾被调用,得到一个计算结果。
transformation和action最大的区别在于,transformation遵循缓式计算(lazyevaluation),程序内部执行tranformation调用之后,并不立即进行计算,直到某个action被调用,才会进行真正的计算。结合下文提到的DAG,优化了程序的执行效率。
Spark中大部分API提供的都是transformation操作,如代码示例中的map,filter及flatmap,少数API提供action操作,如count和reduce