在spark中,map算子可以说是我们使用最频繁的一个基础算子,功能也非常简单,将一条数据经过变换形成另外一条数据。那么还有一个算子和它非常相似:mapPartition。
很显然,这个算子多了一个Partition,所以表示的含义就是:对于每一个分区的数据,整体进行数据的变换。
有人可能会问,难道map就不是对分区进行的?也是。不过map没有分区的概念,就是一条数据一条处理,也是分布式的处理,只是在map无法看到分区而已。
那么对于mapPartition算子,什么情况下会使用呢?这里例举两种最频繁的应用场景:
(1)数据频繁进行与外部交互的时候。
最典型的比如需要将分布式的数据data每条进行与数据库的增删改查操作。很自然的想法就是:
sc.parallelize(Seq(1, 2, 3, 4, 5))
.map{x =>
XXX // 连接数据库操作
XXX.insert(x) // 增删改查该数据到数据库
XXX// 关闭数据库
x
}
很显然这里采用直白的map操作,那么每条数据都会进行一次数据库的连接与关闭操作,显然是没有必要的。试想一下,其实每个分区的数据都在同一台机器上,那么对这个机器上的数据,其实只需要做一次数据库的连接与关闭操作不就行了?
这就自然引出了mapPartition算子。mapPartition本身会将一个分区的数据打包成一个迭代器统一操作。
还是刚才的例子,那么伪代码就是:
sc.parallelize(Seq(1, 2, 3, 4, 5))
.mapPartitions{iter =>
XXX //