কিভাবে স্টার্ক স্পার্কে কার্যগুলিতে বিভক্ত হয়?


143

আসুন নিম্নলিখিতগুলির জন্য ধরে নেওয়া যাক যে প্রতিটি পয়েন্টে সময়ে মাত্র একটি স্পার্ক কাজ চলছে।

আমি এখন পর্যন্ত কি পেতে

স্পার্কে কী ঘটে তা আমি এখানে বুঝতে পারি:

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

চিত্র 1

আমি বুঝতে পারি যে

  • একটি কাজ হ'ল ফাংশন অবজেক্টটি সিরিয়াল করে ড্রাইভারের কাছ থেকে এক্সিকিউটারের কাছে পাঠানো একটি কমান্ড।
  • নির্বাহক কমান্ডটি (টাস্ক) ডিসায়ারাইজ করে (ড্রাইভার জারের সাথে) এবং এটি একটি পার্টিশনে চালিত করে।

কিন্তু

প্রশ্ন (গুলি)

এই কাজগুলিতে আমি কীভাবে মঞ্চটি বিভক্ত করব?

বিশেষ করে:

  1. রূপান্তর ও ক্রিয়া দ্বারা নির্ধারিত কার্যগুলি কি একাধিক রূপান্তর / ক্রিয়া কোনও কার্যক্রমে হতে পারে?
  2. পার্টিশন দ্বারা নির্ধারিত কাজগুলি (উদাহরণস্বরূপ পার্টিশন প্রতি স্টেজ প্রতি এক টাস্ক)।
  3. কাজগুলি নোডগুলি দ্বারা নির্ধারিত হয় (উদাহরণস্বরূপ নোডের প্রতিটি স্তরের প্রতি কাজ)?

আমি যা মনে করি (কেবলমাত্র আংশিক উত্তর, এমনকি সঠিক হলেও)

ইন https://0x0fff.com/spark-architecture-shuffle , এলোমেলো ইমেজের সাথে ব্যাখ্যা করা হয়

এখানে চিত্র বর্ণনা লিখুন

এবং আমি ধারণাটি পেয়েছি যে নিয়মটি

নোডের সংখ্যা বিবেচনা না করে প্রতিটি পর্যায় পার্টিশন কার্যের # সংখ্যাতে বিভক্ত

আমার প্রথম চিত্রের জন্য আমি বলব যে আমার কাছে 3 টি মানচিত্রের কাজ এবং 3 টি কার্য কমাতে হবে।

0x0fff থেকে চিত্রটির জন্য, আমি বলব 8 টি মানচিত্র এবং 3 টি কার্য কমানো আছে (ধরে নিবেন যে কেবল তিনটি কমলা এবং তিনটি গা green় সবুজ ফাইল রয়েছে)।

যে কোনও ক্ষেত্রে প্রশ্ন খুলুন

এটা কি ঠিক? তবে এটি সঠিক হলেও, আমার উপরের সমস্ত প্রশ্নের উত্তর দেওয়া হবে না, কারণ এটি এখনও খোলা রয়েছে, একাধিক ক্রিয়াকলাপ (যেমন একাধিক মানচিত্র) কোনও কাজের মধ্যেই রয়েছে বা প্রতিটি ক্রিয়াকলাপে একটি কার্যে পৃথক করা হয়েছে।

অন্যরা কী বলে

স্পার্ক একটি কাজ কি? স্পার্ক কর্মী কীভাবে জার ফাইলটি কার্যকর করে? এবং অ্যাপাচি স্পার্ক শিডিয়ুলার ফাইলগুলিকে কীভাবে বিভক্ত করে? অনুরূপ, তবে আমি মনে করি না যে আমার প্রশ্নের উত্তরটি সেখানে পরিষ্কারভাবে দেওয়া হয়েছিল।

উত্তর:


52

আপনার এখানে একটি সুন্দর সুন্দর রূপরেখা আছে। আপনার প্রশ্নের উত্তর দিতে

  • একটি পৃথক task করে প্রতিটি জন্য তথ্য প্রতিটি পার্টিশন এর জন্য আমাদের প্রবর্তিত করা প্রয়োজন stage। বিবেচনা করুন যে প্রতিটি পার্টিশন সম্ভবত পৃথক শারীরিক অবস্থানের উপর নির্ভর করবে - যেমন এইচডিএফএসের ব্লক বা স্থানীয় ফাইল সিস্টেমের জন্য ডিরেক্টরি / ভলিউম।

নোট করুন যে এর জমা দিয়ে Stageচালিত হয় DAG Scheduler। এর অর্থ যে পরস্পর নির্ভরশীল নয় এমন স্তরগুলি সমান্তরালভাবে সম্পাদনের জন্য ক্লাস্টারে জমা দেওয়া যেতে পারে: এটি ক্লাস্টারে সমান্তরালকরণের ক্ষমতা সর্বাধিক করে তোলে। সুতরাং যদি আমাদের ডেটাফ্লোতে ক্রিয়াকলাপ একই সাথে ঘটতে পারে তবে আমরা একাধিক পর্যায় চালু হওয়া আশা করব।

আমরা নিম্নলিখিত খেলনা উদাহরণে ক্রিয়াকলাপে দেখতে পাই যেখানে আমরা নিম্নলিখিত ধরণের অপারেশন করি:

  • দুটি ডাটাসোর্স লোড করুন
  • উভয় ডেটা উত্স পৃথকভাবে কিছু মানচিত্র অপারেশন সঞ্চালন
  • তাদের যোগদান
  • ফলাফলের উপর কিছু মানচিত্র এবং ফিল্টার অপারেশন সম্পাদন করুন
  • ফলাফল সংরক্ষণ করুন

তাহলে আমরা কতটি পর্যায় শেষ করব?

  • সমান্তরাল = 2 পর্যায়ে দুটি ডেটাসোর্স লোড করার জন্য প্রতিটি 1 পর্যায়
  • একটি তৃতীয় পর্যায় যা অন্য দুটি স্তরের উপর নির্ভরশীলjoin তা উপস্থাপন করে
  • দ্রষ্টব্য: যোগদান করা ডেটাতে কাজ করা সমস্ত ফলো-অন ক্রিয়াকলাপ একই পর্যায়ে সম্পাদন করা যেতে পারে কারণ তাদের অবশ্যই ক্রমানুসারে ঘটতে হবে। অতিরিক্ত ধাপে চালু করার কোনও সুবিধা নেই কারণ পূর্বের ক্রিয়াকলাপটি শেষ না হওয়া পর্যন্ত তারা কাজ শুরু করতে পারে না।

এখানে যে খেলনা প্রোগ্রাম

val sfi  = sc.textFile("/data/blah/input").map{ x => val xi = x.toInt; (xi,xi*xi) }
val sp = sc.parallelize{ (0 until 1000).map{ x => (x,x * x+1) }}
val spj = sfi.join(sp)
val sm = spj.mapPartitions{ iter => iter.map{ case (k,(v1,v2)) => (k, v1+v2) }}
val sf = sm.filter{ case (k,v) => v % 10 == 0 }
sf.saveAsTextFile("/data/blah/out")

এবং এখানে ফলাফলের ডিএজি রয়েছে

এখানে চিত্র বর্ণনা লিখুন

এখন: কত কাজ ? কাজের সংখ্যা সমান হতে হবে

যোগফল ( Stage* #Partitions in the stage)


2
ধন্যবাদ! দয়া করে আমার পাঠের বিষয়ে আপনার উত্তরটি বিস্তারিতভাবে বর্ণনা করুন: 1) আমার পর্যায়ের সংজ্ঞাটি কি ব্যাপক নয়? মনে হচ্ছে যে আমি এই প্রয়োজনীয়তাটি হারালাম যে কোনও পর্যায়ে সমান্তরাল হতে পারে এমন ক্রিয়াকলাপ থাকতে পারে না। বা আমার বিবরণটি ইতিমধ্যে কঠোরভাবে বোঝাচ্ছে? 2) কাজের জন্য যে কার্য সম্পাদন করতে হবে তার সংখ্যা পার্টিশনের সংখ্যা দ্বারা নির্ধারিত হয়, তবে প্রসেসর বা নোডের সংখ্যা দ্বারা নয়, একই সাথে সম্পাদন করা যেতে পারে এমন সংখ্যার উপর নির্ভরশীল প্রসেসর, তাই না? 3) একটি কাজ একাধিক অপারেশন থাকতে পারে?
Make42

