# 只是定义操作,获取最终的结果需要调rdd.collect()、rdd.count()等获取rdd信息的函数,才会真正执行定义的函数.有点类似于tensorflow中定义的计算图. 要求func有返回值,否则需要像foreachPartition底层那样包装下才能执行count()等.
rdd = rdd.mapPartitions(func)
rdd Action操作:用于RDD的操作(返回类型为None),它指示Spark执行计算并将结果发送回驱动程序. eg:foreach、foreachPartition、count等. 底层均调的mapPartitions
# 直接执行自定义函数
rdd.foreachPartition(func)
# rdd不支持操作字典,并且sc.parallelize函数的参数c一般均传的list
若想最终map操作后得到一个字典有以下两种方法:
方法1:func返回[(key1,val1),(key2,val2),...],即类似namedtuple(推荐)
def func(arr): res = [] for val in arr: res.append((str(val), val)) return res values = list(range(20)) rdd = sc.parallelize(values, numSlices=4) rdd = rdd.mapPartitions(func) res = rdd.collectAsMap() # rdd.collect()返回的是list,若rdd为字典则会返回list(keys)
方法2:func返回[dict]
def func(arr): res = {} for val in arr: res[str(val)] = val return [res] values = list(range(20)) rdd = sc.parallelize(values, numSlices=4) rdd = rdd.mapPartitions(func) res = rdd.collect() result = {} for val in res: result.update(val)
获取spark-submit命令传入的spark配置参数:
spark-submit --name myApp2 --master local --deploy-mode client --driver-cores 1 --driver-memory 4G --num-executors 2 --executor-memory 2G --executor-cores 2 spark_main.py
# driver与executor相关参数只在yarn模式下才有值 def printConf(conf: SparkConf): print('All: ', conf.getAll()) print('spark.driver.cores: ', conf.get('spark.driver.cores')) print('spark.driver.memory: ', conf.get('spark.driver.memory')) print('spark.executor.memory: ', conf.get('spark.executor.memory')) print('spark.executor.num: ', conf.get('spark.executor.num')) print('spark.executor.cores: ', conf.get('spark.executor.cores')) print('spark.app.name: ', conf.get('spark.app.name')) print('spark.master: ', conf.get('spark.master'))
sc.parallelize:划分
总数量为n,partition数量为m(n>m),a=n//m,b=n%m:
若b > a:则余数会按a为单位划分成多份,分别叠加到b//a个partition上,b%a给到另一个partition上; (而不是以1为单位)
若b <=a:则直接随机迭加到某个partition上.
广播变量的使用:对于比较占内存且一般为只读的在多个任务中用到的变量,推荐定义成广播变量(一般是全局变量)。
详见:https://www.jianshu.com/p/3bd18acd2f7f
https://www.cnblogs.com/jiangzhengjun/p/7262544.html
https://www.cnblogs.com/xlturing/p/6652945.html#