RDD之collect方法执行的过程

本文介绍了Spark集群中collect方法的执行过程。集群有master和worker节点,提交任务时启动driver进程,master找合适worker节点启动executor,driver生成task分发执行。执行collect时,driver收集worker计算结果。同时提醒,数据量大时不应先汇总到driver,应直接保存executor数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先来看一张图:
在这里插入图片描述
spark集群中有master节点和Worker节点,master节点负责任务调度,worker节点负责计算。

当集群启动时,worker节点会向master注册,并且定期向master发送心跳。

当我们向集群提交任务时,会启动一个进程spark-submit,这个进程也叫做driver。这个进程先要连接master,然后master会通过注册信息找到合适的worker节点去计算这个任务。这里所谓合适的worker节点,就是内存满足条件的,如果集群中没有内存满足条件的worker,那么这个任务就提交不上去了。

当找到合适的worker节点后,worker节点就会启动executor(进程),然后executor会通过master,worker节点知道driver的位置,然后和driver进行通信。

driver端会根据我们写的业务逻辑,切片,生成task,然后将这些task(是一个实例对象)分发给executor去执行,task中记录着计算逻辑,分区中记录着将来要从哪里读取数据。

executor要通过网络把数据读过去进行计算,(如果数据量很大,他会边读边计算),在executor中,task会将数据进行计算,计算的结果在worker上。

当执行collect时,driver端会将worker上的计算结果通过网络收集回去,放到Array中。(在存放到Array中的时候,会根据分区编号的顺序进行存放)

注意

在我们平时应用过程中,我们通常要把计算好的数据存放到HDFS,数据库中,如果我们都要先将数据汇总到driver端再存到数据库,那么当数据量很大的时候,driver端就会存放不下。所以我们应该直接把executor上计算好的数据保存进数据库。

在开发过程中,我们要尽可能使用foreach和foreachPartition方法,详细讲解请看博客:
https://blog.youkuaiyun.com/weixin_43866709/article/details/88667288

### RDD 常用方法及其用法 #### 1. **Transformation 方法** Transformations 是一种懒加载的操作,它们不会立即执行,而是定义了一个新的 RDD。只有当触发 Action 操作时,才会真正执行 Transformation。 - **`map(func)`**: 对 RDD 中的每一个元素应用 `func` 函数,并返回一个新的 RDD[^3]。 ```python rdd = sc.parallelize([1, 2, 3]) mapped_rdd = rdd.map(lambda x: x * 2) ``` - **`filter(func)`**: 返回一个新的 RDD,其中只包含满足条件的元素。 ```python filtered_rdd = rdd.filter(lambda x: x % 2 == 0) ``` - **`flatMap(func)`**: 类似于 `map`,但是它会对每个输入项生成零个或多个输出项。 ```python flat_mapped_rdd = rdd.flatMap(lambda x: range(x)) ``` - **`groupByKey()`**: 当处理键值对形式的数据时,此操作会将具有相同 key 的 value 聚合在一起。 ```python kv_rdd = sc.parallelize([(1, 'a'), (1, 'b'), (2, 'c')]) grouped_rdd = kv_rdd.groupByKey() ``` - **`reduceByKey(func)`**: 和 `reduce` 类似,但它仅应用于每组共享同一个 key 的数据。 ```python reduced_rdd = kv_rdd.reduceByKey(lambda a, b: a + b) ``` - **`join(otherDataset, [numTasks])`**: 执行两个 RDD 的内连接操作,适用于键值对型 RDD[^5]。 ```python other_kv_rdd = sc.parallelize([(1, 'A'), (2, 'B')]) joined_rdd = kv_rdd.join(other_kv_rdd) ``` --- #### 2. **Action 方法** Actions 是实际触发计算的操作,它们会返回最终的结果或者写入外部存储系统。 - **`collect()`**: 将整个 RDD 收集到驱动程序中作为一个列表返回。 ```python result_list = rdd.collect() ``` - **`count()`**: 计算 RDD 中的元素数量。 ```python count_value = rdd.count() ``` - **`take(n)`**: 获取前 n 个元素,通常用于调试目的[^2]。 ```python first_n_elements = rdd.take(5) ``` - **`foreach(func)`**: 对 RDD 中的每个元素逐一调用 func 函数。 ```python rdd.foreach(print) ``` - **`saveAsTextFile(path)`**: 将 RDD 数据保存为文本文件。 ```python rdd.saveAsTextFile("/path/to/output") ``` --- #### 3. **持久化机制** 为了优化性能,可以使用缓存功能来减少重复计算的时间开销。 - **`cache()`**: 缓存当前 RDD 到内存中以便后续重用[^1]。 ```python cached_rdd = rdd.cache() ``` - **`persist(storageLevel)`**: 提供更细粒度的控制选项指定如何以及在哪里存储该 RDD。 ```python from pyspark import StorageLevel persisted_rdd = rdd.persist(StorageLevel.MEMORY_AND_DISK) ``` --- #### 4. **其他重要概念** - **Partitioning**: 每个 RDD 可以划分为若干分区,在集群的不同节点上运行。 - **Lineage Graph**: 如果某个分区丢失,则可以通过其血统图重新构建而无需完全重启作业。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值