构建RDD对象的方式主要有二种
1- 通过parallelized Collections构建RDD: 并行本地集合方式 (测试)
2- 通过 External Data构建RDD: 加载外部文件的方式 (测试/开发)
1 通过并行化本地的方式构建RDD
代码实现
from pyspark import SparkContext, SparkConf
import os
# 锁定远端环境, 确保环境统一
os.environ['SPARK_HOME'] = '/export/server/spark'
os.environ['PYSPARK_PYTHON'] = '/root/anaconda3/bin/python3'
os.environ['PYSPARK_DRIVER_PYTHON'] = '/root/anaconda3/bin/python3'
if __name__ == '__main__':
print("如何构建RDD方式一: 并行本地集合")
# 1. 创建SparkContext核心对象
conf = SparkConf().setAppName("create_rdd_01").setMaster("local[2]")
sc = SparkContext(conf=conf)
# 2. 读取数据集: 本地集合
rdd_init = sc.parallelize([1, 2, 3, 4, 5, 6, 7, 8, 9, 10],3)
# 3. 打印结果数据
print(rdd_init.collect())
print(rdd_init.getNumPartitions()) # 获取这个RDD有多少个分区
print(rdd_init.glom().collect()) # 获取每个分区中的数据
# 4- 释放资源
sc.stop()
相关的API:
查看分区数量API:
rdd.getNumPartitions()
查看每个分区数据的API:
rdd.glom().collect()
构建RDD的API:
parallelize(参数1,参数2)
参数1: 设置本地列表
参数2: 设置有多少个分区
通过本地列表的方式构建RDD, 其RDD初始的分区数量如何确定:
1- 默认与setMaster设置的线程的数量保持一致: 比如 local[3] 表示默认有三个分区, 如果集群模式 默认为2
2- local[*]: * 对应的数值是与当前节点的CPU核心数保持一致
3- 如果想要改变RDD的分区数量:
方式一: 在local模式下, 直接修改 setMaster中的local N 即可,
方式二: 修改 parallelize的参数2的设置, 设置多少, 那么就有多少个分区,一般建议小于setMaster设置
2 通过读取外部数据源方式
代码演示:
from pyspark import SparkContext, SparkConf
import os
# 锁定远端环境, 确保环境统一
os.environ['SPARK_HOME'] = '/export/server/spark'
os.environ['PYSPARK_PYTHON'] = '/root/anaconda3/bin/python3'
os.environ['PYSPARK_DRIVER_PYTHON'] = '/root/anaconda3/bin/python3'
if __name__ == '__main__':
print("如何构建RDD方式二: 读取外部数据集")
# 1. 创建SparkContext核心对象
conf = SparkConf().setAppName("create_rdd_02").setMaster("local[*]")
sc = SparkContext(conf=conf)
# 2. 读取数据集:
rdd_init = sc.textFile("file:///export/data/workspace/ky06_pyspark/_02_SparkCore/data/")
# 3. 打印结果
print(rdd_init.collect())
print(rdd_init.getNumPartitions())
print(rdd_init.glom().collect())
"""
[
[
'hadoop hive hive hadoop sqoop',
'sqoop kafka hadoop sqoop hive hive',
'hadoop hadoop hive sqoop kafka kafka'
],
[
'kafka hue kafka hbase hue hadoop hadoop hive',
'sqoop sqoop kafka hue hue kafka'
]
]
[
['hadoop hive hive hadoop sqoop', 'sqoop kafka hadoop sqoop hive hive'],
['hadoop hadoop hive sqoop kafka kafka'],
['kafka hue kafka hbase hue hadoop hadoop hive'],
[],
['sqoop sqoop kafka hue hue kafka']]
"""
# 4- 释放资源
sc.stop()
说明: 分区数据确认, 以当前看到的现象为准
1- 与setMaster关系不大, 但是当设置为1的时候, 有用, 往大没有用
2- 可以在textFile中设置最小分区数量, 但是实际这个RDD的分区数量可能会大于等于设置最小分区数
3- 默认的情况下, 读取多个文件的时候, 有多少个文件, 一般会至少产生多少个分区
处理小文件的操作:
from pyspark import SparkContext, SparkConf
import os
# 锁定远端环境, 确保环境统一
os.environ['SPARK_HOME'] = '/export/server/spark'
os.environ['PYSPARK_PYTHON'] = '/root/anaconda3/bin/python3'
os.environ['PYSPARK_DRIVER_PYTHON'] = '/root/anaconda3/bin/python3'
if __name__ == '__main__':
print("如何构建RDD方式三: 读取外部数据集--小文件处理")
# 1. 创建SparkContext核心对象
conf = SparkConf().setAppName("create_rdd_03").setMaster("local[*]")
sc = SparkContext(conf=conf)
# 2. 读取外部的文件数据集:
# wholeTextFiles 专门用于处理小文件的API, 默认情况下, 尽可能技术那好分区的数量
rdd_init = sc.wholeTextFiles(path='file:///export/data/workspace/ky06_pyspark/_02_SparkCore/data/',minPartitions=2)
# 3. 打印结果
print(rdd_init.collect())
print(rdd_init.getNumPartitions())
print(rdd_init.glom().collect())
"""
[
[
('file:/export/data/workspace/ky06_pyspark/_02_SparkCore/data/words.txt', 'hadoop hive hive hadoop sqoop\r\nsqoop kafka hadoop sqoop hive hive\r\nhadoop hadoop hive sqoop kafka kafka\r\nkafka hue kafka hbase hue hadoop hadoop hive\r\nsqoop sqoop kafka hue hue kafka'),
('file:/export/data/workspace/ky06_pyspark/_02_SparkCore/data/a.txt', 'hadoop hive hive hadoop sqoop\r\nsqoop kafka hadoop sqoop hive hive\r\nhadoop hadoop hive sqoop kafka kafka\r\nkafka hue kafka hbase hue hadoop hadoop hive\r\nsqoop sqoop kafka hue hue kafka'),
('file:/export/data/workspace/ky06_pyspark/_02_SparkCore/data/b.txt', 'hadoop hive hive hadoop sqoop\r\nsqoop kafka hadoop sqoop hive hive\r\nhadoop hadoop hive sqoop kafka kafka\r\nkafka hue kafka hbase hue hadoop hadoop hive\r\nsqoop sqoop kafka hue hue kafka')
],
[
('file:/export/data/workspace/ky06_pyspark/_02_SparkCore/data/c.txt', 'hadoop hive hive hadoop sqoop\r\nsqoop kafka hadoop sqoop hive hive\r\nhadoop hadoop hive sqoop kafka kafka\r\nkafka hue kafka hbase hue hadoop hadoop hive\r\nsqoop sqoop kafka hue hue kafka'),
('file:/export/data/workspace/ky06_pyspark/_02_SparkCore/data/d.txt', 'hadoop hive hive hadoop sqoop\r\nsqoop kafka hadoop sqoop hive hive\r\nhadoop hadoop hive sqoop kafka kafka\r\nkafka hue kafka hbase hue hadoop hadoop hive\r\nsqoop sqoop kafka hue hue kafka'),
('file:/export/data/workspace/ky06_pyspark/_02_SparkCore/data/e.txt', 'hadoop hive hive hadoop sqoop\r\nsqoop kafka hadoop sqoop hive hive\r\nhadoop hadoop hive sqoop kafka kafka\r\nkafka hue kafka hbase hue hadoop hadoop hive\r\nsqoop sqoop kafka hue hue kafka')
]
]
"""
# 4- 释放资源
sc.stop()
减少分区的数量, 可以减少整个Spark应用程序的线程数量, 默认情况下, 一个分区对应着一个线程
扩展: RDD的分区数量是如何确定的
1- 分区数量(线程数量) 一般设置为CPU核数2~3倍
2- RDD的分区数量,取决于多个因素: 调用任务设置CPU核数, 调用对于API设置分区数量, 以及本身读取文件分区数量
2.1 当初始化SparkContext的时候, 其实确定了一个基本的并行度参数:
参数: spark.default.parallelism
值: 默认为CPU核数, 如果是集群至少为2,如果是Local[N]模式, 取决于 N, N为多少, 即为多少并行度
2.2 如果调用者通过parallelism API来构建RDD:
分区数量:
如果没有指定分区数, 就使用spark.default.parallelism
如果指定分区数量, 取决于自己设置的分区数
2.3 如果调用者通过textFile(path,minPartition): 分区确定
取决于以下几个参数:
defaultMinPartition:
值:
如果没有指定 minPartition,此值为: min(spark.default.parallelism,2)
如果设置minPartition,取决于自己设置的分区数
对于读取本地文件来说: 判断标准
RDD分区数 = max(本地文件分片数, defaultMinPartition)
对于读取HDFS文件: 判断标准
RDD分区数 = max(文件的Block块数量, defaultMinPartition)