1
4) আপনার শেষ বাক্যটি দিয়ে আপনি কী বোঝাতে চেয়েছিলেন? সর্বোপরি, সংখ্যা পার্টিশনগুলি পর্যায় থেকে মঞ্চে পৃথক হতে পারে। আপনি কি বোঝাতে চেয়েছেন যে আপনি এইভাবে সমস্ত পদক্ষেপের জন্য নিজের কাজটি কনফিগার করেছেন?
Make 42

@ Make42 অবশ্যই পার্টিশনের সংখ্যা পর্যায় থেকে মঞ্চে পরিবর্তিত হতে পারে - আপনি সঠিক। sum(..)সেই প্রকরণটি আমলে নেওয়ার কথা বলে আমার উদ্দেশ্য ছিল ।
জাভাদবা

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

@ অ্যাপসিপু এটি একটি বিশেষ ঘটনা ছিল - তবে আমি সম্মত হই যে এটি বিভ্রান্তিকর হবে তাই আমি এটিকে সরিয়ে দিচ্ছি।
জাভাদবা

26

এটি আপনাকে বিভিন্ন টুকরো বুঝতে আরও সহায়তা করতে পারে:

  • পর্যায়: কাজের একটি সংগ্রহ is ডেটা (পার্টিশন) এর বিভিন্ন সাবসেটের বিরুদ্ধে একই প্রক্রিয়া চলছে।
  • কার্য: বিতরণ করা ডেটাসেটের বিভাজনে কাজের একককে উপস্থাপন করে। সুতরাং প্রতিটি পর্যায়ে, কর্মের সংখ্যা = পার্টিশনের সংখ্যা-বা আপনি যেমন বলেছিলেন "পার্টিশন প্রতি পর্যায়ে প্রতিটি কাজ"।
  • প্রতিটি নির্বাহক একটি সুতার পাত্রে চালিত হয় এবং প্রতিটি ধারক একটি নোডে থাকে।
  • প্রতিটি পর্যায় একাধিক নির্বাহককে ব্যবহার করে, প্রতিটি নির্বাহককে একাধিক ভিকোর বরাদ্দ করা হয়।
  • প্রতিটি vcore একবারে ঠিক একটি কাজ সম্পাদন করতে পারে
  • সুতরাং যে কোনও পর্যায়ে, একাধিক কাজ সমান্তরালভাবে সম্পাদন করা যেতে পারে। টাস্কের সংখ্যা চলমান = ভোকোর সংখ্যা ব্যবহার করা হচ্ছে।

2
এটি স্পার্ক আর্কিটেকচারে সত্যই দরকারী পঠনযোগ্য: 0x0fff.com/spark-architecture
পেড্রাম বাশির

আমি আপনার পয়েন্ট নম্বরটি পাইনি 3 যতদূর আমি জানি প্রতিটি নোডে একাধিক এক্সিকিউটার থাকতে পারে, সুতরাং পয়েন্ট 3 অনুসারে: নোডের জন্য কেবলমাত্র একজন এক্সিকিউটার থাকতে হবে। আপনি এই বিষয়টি পরিষ্কার করতে পারেন?
তুপর্ণ বেহেরা

প্রত্যেকটি নোডে একাধিক স্পার্ক এক্সিকিউটর থাকতে পারে এই লিঙ্কটি দেখুন। docs.cloudera.com/runtime/7.0.2/running-spark-applications/…
পেডরাম বাশিরি

15

যদি আমি সঠিকভাবে বুঝতে পারি তবে 2 টি (সম্পর্কিত) জিনিস যা আপনাকে বিভ্রান্ত করে:

1) কোন কাজের বিষয়বস্তু নির্ধারণ করে?

2) কোনটি সম্পাদন করতে হবে তার সংখ্যা নির্ধারণ করে?

স্পার্কের ইঞ্জিন " আঠালো " একসাথে একটানা rdds এ সাধারণ অপারেশনগুলি উদাহরণস্বরূপ:

rdd1 = sc.textFile( ... )
rdd2 = rdd1.filter( ... )
rdd3 = rdd2.map( ... )
rdd3RowCount = rdd3.count

সুতরাং যখন rdd3 (অলস) গণনা করা হয়, স্পার্ক rdd1 এর পার্টিশন অনুযায়ী একটি টাস্ক তৈরি করে এবং প্রতিটি টাস্ক rdd3 এর ফলস্বরূপ ফিল্টার এবং লাইন প্রতি ম্যাপ উভয়ই সম্পাদন করে।

পার্টিশনের সংখ্যা দ্বারা কার্যের সংখ্যা নির্ধারিত হয়। প্রতিটি আরডিডি-তে একটি সংখ্যক পার্টিশন রয়েছে। এমন একটি উত্স আরডিডি-র জন্য যা এইচডিএফএস থেকে পড়া হয় (উদাহরণস্বরূপ sc.textFile (...) ব্যবহার করে) পার্টিশনের সংখ্যা হ'ল ইনপুট ফর্ম্যাট দ্বারা উত্পন্ন বিভাজনের সংখ্যা। আরডিডি (গুলি) এর কিছু ক্রিয়াকলাপের ফলে পৃথক পৃথক সংখ্যক পার্টিশন থাকা আরডিডি হতে পারে:

rdd2 = rdd1.repartition( 1000 ) will result in rdd2 having 1000 partitions ( regardless of how many partitions rdd1 had ).

আর একটি উদাহরণ যোগ দেয়:

rdd3 = rdd1.join( rdd2  , numPartitions = 1000 ) will result in rdd3 having 1000 partitions ( regardless of partitions number of rdd1 and rdd2 ).

(সর্বাধিক) ক্রিয়াকলাপ যা পার্টিশনের সংখ্যা পরিবর্তন করে তা একটি শ্যাফাল জড়িত, যখন আমরা উদাহরণস্বরূপ:

rdd2 = rdd1.repartition( 1000 ) 

আসলে যা ঘটে তা হল rdd1 এর প্রতিটি বিভাজনে টাস্কটির একটি শেষ-আউটপুট তৈরি করা দরকার যা নীচের পর্যায়ে পড়া যায় যাতে rdd2 তৈরি করতে সঠিক 1000 পার্টিশন থাকে (তারা এটি কীভাবে করবেন? হ্যাশ বা সাজান )। এই পাশের কার্যগুলি মাঝে মাঝে "মানচিত্র (পাশের কাজগুলি") হিসাবে উল্লেখ করা হয়। পরে rdd2 এ চলবে এমন একটি কার্য একটি বিভাজনে (rdd2 এর) কাজ করবে এবং সেই পার্টিশনের সাথে সম্পর্কিত মানচিত্রের পাশের আউটপুটগুলি কীভাবে পড়তে / একত্রিত করতে হবে তা নির্ধারণ করতে হবে। এই পক্ষের কার্যগুলি মাঝে মাঝে "হ্রাস (পাশ) কার্য" হিসাবে উল্লেখ করা হয়।

দুটি প্রশ্ন সম্পর্কিত: একটি পর্যায়ে কার্য সংখ্যা পার্টিশনের সংখ্যা (একটানা rdds একসাথে "আঠালো" একসাথে সাধারণ) এবং আরডিডি পার্টিশনের সংখ্যা পর্যায়ের মধ্যে পরিবর্তন করতে পারে (কিছুতে পার্টিশনের সংখ্যা নির্দিষ্ট করে) উদাহরণস্বরূপ অপারেশন ঘটাচ্ছে)

একবার কোনও মঞ্চের সম্পাদন শুরু হয়ে গেলে, এর কাজগুলি টাস্ক স্লট দখল করতে পারে। একযোগে টাস্ক-স্লটের সংখ্যা হ'ল নামক এক্সিকিউটর * এক্সিকিউটারকরেস। সাধারণভাবে, এগুলি বিভিন্ন, অ-নির্ভরশীল পর্যায়ে কাজ দ্বারা দখল করা যেতে পারে।

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