অ্যাপাচি স্পার্ক: মানচিত্র বনাম মানচিত্রের পার্টিশন?


133

আরডিডি map এবং mapPartitionsপদ্ধতির মধ্যে পার্থক্য কী ? এবং flatMapমত mapবা মত আচরণ করে mapPartitions? ধন্যবাদ।

(সম্পাদনা) অর্থাত্ পার্থক্যটি (অর্থহীনভাবে বা বাস্তবায়নের ক্ষেত্রে) কী

  def map[A, B](rdd: RDD[A], fn: (A => B))
               (implicit a: Manifest[A], b: Manifest[B]): RDD[B] = {
    rdd.mapPartitions({ iter: Iterator[A] => for (i <- iter) yield fn(i) },
      preservesPartitioning = true)
  }

এবং:

  def map[A, B](rdd: RDD[A], fn: (A => B))
               (implicit a: Manifest[A], b: Manifest[B]): RDD[B] = {
    rdd.map(fn)
  }

3
উত্তর নিচে পড়ার পর আপনি [এই অভিজ্ঞতা] যদি কেউ যিনি প্রকৃতপক্ষে এটি ব্যবহৃত দ্বারা ভাগ করা কটাক্ষপাত থাকতে পারে। ( Bzhangusc.wordpress.com/2014/06/19/... ) bzhangusc.wordpress.com/2014/06/19 /…
অভিদেমন

উত্তর:


121

কোনও আরডিডির মানচিত্র এবং মানচিত্রের পার্টিশন পদ্ধতির মধ্যে পার্থক্য কী?

পদ্ধতি মানচিত্র উত্স আরডিডি প্রতিটি উপাদান একটি ফাংশন প্রয়োগ করে ফলাফল আরডিডি একক উপাদান রূপান্তর করে । মানচিত্রের পার্টিশনগুলি উত্স আরডিডি-র প্রতিটি বিভাজনকে ফলাফলের একাধিক উপাদানগুলিতে রূপান্তর করে (সম্ভবত কোনওটি নয়)।

এবং ফ্ল্যাটম্যাপ মানচিত্রের মতো বা মানচিত্রের মতো আচরণ করে?

না হয়, ফ্ল্যাটম্যাপ একটি একক উপাদান হিসাবে (যেমন map) কাজ করে এবং ফলাফলের একাধিক উপাদান (হিসাবে ) উত্পাদন করে mapPartitions


3
ধন্যবাদ - সুতরাং মানচিত্রের কারণে কী পরিবর্তন হয় (বা অন্যথায় পার্টিশনের সংখ্যা পরিবর্তন হয়)? এটি নোডের মধ্যে ডেটা সরিয়ে দেয়? আমি নোডের মধ্যে ডেটা স্থানান্তর এড়াতে মানচিত্রের পার্টিশনগুলি ব্যবহার করছি, তবে ফ্ল্যাপম্যাপ তা করবে কিনা তা নিশ্চিত ছিল না।
নিকোলাস হোয়াইট

আপনি যদি উত্সটি দেখেন - github.com/apache/incubator-spark/blob/… এবং github.com/apache/incubator-spark/blob/… - উভয়ের mapএবং flatMapপিতামাতার মতো ঠিক একই পার্টিশন রয়েছে।
অ্যালেক্সি রোমানভ

13
একটি নোট হিসাবে, ২০১৩ সান ফ্রান্সিসকো স্পার্ক সামিটের (goo.gl/JZXDCR) স্পিকারের সরবরাহিত একটি উপস্থাপনা হাইলাইট করেছে যে প্রতি প্রতি রেকর্ড ওভারহেড সহ কাজগুলি মানচিত্রের রূপান্তরের চেয়ে মানচিত্রের পার্টিশনের সাথে আরও ভাল সম্পাদন করে। এটি, উপস্থাপনা অনুযায়ী, একটি নতুন টাস্ক স্থাপনের জন্য ব্যয় বেশি।
মাইকেল উর্কিয়া

