ภูตผีปีศาจ เคล็ดลับ:
  เมื่อใดก็ตามที่คุณมีการกำหนดค่าเริ่มต้นที่มีน้ำหนักมากซึ่งควรทำครั้งเดียวสำหรับหลายRDDองค์ประกอบแทนที่จะเป็นหนึ่งครั้งต่อRDDองค์ประกอบและหากการเริ่มต้นนี้เช่นการสร้างวัตถุจากไลบรารีของบุคคลที่สามจะไม่สามารถทำให้เป็นอนุกรมได้ (เพื่อให้ Spark สามารถส่งข้ามคลัสเตอร์ไปยัง โหนดคนงาน) ให้ใช้แทนmapPartitions()
  จัดเตรียมสำหรับการเตรียมใช้งานครั้งเดียวต่องาน / เธรด / พาร์ติชันของผู้ปฏิบัติงานแทนที่จะเป็นหนึ่งครั้งต่อองค์ประกอบข้อมูลตัวอย่างเช่นดูด้านล่างmap()mapPartitions()RDD
val newRd = myRdd.mapPartitions(partition => {
  val connection = new DbConnection /*creates a db connection per partition*/
  val newPartition = partition.map(record => {
    readMatchingFromDB(record, connection)
  }).toList // consumes the iterator, thus calls readMatchingFromDB 
  connection.close() // close dbconnection here
  newPartition.iterator // create a new iterator
})
  ไตรมาสที่ 2 ไม่flatMapประพฤติเช่นแผนที่หรือชอบmapPartitions?
ใช่. โปรดดูตัวอย่างที่ 2 ของflatmap.. อธิบายตัวเอง
  ไตรมาสที่ 1 อะไรคือความแตกต่างระหว่าง RDD mapและmapPartitions
  
  mapทำงานฟังก์ชันที่ใช้ในระดับต่อองค์ประกอบในขณะที่
   mapPartitionsออกกำลังกายที่ระดับพาร์ติชัน
สถานการณ์สมมติตัวอย่าง :   ถ้าเรามี 100K องค์ประกอบโดยเฉพาะRDDพาร์ทิชันแล้วเราจะปิดไฟฟังก์ชั่นการใช้งานโดยการเปลี่ยนแปลงการทำแผนที่ 100K mapครั้งเมื่อเราใช้  
ในทางกลับกันถ้าเราใช้mapPartitionsเราจะเรียกใช้ฟังก์ชันนั้นเพียงครั้งเดียว แต่เราจะส่งผ่านในระเบียน 100K ทั้งหมดและรับการตอบกลับทั้งหมดในการเรียกใช้ฟังก์ชันเดียว
จะมีการเพิ่มประสิทธิภาพเนื่องจากmapทำงานกับฟังก์ชันเฉพาะหลาย ๆ ครั้งโดยเฉพาะอย่างยิ่งหากฟังก์ชันนั้นทำสิ่งที่มีราคาแพงในแต่ละครั้งที่ไม่จำเป็นต้องทำหากเราส่งผ่านองค์ประกอบทั้งหมดในครั้งเดียว (ในกรณีmappartitions)
แผนที่
  ใช้ฟังก์ชันการแปลงกับแต่ละรายการของ RDD และส่งคืนผลลัพธ์เป็น RDD ใหม่
  
  รายชื่อตัวแปร
  
  แผนที่ def [U: ClassTag] (f: T => U): RDD [U]
ตัวอย่าง:
val a = sc.parallelize(List("dog", "salmon", "salmon", "rat", "elephant"), 3)
 val b = a.map(_.length)
 val c = a.zip(b)
 c.collect
 res0: Array[(String, Int)] = Array((dog,3), (salmon,6), (salmon,6), (rat,3), (elephant,8)) 
mapPartitions
  นี่คือแผนที่พิเศษที่เรียกเพียงครั้งเดียวสำหรับแต่ละพาร์ติชัน เนื้อหาทั้งหมดของพาร์ติชันที่เกี่ยวข้องพร้อมใช้งานเป็นสตรีมค่าตามลำดับผ่านอาร์กิวเมนต์อินพุต (Iterarator [T]) ฟังก์ชันที่กำหนดเองจะต้องส่งคืน Iterator [U] อีกตัวหนึ่ง ตัววนซ้ำผลลัพธ์ที่รวมกันจะถูกแปลงเป็น RDD ใหม่โดยอัตโนมัติ โปรดทราบว่า tuples (3,4) และ (6,7) หายไปจากผลลัพธ์ต่อไปนี้เนื่องจากการแบ่งพาร์ติชันที่เราเลือก
  
  preservesPartitioningระบุว่าฟังก์ชันอินพุตจะเก็บรักษาพาร์ติชันเนอร์ไว้หรือไม่ซึ่งควรจะเป็นfalseเว้นแต่ว่านี่คือคู่ RDD และฟังก์ชันอินพุตจะไม่แก้ไขคีย์
  
  รายชื่อตัวแปร
  
  def mapPartitions [U: ClassTag] (f: Iterator [T] => Iterator [U], preservesPartitioning: Boolean = false): RDD [U]
ตัวอย่าง 1
val a = sc.parallelize(1 to 9, 3)
 def myfunc[T](iter: Iterator[T]) : Iterator[(T, T)] = {
   var res = List[(T, T)]()
   var pre = iter.next
   while (iter.hasNext)
   {
     val cur = iter.next;
     res .::= (pre, cur)
     pre = cur;
   }
   res.iterator
 }
 a.mapPartitions(myfunc).collect
 res0: Array[(Int, Int)] = Array((2,3), (1,2), (5,6), (4,5), (8,9), (7,8)) 
ตัวอย่าง 2
val x = sc.parallelize(List(1, 2, 3, 4, 5, 6, 7, 8, 9,10), 3)
 def myfunc(iter: Iterator[Int]) : Iterator[Int] = {
   var res = List[Int]()
   while (iter.hasNext) {
     val cur = iter.next;
     res = res ::: List.fill(scala.util.Random.nextInt(10))(cur)
   }
   res.iterator
 }
 x.mapPartitions(myfunc).collect
 // some of the number are not outputted at all. This is because the random number generated for it is zero.
 res8: Array[Int] = Array(1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 5, 7, 7, 7, 9, 9, 10) 
โปรแกรมข้างต้นสามารถเขียนโดยใช้ flatMap ได้ดังนี้
ตัวอย่างที่ 2 โดยใช้แฟลตแมป
val x  = sc.parallelize(1 to 10, 3)
 x.flatMap(List.fill(scala.util.Random.nextInt(10))(_)).collect
 res1: Array[Int] = Array(1, 2, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10) 
สรุป:
mapPartitionsการแปลงจะเร็วกว่าmapเนื่องจากเรียกใช้ฟังก์ชันของคุณครั้งเดียว / พาร์ติชันไม่ใช่ครั้งเดียว / องค์ประกอบ ..
อ่านเพิ่มเติม: foreach Vs foreachPartitions เมื่อใดควรใช้ What?