【pyspark】parallelize和broadcast文件落盘问题(后续)

文章探讨了PySpark中广播变量的使用与管理问题,特别是在无限循环中如何避免因广播变量累积导致的磁盘空间耗尽。提出了在每个循环结束后清理临时目录中广播变量文件的方法。

之前写过一篇文章,pyspark】parallelize和broadcast文件落盘问题,这里后来倒腾了一下,还是没找到 PySpark 没有删掉自定义类型的广播变量文件,因为用户的代码是一个 While True 的无限循环,类似下面的逻辑(下面的代码实际上 destroy 是可以删除落盘的广播变量文件的,但是用户的代码删不掉,因为没有仔细研究用户的代码 ,所以其实这个问题我感觉也不算 PySpark 的问题,只是在帮用户解决问题的时候另辟蹊径了 ,所以就记录下来了)。

class KK:
    def __init__(self):
        self._dummy = 'kk' * 10000000
        self.m = 'k'

def test(k):
    return k.value.m

def run():
    k = KK()
    a = sc.parallelize(list(range(1000)))
    broad_k = sc.broadcast(k)
    kk = a.map(lambda x: test(broad_k))
    kk.collect()
    broad_k.destroy()

while True:
    run()

Driver 的磁盘大小有效,如果这些变量文件不删除,迟早会把磁盘刷爆,Driver 进程就可能会挂掉,所以后来想到一个比较猥琐的方法 ,就是每次 loop 结束之前,或者下一个 loop 开始之后,把临时目录的文件删一次 ,因为广播变量的文件路径是固定,这个在 python 里还是很好实现的。

### PySparkparallelize 方法的使用与示例 在 PySpark 中,`parallelize` 是一种将本地数据转换为分布式 RDD(弹性分布式数据集)的方法。通过 `parallelize` 方法,用户可以将 Python 列表或其他本地数据结构并行化,从而在 Spark 集群上进行分布式计算[^1]。 以下是 `parallelize` 方法的核心功能用法: #### 1. 基本语法 `parallelize` 方法由 SparkContext 提供,其基本语法如下: ```python sc.parallelize(data, numSlices=None) ``` - `data`: 要并行化的本地数据集合,通常是一个列表或数组。 - `numSlices`: 可选参数,指定数据被划分为多少个分区。如果未指定,默认值取决于 Spark 的配置[^3]。 #### 2. 示例代码 以下是一些使用 `parallelize` 方法的示例: ##### 示例 1: 计算 Pi (莱布尼兹方法) 此示例展示了如何使用 `parallelize` 并行化一组整数以计算 Pi 的近似值。 ```python from pyspark import SparkContext sc = SparkContext("local", "Pi Leibniz approximation") iteration = 10000 partition = 4 # 创建一个从 0 到 iteration-1 的列表,并将其并行化 data = range(0, iteration) distIn = sc.parallelize(data, partition) # 使用 map reduce 计算 Pi result = distIn.map(lambda n: (1 if n % 2 == 0 else -1) / float(2 * n + 1)).reduce(lambda a, b: a + b) print("Pi is roughly %f" % (result * 4)) ``` ##### 示例 2: 概率计算方法 另一个示例是通过随机点生成来估算 Pi 的值。 ```python from __future__ import print_function import sys from random import random from operator import add from pyspark.sql import SparkSession spark = SparkSession.builder.appName("PythonPi").getOrCreate() partitions = int(sys.argv[1]) if len(sys.argv) > 1 else 2 n = 100000 * partitions def f(_): x = random() * 2 - 1 y = random() * 2 - 1 return 1 if x ** 2 + y ** 2 <= 1 else 0 # 并行化范围 [1, n+1] count = spark.sparkContext.parallelize(range(1, n + 1), partitions).map(f).reduce(add) print("Pi is roughly %f" % (4.0 * count / n)) spark.stop() ``` ##### 示例 3: 处理 CSV 数据 下面的示例展示了如何使用 `parallelize` 将本地数据加载为 DataFrame 并执行 SQL 查询。 ```python from pyspark import SparkConf, SparkContext from pyspark.sql import SparkSession, Row conf = SparkConf().setMaster("local").setAppName("First_App") sc = SparkContext(conf=conf) spark = SparkSession.builder.appName("PythonSQL").getOrCreate() # 创建本地数据 data = [ ("Alice", 25), ("Bob", 30), ("Charlie", 35) ] # 并行化数据 rdd = sc.parallelize(data) # 转换为 DataFrame df = rdd.map(lambda row: Row(name=row[0], age=row[1])).toDF() # 注册临时视图 df.createOrReplaceTempView("people") # 执行 SQL 查询 spark.sql("SELECT * FROM people WHERE age > 25").show() ``` #### 3. 注意事项 - **分区数**: `parallelize` 的第二个参数决定了数据的分区数。分区越多,数据越分散,但过高的分区数可能导致性能下降[^3]。 - **数据大小**: `parallelize` 适用于小型本地数据集。对于大型文件,建议使用 `textFile` 或其他方法直接从外部存储加载数据[^2]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值