1
আমি বিপরীতটি দেখতে পাচ্ছি - এমনকি খুব ছোট অপারেশন সহ, এটি মানচিত্রের পার্টিশনগুলিতে কল করা দ্রুত এবং কল মানচিত্রের চেয়ে পুনরাবৃত্তি। আমি ধরে নিচ্ছি যে এটি কেবলমাত্র ভাষা ইঞ্জিন শুরু করার ওভারহেড যা মানচিত্রের কার্য সম্পাদন করবে। (আমি আর এ আছি, যার আরও বেশি স্টার্টআপ ওভারহেড থাকতে পারে)) আপনি যদি একাধিক ক্রিয়াকলাপ চালিয়ে যাচ্ছেন তবে মানচিত্রের পার্টিশনগুলি বেশ খানিকটা দ্রুত গতিযুক্ত বলে মনে হচ্ছে - আমি এটি ধরে নিচ্ছি কারণ এটি কেবল একবার আরডিডি পড়ে। এমনকি আরডিডি যদি র‍্যামে ক্যাশে থাকে তবে এটি ধরণের রূপান্তর থেকে প্রচুর ওভারহেড সাশ্রয় করে।
বব

3
mapমূলত আপনার ফাংশনটি নেয় fএবং এতে প্রবেশ করে iter.map(f)। সুতরাং মূলত এটি একটি সুবিধার পদ্ধতি যা মোড়কে যায় mapPartitions। খাঁটি মানচিত্রের শৈলীর রূপান্তর কাজের জন্য যদি কোনওভাবেই পারফরম্যান্স সুবিধা পাওয়া যায় তবে আমি অবাক হয়ে যাব (যেমন ফাংশনটি অভিন্ন), যদি আপনাকে প্রসেসিংয়ের জন্য কিছু অবজেক্ট তৈরি করার প্রয়োজন হয়, যদি এই বিষয়গুলি ভাগ করা যায় তবে mapPartitionsসুবিধাজনক হবে।
নাইটওয়ালফ

129

খুদে শয়তান। টিপ:

যখনই আপনার কাছে ভারী ওজন সূচনা হয়েছে যা RDDএকবারে RDDউপাদান হিসাবে একবার করার চেয়ে একবারে অনেকগুলি উপাদানের জন্য একবার করা উচিত এবং যদি এই সূচনাটি যেমন তৃতীয় পক্ষের লাইব্রেরি থেকে অবজেক্ট তৈরি করা হয় তবে সিরিয়ালায়িত করা যায় না (যাতে স্পার্ক এটি ক্লাস্টারে জুড়ে প্রেরণ করতে পারে কর্মী নোড), 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
})

Q2 এর। না flatMapমানচিত্র মত বা মত আচরণ mapPartitions?

হ্যাঁ. দয়া করে এর 2 উদাহরণ দেখুন flatmap.. এর স্ব ব্যাখ্যাযোগ্য।

চতুর্থাংশ 1। আরডিডি mapএবং এর মধ্যে পার্থক্য কীmapPartitions

mapmapPartitionsপার্টিশন পর্যায়ে ফাংশনটি অনুশীলন করার সময় প্রতিটি উপাদান স্তরে ব্যবহার করা হচ্ছে ফাংশনটি কাজ করে ।

উদাহরণ দৃশ্যপট : যদি আমরা একটি বিশেষ 100K উপাদান আছেRDDপার্টিশন তারপর আমরা ফাংশন বন্ধ করো ম্যাপিং রূপান্তর দ্বারা ব্যবহৃত হচ্ছে 100K বার যখন আমরা ব্যবহার করবেmap

বিপরীতভাবে, আমরা যদি ব্যবহার করি mapPartitionsতবে আমরা কেবলমাত্র একবার নির্দিষ্ট ফাংশনটি কল করব, তবে আমরা সমস্ত 100 কে রেকর্ডে পাস করব এবং একটি ফাংশন কলে সমস্ত প্রতিক্রিয়া ফিরে পাব।

