নিম্নলিখিত উত্তরটি শিরোনামে উল্লিখিত তিনটি প্রধান দিককে অন্তর্ভুক্ত করে - নির্বাহকের সংখ্যা, এক্সিকিউটারের স্মৃতি এবং কোর সংখ্যা। ড্রাইভারের মেমরির মতো অন্যান্য পরামিতি এবং অন্যান্য থাকতে পারে যা আমি এই উত্তর হিসাবে সম্বোধন করি নি, তবে নিকট ভবিষ্যতে যুক্ত করতে চাই।
কেস 1 হার্ডওয়্যার - 6 নোড এবং প্রতিটি নোড 16 কোর, 64 জিবি র্যাম
প্রতিটি নির্বাহক একটি জেভিএম উদাহরণ। সুতরাং আমরা একক নোডে একাধিক এক্সিকিউটার থাকতে পারি
ওএস এবং হ্যাডোপ ডেমনসের জন্য প্রথম 1 কোর এবং 1 জিবি প্রয়োজন, তাই প্রতিটি নোডের জন্য 15 টি কোর, 63 জিবি র্যাম পাওয়া যায়
কোরগুলির সংখ্যা কীভাবে চয়ন করবেন তা দিয়ে শুরু করুন :
Number of cores = Concurrent tasks as executor can run
So we might think, more concurrent tasks for each executor will give better performance. But research shows that
any application with more than 5 concurrent tasks, would lead to bad show. So stick this to 5.
This number came from the ability of executor and not from how many cores a system has. So the number 5 stays same
even if you have double(32) cores in the CPU.
নির্বাহকের সংখ্যা:
Coming back to next step, with 5 as cores per executor, and 15 as total available cores in one Node(CPU) - we come to
3 executors per node.
So with 6 nodes, and 3 executors per node - we get 18 executors. Out of 18 we need 1 executor (java process) for AM in YARN we get 17 executors
This 17 is the number we give to spark using --num-executors while running from spark-submit shell command
প্রতিটি নির্বাহকের জন্য স্মৃতি:
From above step, we have 3 executors per node. And available RAM is 63 GB
So memory for each executor is 63/3 = 21GB.
However small overhead memory is also needed to determine the full memory request to YARN for each executor.
Formula for that over head is max(384, .07 * spark.executor.memory)
Calculating that overhead - .07 * 21 (Here 21 is calculated as above 63/3)
= 1.47
Since 1.47 GB > 384 MB, the over head is 1.47.
Take the above from each 21 above => 21 - 1.47 ~ 19 GB
So executor memory - 19 GB
চূড়ান্ত সংখ্যা - এক্সিকিউটর - 17, কোর 5, এক্সিকিউটার মেমরি - 19 জিবি
কেস 2 হার্ডওয়্যার: একই 6 নোড, 32 কোর, 64 জিবি
5 ভাল সমঝোতার জন্য একই
প্রতিটি নোডের জন্য নির্বাহকের সংখ্যা = 32/5 ~ 6
সুতরাং মোট নির্বাহক = 6 * 6 নোড = 36. তারপরে চূড়ান্ত সংখ্যা 36 - 1 এএম = 35 এর জন্য
এক্সিকিউটারের মেমরিটি: প্রতিটি নোডের জন্য 6 জন এক্সিকিউটর। 63/6। 10। ওভার হেড .07 * 10 = 700 এমবি। ওভার হেড হিসাবে 1GB তে গোল করে আমরা 10-1 = 9 জিবি পাই
চূড়ান্ত সংখ্যা - নির্বাহক - 35, কোর 5, এক্সিকিউটার মেমরি - 9 জিবি
মামলা 3
উপরোক্ত পরিস্থিতিগুলি স্থির হিসাবে কয়েকটি সংখ্যক কোর গ্রহণ এবং এক্সিকিউটর এবং মেমরির # তে সরানো শুরু করে।
এখন প্রথম কেসটির জন্য, যদি আমরা মনে করি আমাদের 19 জিবি প্রয়োজন হয় না, এবং মাত্র 10 গিগাবাইটই যথেষ্ট, তবে নিম্নলিখিত সংখ্যাগুলি নিম্নরূপ:
প্রতিটি নোড = 3 এর জন্য নির্বাহকের 5 # টি কোরেস
এই পর্যায়ে, এটি আমাদের প্রথম গণনা অনুসারে 21, এবং তারপরে 19 এ নিয়ে যাবে। তবে যেহেতু আমরা ভেবেছিলাম 10 ঠিক আছে (সামান্য ওভারহেড ধরে নিই), তারপরে আমরা নোডের জন্য নির্বাহীদের # টি স্যুইচ করতে পারি না (63 63/১০ এর মতো)। নোডের জন্য exec জন এক্সিকিউটর এবং 5 কোরের সাথে উঠুন এটি নোডে 30 কোরে নেমে আসে, যখন আমাদের কেবল 16 কোর থাকে। সুতরাং আমাদের প্রতিটি নির্বাহকের জন্য কোডের সংখ্যাও পরিবর্তন করতে হবে।
সুতরাং আবার গণনা,
5 নম্বর ম্যাজিক 3 এ আসে (5 এর চেয়ে কম বা সমান যে কোনও সংখ্যা)। সুতরাং 3 টি কোর এবং 15 টি উপলব্ধ কোর সহ - আমরা নোডের জন্য 5 এক্সিকিউটার পেতে পারি। সুতরাং (5 * 6 -1) = 29 নির্বাহক
সুতরাং মেমরিটি 63/5 ~ 12. ওভার হেড 12 * .07 = .84 সুতরাং এক্সিকিউটারের মেমরি 12 - 1 জিবি = 11 জিবি
চূড়ান্ত নম্বরগুলি 29 এক্সিকিউটার, 3 কোর, এক্সিকিউটারের মেমরি 11 জিবি
গতিশীল বরাদ্দ:
দ্রষ্টব্য: গতিশীল বরাদ্দ সক্ষম করা থাকলে এক্সিকিউটারের সংখ্যার জন্য উপরের আবদ্ধ। সুতরাং এটি বলছে যে স্পার্ক অ্যাপ্লিকেশন প্রয়োজন হলে সমস্ত সংস্থান খেয়ে ফেলতে পারে। সুতরাং এমন একটি ক্লাস্টারে যেখানে আপনার অন্যান্য অ্যাপ্লিকেশন চলছে এবং তাদের কাজগুলি চালনার জন্যও কোরগুলির প্রয়োজন, দয়া করে নিশ্চিত হয়ে নিন যে আপনি এটি ক্লাস্টার পর্যায়ে করছেন। আমার অর্থ আপনি ব্যবহারকারীর অ্যাক্সেসের ভিত্তিতে YARN এর জন্য নির্দিষ্ট সংখ্যক কোর বরাদ্দ করতে পারেন। সুতরাং আপনি তৈরি করতে পারেন স্পার্ক_উজারটি হতে পারে এবং তারপরে সেই ব্যবহারকারীর জন্য কোর (মিনিট / সর্বোচ্চ) দিতে পারেন। এই সীমাগুলি স্পার্ক এবং অন্যান্য অ্যাপ্লিকেশনগুলির মধ্যে ভাগ করার জন্য যা ইয়ারনে চালিত হয়।
spark.dynamicAllocation.en सक्षम - এটি সত্য হিসাবে সেট করা হলে - আমাদের এক্সিকিউটারের উল্লেখ করার দরকার নেই। কারণটি নীচে:
স্টার্ক-জমা দেওয়ার সময় আমরা যে স্ট্যাটিক প্যারাম নম্বর দিই তা পুরো কাজের সময়কালের জন্য। তবে যদি গতিশীল বরাদ্দ চিত্রে আসে, তবে বিভিন্ন ধরণের ধরণ থাকবে
কি দিয়ে শুরু করবেন:
প্রারম্ভিক সংখ্যক এক্সিকিউটার ( স্পার্ক.ডিনামিকএলোকেশন ইনিটিয়াল এক্সেকিউটারস ) দিয়ে শুরু করতে
কতগুলো :
তারপরে লোডের উপর ভিত্তি করে (কার্যগুলি মুলতুবি রয়েছে) কতটি অনুরোধ করবেন। স্থির পথে স্পার্ক-সাবমিটে আমরা যা দেই তা এটি শেষ পর্যন্ত হবে। সুতরাং প্রাথমিক নির্বাহকের নম্বরগুলি সেট হয়ে গেলে আমরা ন্যূনতম ( স্পার্ক.ডিনামিক অ্যালোকেশন.মিনিএক্সেকিউটারস ) এবং সর্বাধিক ( স্পার্ক.ডিনামিক অলোকেশন.ম্যাক্স এক্সেকটরস ) সংখ্যায় যাই ।
জিজ্ঞাসা বা দিতে কখন:
আমরা কখন নতুন এক্সিকিউটরদের ( স্পার্ক.ডিনামিকএলোকেশন.সচেডুলারব্যাকলগটাইমআউট ) অনুরোধ করব - এই অনেক সময়কালের জন্য এখানে प्रलंबित কাজ রয়েছে। অনুরোধ প্রতিটি রাউন্ডে অনুরোধ করা এক্সিকিউটারের সংখ্যা পূর্ববর্তী রাউন্ড থেকে তাত্ক্ষণিকভাবে বৃদ্ধি পায়। উদাহরণস্বরূপ, একটি অ্যাপ্লিকেশন প্রথম রাউন্ডে 1 জন নির্বাহক এবং তারপরে 2, 4, 8 এবং পরবর্তী রাউন্ডগুলিতে এক্সিকিউটারকে যুক্ত করবে। নির্দিষ্ট সময়ে, উপরের সর্বোচ্চটি ছবিতে আসে
কখন আমরা কোনও নির্বাহককে ছেড়ে দেব ( spark.dynamicAllocation.executorIdleTimeout ) -
আমি যদি কিছু মিস করি তবে দয়া করে আমাকে সংশোধন করুন। উপরোক্তগুলি আমি প্রশ্নে এবং কিছু অনলাইন সংস্থানগুলিতে ভাগ করে নেওয়া ব্লগের উপর ভিত্তি করে আমার বোঝাপড়া। ধন্যবাদ.
তথ্যসূত্র: