Spark 的 Broadcast 和 Accumulator 的使用
适合使用 Broadcast 的场景
- 如果希望 driver 和每个 executor 读到的变量值是一致的
- 如果有的变量存储的数据比较大,希望在每个 executor 都只初始化一遍
broadcast 的变量是在 driver 初始化的,然后将 broadcast 变量的元数据传给 executor,当 executor 使用 broadcast 的时候先在本地查找,如果没有就从 driver 拉取一份,然后存在本地
由于 broadcast 是在 driver 初始化并分发到各个 executor 的,并且 broadcast 是只读的,所以能保证一致性,即 driver 和各个 executor 读到的数据是一致的
如果不用 broadcast 那么每次运行 task 都需要或者初始化变量,或者由 driver 启动 task 的时候传递变量,这样做一般没问题,但如果变量存储的数据比较大,效率就低了,使用了 broadcast 后可以保证每个 executor 只从 driver 拉取一次数据,后续的 task 可以重复使用
例子
val data = List(1, 2, 3, 4, 5, 6)
val bdata = sc.broadcast(data)
val rdd = sc.parallelize(1 to 6, 2)
val observedSizes = rdd.map(_ => bdata.value.size)
注意由于 driver 传到 executor 需要序列化,一些序列化不了的变量无法使用 broadcast
如果需要跨多个 task 统计数据,就可以使用累加器 Accumulator
例子
// scala
val accum = sc.longAccumulator("My Accumulator") // Accumulator 可以有名字,在 Spark UI 可以看到
sc.parallelize(Array(1, 2, 3, 4)).foreach(x => accum.add(x))
accum.value
# python
accum = sc.accumulator(0) # Accumulator 初始值是 0
sc.parallelize([1, 2, 3, 4]).foreach(lambda x: accum.add(x))
accum.value
scala 和 python 的用法不一样
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 提示词工程——AI应用必不可少的技术
· 地球OL攻略 —— 某应届生求职总结
· 字符编码:从基础到乱码解决
· SpringCloud带你走进微服务的世界