mapএকটি বিশেষ ফাংশনটিতে এতবার কাজ করার পরে কার্যকারিতা লাভ হবে , বিশেষত যদি ফাংশনটি প্রতিবার ব্যয়বহুল কিছু করে যা যদি আমরা সমস্ত উপাদানগুলিতে একবারে (ক্ষেত্রে ক্ষেত্রে mappartitions) পাস করি তবে এটি করার প্রয়োজন হবে না ।

মানচিত্র

আরডিডির প্রতিটি আইটেমে একটি রূপান্তর ফাংশন প্রয়োগ করে এবং ফলাফলটি নতুন আরডিডি হিসাবে দেয়।

তালিকা বৈকল্পিক

Def মানচিত্র [ইউ: ক্লাসট্যাগ] (চ: টি => ইউ): আরডিডি [ইউ]

উদাহরণ:

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

এটি একটি বিশেষায়িত মানচিত্র যা প্রতিটি বিভাজনের জন্য কেবল একবার ডাকা হয়। সংশ্লিষ্ট পার্টিশনের পুরো সামগ্রীটি ইনপুট আর্গুমেন্টের (আইট্রেটর [টি]) এর মাধ্যমে মানগুলির ক্রমানুসারে স্ট্রিম হিসাবে উপলব্ধ। কাস্টম ফাংশন অবশ্যই অন্য আইট্রেটার [ইউ] ফিরে আসতে হবে। সম্মিলিত ফলাফল পুনরাবৃত্তি স্বয়ংক্রিয়ভাবে একটি নতুন আরডিডিতে রূপান্তরিত হয়। দয়া করে মনে রাখবেন, টিউপসগুলি (3,4) এবং (6,7) নীচের ফলাফল থেকে অনুপস্থিত যা আমরা বেছে নিয়েছি বিভাজনের কারণে।

preservesPartitioningইনপুট ফাংশন পার্টিশনর সংরক্ষণ করে কিনা তা নির্দেশ করে, এটি হওয়া উচিত falseযদি না এটি একটি জোড় আরডিডি হয় এবং ইনপুট ফাংশনটি কীগুলি পরিবর্তন না করে।

তালিকা বৈকল্পিক

Def map পার্টিশনগুলি [ইউ: ক্লাসট্যাগ] (চ: আইট্রেটার [টি] => আইট্রেটার [ইউ], সংরক্ষণের পার্টিশন: বুলিয়ান = মিথ্যা): আরডিডি [ইউ]

উদাহরণ 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) 

উপরের প্রোগ্রামটি নীচে ফ্ল্যাটম্যাপ ব্যবহার করেও লেখা যেতে পারে।

ফ্ল্যাটম্যাপ ব্যবহার করে উদাহরণ 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যেহেতু এটি আপনার ফাংশনটিকে একবার / পার্টিশনকে একবার বলায় / একবার / উপাদান হিসাবে নয় ..

আরও পঠন: ফোরচ বনাম পূর্বাঙ্গ বিভাগ কখন ব্যবহার করবেন?


4
আমি জানি যে আপনি একই ফলাফলটি ব্যবহার করতে mapবা mapPartitionsঅর্জন করতে পারেন (প্রশ্নের দুটি উদাহরণ দেখুন); এই প্রশ্নটি হল আপনি কেন অন্য উপায়ে একটি উপায় বেছে নিতে চান is অন্য উত্তরের মন্তব্যগুলি সত্যিই দরকারী! এছাড়াও, আপনি এটি উল্লেখ করেন নি mapএবং flatMapপাস falseকরেছেন preservesPartitioningএবং এর কী কী প্রভাব রয়েছে imp
নিকোলাস হোয়াইট

2
পার্টিশনের জন্য প্রতিবার কার্যকর করা বনাম ফাংশন একবারে এক্সিকিউট করা হ'ল লিঙ্কটি আমি অনুপস্থিত ছিল। মানচিত্রের পার্টিশন সহ একবারে একাধিক ডেটা রেকর্ডে অ্যাক্সেস থাকা একটি অমূল্য জিনিস। উত্তরটির প্রশংসা করুন
সেমিকোলনস এবং নালী টেপ

