Spark之RDD内核原理,数据共享,RDD算子优化利用累加器避免shuffle阶段

        在 Spark 中,RDD(Resilient Distributed Dataset,弹性分布式数据集)是其核心概念之一。以下是关于 Spark 中 RDD 的内核原理、数据共享以及广播变量和累加器的介绍:

目录

一、RDD 内核原理

1,弹性

2,分布式

3,不可变

二、数据共享

2-1,广播变量

2-1-1,概念

2-1-2,优势

2-1-3,使用方法

2-2,累加器

2-2-1,概念

2-2-2,优势

2-2-3,使用方法

三,总结


一、RDD 内核原理

1,弹性

  • RDD 具有弹性的特点,主要体现在以下几个方面:
    • 自动进行内存和磁盘数据存储的切换。如果内存不足,RDD 可以自动将部分数据存储到磁盘上,以避免内存溢出。
    • 基于 Lineage(血统)机制实现容错。当某个 RDD 的分区数据丢失时,可以通过其血统关系,即从父 RDD 重新计算该分区,而不是从原始数据重新计算整个 RDD。
    • 可以根据数据的局部性进行计算任务的调度,提高数据处理的效率。

2,分布式

  • RDD 是分布式的数据结构,数据被分割成多个分区,分布在不同的节点上进行并行计算。
  • Spark 可以根据集群的资源情况自动进行任务的分配和调度,充分利用集群的计算能力。

3,不可变

  • RDD 是不可变的数据结构,一旦创建就不能修改。对 RDD 的操作会返回一个新的 RDD,而不会修改原始的 RDD。
  • 这种不可变性使得 RDD 可以进行高效的并行计算,同时也方便了 Spark 的任务调度和容错处理。

二、数据共享

在 Spark 中,数据共享可以通过多种方式实现,其中广播变量和累加器是两种常用的机制。

2-1,广播变量

 

     如果我们要在分布式计算里面分发大的变量数据,这个都会由Driver端进行分发,一般来讲,如果这个变量不是广播变量,那么每个task就会分发一份,这在task数目十分多的情况下Driver的带宽会成为系统的瓶颈,而且会大量消耗task服务器上的资源,如果将这个变量声明为广播变量,那么每个executor拥有一份,这个executor启动的task会共享这个变量,节省了通信的成本和服务器的资源。

核心目的:

        减少task线程对应变量的定义,节省内存空间

2-1-1,概念

  • 广播变量是一种在 Spark 集群中共享数据的机制。它可以将一个只读的变量广播到所有的节点上,使得每个节点都可以访问这个变量,而不需要在每个任务中都传输这个变量。
  • 广播变量通常用于在多个任务中共享一个较大的只读数据集,如字典、配置文件等。

2-1-2,优势

  • 减少数据传输:通过广播变量,可以将数据一次性广播到所有的节点上,而不是在每个任务中都传输这个数据。这样可以大大减少数据传输的开销,提高程序的性能。
  • 提高内存利用率:由于每个节点只需要存储一份广播变量的数据,而不是在每个任务中都存储一份,因此可以提高内存的利用率。

2-1-3,使用方法

  • 创建广播变量:可以使用 SparkContext.broadcast() 方法创建一个广播变量。例如:
     from pyspark import SparkContext

     sc = SparkContext()
     data = [1, 2, 3, 4, 5]
     broadcast_data = sc.broadcast(data)
  • 访问广播变量:在任务中,可以通过广播变量的 value 属性访问广播变量的数据。例如:
     def process_data(partition):
         for element in partition:
             result = element * broadcast_data.value[0]
             yield result

     rdd = sc.parallelize([1, 2, 3, 4, 5], 2)
     result_rdd = rdd.mapPartitions(process_data)
     print(result_rdd.collect())
# 广播变量
from pyspark import SparkContext


sc  = SparkContext()

num = 10
# 将变量定义成广播变量
b_obj = sc.broadcast(num)

rdd = sc.parallelize([1,2,3,4])

# 转化计算
def func(x):
    # 广播变量无法修改
    # b_obj.value=20
    # 获取广播变量值
    return x+b_obj.value

rdd_map = rdd.map(func)

# 查看数据
res = rdd_map.collect()
print(res)

2-2,累加器

2-2-1,概念

目的:

  • 防止资源抢占的时候,计算不准确的问题
  • 利用累加器避免shuffle阶段

  • 累加器是一种在 Spark 集群中进行分布式计数或求和等操作的机制。它可以在多个任务中对一个变量进行累加,而不需要在每个任务中都将结果返回给驱动程序进行累加。
  • 累加器通常用于在分布式计算中进行计数、求和、求平均值等操作。

2-2-2,优势

  • 高效的分布式计算:通过累加器,可以在多个任务中对一个变量进行累加,而不需要在每个任务中都将结果返回给驱动程序进行累加。这样可以大大提高分布式计算的效率。
  • 方便的错误处理:如果在计算过程中出现错误,可以通过累加器的值来判断哪些任务出现了错误,从而进行相应的错误处理。

2-2-3,使用方法

创建累加器:可以使用 SparkContext.accumulator() 方法创建一个累加器。例如:

     from pyspark import SparkContext

     sc = SparkContext()
     accumulator = sc.accumulator(0)
  • 累加操作:在任务中,可以通过累加器的 add() 方法对累加器进行累加操作。例如:
     def process_data(partition):
         for element in partition:
             accumulator.add(element)

     rdd = sc.parallelize([1, 2, 3, 4, 5], 2)
     rdd.foreachPartition(process_data)
     print(accumulator.value)
# 累加器
from pyspark import SparkContext


sc  = SparkContext()

num = 10
# 将变量定义成累加器
a_obj = sc.accumulator(num)
# 生成rdd
rdd = sc.parallelize([1,2,3,4])

# 对rdd进行计算
def func(x):
    print(x) # 输出rdd中元素数据
    # 对累加器的值进行修改 每次加1
    a_obj.add(1)
    return (x,1)

rdd_map = rdd.map(func)

# 查看数据
res = rdd_map.collect()
print(res)

# 查看累加器的数据
print(a_obj.value)

三,总结

        总之,RDD 是 Spark 的核心概念之一,其内核原理包括弹性、分布式和不可变等特点。

        数据共享可以通过广播变量和累加器等机制实现,广播变量可以将一个只读的变量广播到所有的节点上,减少数据传输的开销;

        累加器可以在多个任务中对一个变量进行累加,提高分布式计算的效率。在使用这些机制时,需要注意合理地选择数据共享的方式,以提高程序的性能和可扩展性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值