1
এর mapচেয়ে ভাল কোন দৃশ্য আছে কি mapPartitions? যদি mapPartitionsখুব ভাল হয় তবে এটি কেন ডিফল্ট মানচিত্রের বাস্তবায়ন নয়?
রুহং

1
@ অ্যানিলেজেডমুল: উভয়ই হ'ল বিবিধ প্রয়োজনীয়তার জন্য যদি আপনি ডিবি সংযোগের মতো সংস্থানগুলি (যেমন উপরের উদাহরণে দেখানো হয়) ইনস্ট্যান্ট করছেন তবে পার্টিশনের প্রতি সংযোগের সাথে সংযোগ হ'ল ম্যাপ পার্টিশনগুলি সঠিক পদ্ধতির। এছাড়াও অ্যাসটেক্সটফায়ার অভ্যন্তরীণভাবে ব্যবহৃত ম্যাপপার্টিশনগুলি দেখুন
রাম গদিয়ারাম

@oneleggedmule আমার দৃষ্টিকোণ থেকে, মানচিত্র () বোঝা এবং শেখা সহজ এবং এটি অনেকগুলি ভিন্ন ভাষার একটি সাধারণ পদ্ধতিও। শুরুতে যদি কেউ এই স্পার্ক নির্দিষ্ট পদ্ধতির সাথে পরিচিত না হয় তবে মানচিত্রের পার্টিশনগুলি () এর চেয়েও ব্যবহার করা সহজ হতে পারে। যদি কোনও পারফরম্যান্সের পার্থক্য না থাকে তবে আমি মানচিত্র () ব্যবহার করতে পছন্দ করি।
রেমন্ড চেন

15

মানচিত্র :

  1. এটি মানচিত্রে () মানচিত্রের পদ্ধতির অনুরূপ, একই সময়ে এক সারি প্রসেস করে।
  2. আপনি প্রতিটি সারির পরে রূপান্তর থেকে ফিরে আসেন।

MapPartitions

  1. এটি একসাথে সম্পূর্ণ বিভাজন প্রক্রিয়া করে।
  2. পুরো পার্টিশনটি প্রক্রিয়া করার পরে আপনি একবারে ফাংশন থেকে ফিরে আসতে পারেন।
  3. আপনি পুরো পার্টিশনটি প্রক্রিয়া না করা পর্যন্ত সমস্ত মধ্যবর্তী ফলাফল স্মৃতিতে রাখা দরকার।
  4. আপনাকে মানচিত্রের সেটআপ () মানচিত্র () এবং ক্লিনআপ () ফাংশন পছন্দ করে

Map Vs mapPartitions http://bytepadding.com/big-data/spark/spark-map-vs-mappartitions/

Spark Map http://bytepadding.com/big-data/spark/spark-map/

Spark mapPartitions http://bytepadding.com/big-data/spark/spark-mappartitions/


2 সম্পর্কিত - যদি আপনি পুনরুক্তি-থেকে-পুনরুক্তি রূপান্তরগুলি সম্পাদন করছেন এবং পুনরুক্তিটিকে কোনও ধরণের সংকলনে রূপান্তর না করে থাকেন তবে আপনাকে পুরো পার্টিশনটিকে মেমরির মধ্যে রাখতে হবে না, বাস্তবে, সেইভাবে স্পার্কটি সক্ষম হবে পার্টিশনের অংশগুলি ডিস্কে ছড়িয়ে দিন।
ইলকর্ড

4
আপনাকে পুরো পার্টিশনটি মেমরিতে রাখতে হবে না, তবে ফলাফলটি। আপনি পুরো পার্টিশনটি প্রক্রিয়া না করা পর্যন্ত আপনি ফলাফলটি ফিরিয়ে দিতে পারবেন না
ক্রাজিগৌতম
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.