(কেন) আমাদের ক্যাশে কল করতে বা আরডিডি চালিয়ে যাওয়া দরকার


171

পাঠ্য ফাইল বা সংগ্রহ থেকে (বা অন্য কোনও আরডিডি থেকে) যখন একটি অনিচ্ছাকৃত বিতরণ করা ডেটাসেট (আরডিডি) তৈরি করা হয় তখন আরডিডি ডেটা মেমরিতে রাখার জন্য আমাদের কী স্পষ্টভাবে "ক্যাশে" কল করতে বা "জেদ" রাখতে হবে? বা আরডিডি ডেটা ডিফল্টরূপে মেমরিতে বিতরণ উপায়ে সংরক্ষণ করা হয়?

val textFile = sc.textFile("/user/emp.txt")

আমার অনুধাবন অনুসারে, উপরের পদক্ষেপের পরে, টেক্সটফিল একটি আরডিডি এবং সমস্ত / কিছু নোডের স্মৃতিতে উপলব্ধ।

যদি তা হয় তবে তখন আমাদের পাঠ্য ফাইলে আরডিডিতে "ক্যাশে" বা "জেদ" রাখতে হবে কেন?

উত্তর:


300

বেশিরভাগ আরডিডি অপারেশন অলস। একটি আরডিডিকে ধারাবাহিক ক্রিয়াকলাপের বর্ণনা হিসাবে ভাবেন। একটি আরডিডি ডেটা নয়। সুতরাং এই লাইন:

val textFile = sc.textFile("/user/emp.txt")

এটা কিছুই করে না। এটি একটি আরডিডি তৈরি করে যা বলে যে "আমাদের এই ফাইলটি লোড করতে হবে"। এই মুহুর্তে ফাইলটি লোড করা হয়নি।

আরডিডি অপারেশনগুলির জন্য যা তথ্যের সামগ্রীর পর্যবেক্ষণ প্রয়োজন অলস হতে পারে না। (এগুলিকে অ্যাকশন বলা হয় )) উদাহরণটি হ'ল RDD.count- আপনাকে ফাইলের লাইনের সংখ্যা বলতে ফাইলটি পড়তে হবে be সুতরাং আপনি যদি লিখেন textFile.count, এই মুহুর্তে ফাইলটি পড়বে, লাইনগুলি গণনা করা হবে, এবং গণনাটি ফিরে আসবে।

textFile.countআবার ফোন করলে কী হবে ? একই জিনিস: ফাইলটি আবার পড়ে গণনা করা হবে। কিছুই সংরক্ষণ করা হয় না। একটি আরডিডি ডেটা নয়।

তাহলে কি করে RDD.cache? আপনি যদি textFile.cacheউপরের কোডটিতে যুক্ত করেন:

val textFile = sc.textFile("/user/emp.txt")
textFile.cache

এটা কিছুই করে না। RDD.cacheএটি একটি অলস অপারেশনও। ফাইলটি এখনও পড়া হয়নি। তবে এখন আরডিডি বলছে "এই ফাইলটি পড়ুন এবং তারপরে বিষয়বস্তুগুলি ক্যাশে করুন"। আপনি যদি textFile.countপ্রথমবার চালনা করেন তবে ফাইলটি লোড, ক্যাশেড এবং গণনা করা হবে। আপনি যদি textFile.countদ্বিতীয়বার কল করেন, অপারেশনটি ক্যাশে ব্যবহার করবে। এটি কেবল ক্যাশে থেকে ডেটা নেবে এবং লাইনগুলি গণনা করবে।

ক্যাশে আচরণ উপলব্ধ মেমরির উপর নির্ভর করে। উদাহরণস্বরূপ, যদি ফাইলটি মেমরিতে ফিট না করে তবে textFile.countস্বাভাবিক আচরণে ফিরে এসে ফাইলটি পুনরায় পড়তে হবে।


4
হাই ড্যানিয়েল, - আপনি যখন ক্যাশে ডাকেন, এর অর্থ কি আরডিডি উত্স থেকে পুনরায় লোড করা হয়নি (উদাহরণস্বরূপ পাঠ্য ফাইল) - আপনি কীভাবে নিশ্চিত হতে পারেন যে পাঠ্য ফাইলটি ডেটা ক্যাশেড হওয়ার পরে সাম্প্রতিকতম? (সূত্রের ডেটা বংশ পরবর্তীতে পুনরায় সংশ্লেষিত হয় তা নিশ্চিত করার জন্য পর্যায়ক্রমে নিবিড়বিড় করাতে ম্যানুয়াল অপারেশনটি কী এটি আবিষ্কার করে?)
অর্রু.বুটকাস

এছাড়াও - যদি আপনাকে পর্যায়ক্রমে অন্বেষণ করতে হয়, - যদি আপনার একটি আরডিডি থাকে যা ক্যাশেড হয়, অন্য আরডিডি যা ক্যাশেডের উপর নির্ভরশীল, আপনি কি পুনরায় সংশোধিত ফলাফলগুলি দেখতে আরডিডি উভয়কেই অংশগ্রহন করবেন?
andrew.butkus

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

10
হ্যাঁ. আরডিডিগুলি পরিবর্তনযোগ্য, তাই প্রতিটি আরডিডি ধরে নেয় যে এর নির্ভরতাও অপরিবর্তনীয়। স্পার্ক স্ট্রিমিং আপনাকে এমন গাছগুলি সেট আপ করতে দেয় যা পরিবর্তনের ধারাতে কাজ করে। তবে একটি আরও সহজ সমাধান হ'ল একটি ফাংশনে গাছ তৈরি করা যা কোনও ফাইলের নামকে প্যারামিটার হিসাবে নেয়। তারপরে কেবল নতুন ফাইল এবং পুফের জন্য ফাংশনটি কল করুন, আপনি নতুন গণনা ট্রি পেয়েছেন।
ড্যানিয়েল দারাবস

1
@ হুমায়ুন: স্পার্ক ইউআইয়ের স্টোরেজ ট্যাবে আপনি দেখতে পারবেন যে প্রতিটি আরডিডি কতটা ক্যাশে রয়েছে। ডেটা এত বড় হতে পারে যে এর মাত্র 40% আপনার ক্যাশে যাওয়ার জন্য মোট স্মৃতিতে ফিট করে। এক্ষেত্রে একটি বিকল্প হ'ল perisistস্টোরেজ বিকল্পটি ব্যবহার এবং বাছাই করা যা ক্যাশে ডেটা ডিস্কে ছড়িয়ে দেওয়ার অনুমতি দেয়।
ড্যানিয়েল দারাবস

197

আমি মনে করি প্রশ্নটি আরও ভালভাবে প্রণয়ন করা হবে:

আমাদের কখন ক্যাশে কল করা বা আরডিডি চালিয়ে যাওয়া দরকার?

স্পার্ক প্রক্রিয়াগুলি অলস হয়, এটি প্রয়োজন না হওয়া পর্যন্ত কিছুই ঘটবে না। প্রশ্নের জবাব দেওয়ার জন্য, val textFile = sc.textFile("/user/emp.txt")জারি করার পরে , তথ্যের সাথে কিছুই হয় না, কেবল HadoopRDDউত্স হিসাবে ফাইলটি ব্যবহার করে, এটি নির্মিত হয়।

ধরা যাক আমরা সেই ডেটাটি কিছুটা রূপান্তরিত করেছি:

val wordsRDD = textFile.flatMap(line => line.split("\\W"))

আবার, ডেটা কিছুই হয় না। এখন একটি নতুন আরডিডি wordsRDDরয়েছে যার একটি রেফারেন্স রয়েছে testFileএবং প্রয়োজনের সময় প্রয়োগ করার জন্য একটি ফাংশন রয়েছে ।

আরডিডি-তে যেমন কোনও ক্রিয়াকলাপ ডাকা হয় কেবল তখনই wordsRDD.count, আরডিডি চেইন, যাকে বংশ বলা হয় কার্যকর করা হবে। অর্থাৎ পার্টিশনগুলিতে বিভক্ত ডেটা স্পার্ক ক্লাস্টারের এক্সিকিউটাররা লোড করবে, flatMapফাংশনটি প্রয়োগ করা হবে এবং ফলাফল গণনা করা হবে।

একটি লিনিয়ার বংশে, যেমন উদাহরণের মতো এটির cache()প্রয়োজন হয় না। এক্সিকিউটারদের উপর ডেটা লোড করা হবে, সমস্ত রূপান্তর প্রয়োগ করা হবে এবং পরিশেষে countমেমরিতে সমস্ত গণনা করা হবে - যদি ডেটা মেমরিতে ফিট করে।

cacheআরডিডি শাখার বংশটি যখন কার্যকর হয় তখন কার্যকর হয়। ধরা যাক আপনি পূর্ববর্তী উদাহরণের শব্দগুলিকে ইতিবাচক এবং নেতিবাচক শব্দের একটি গণনায় ফিল্টার করতে চান। আপনি এটির মতো এটি করতে পারেন:

val positiveWordsCount = wordsRDD.filter(word => isPositive(word)).count()
val negativeWordsCount = wordsRDD.filter(word => isNegative(word)).count()

এখানে, প্রতিটি শাখা তথ্য পুনরায় লোড ইস্যু করে। একটি স্পষ্ট cacheবিবৃতি যোগ করা নিশ্চিত করবে যে পূর্বে সম্পন্ন প্রক্রিয়াজাতকরণ সংরক্ষণ ও পুনরায় ব্যবহৃত হয়েছে। কাজটি দেখতে এইরকম দেখাবে:

val textFile = sc.textFile("/user/emp.txt")
val wordsRDD = textFile.flatMap(line => line.split("\\W"))
wordsRDD.cache()
val positiveWordsCount = wordsRDD.filter(word => isPositive(word)).count()
val negativeWordsCount = wordsRDD.filter(word => isNegative(word)).count()

যে কারণে cacheএটি 'বংশ ভাঙ্গা' বলা হয় কারণ এটি একটি চেকপয়েন্ট তৈরি করে যা আরও প্রক্রিয়াজাতকরণের জন্য পুনরায় ব্যবহার করা যেতে পারে।

থাম্বের বিধি: cacheযখন আপনার আরডিডি শাখার বংশটি বাইরে চলে যায় বা যখন কোনও আরডিডি লুপের মতো একাধিকবার ব্যবহৃত হয় তখন ব্যবহার করুন।


1
অসাধারণ. ধন্যবাদ। আরও একটি সম্পর্কিত প্রশ্ন। যখন আমরা ক্যাশে বা অবিচল থাকি তখন ডেটা নির্বাহকের স্মৃতিতে বা কর্মী নোডের স্মৃতিতে সংরক্ষণ করা হবে। যদি এটি এক্সিকিউটারের মেমরি হয় তবে স্পার্ক সনাক্ত করে যে কোন এক্সিকিউটারের ডেটা রয়েছে।
রমনা

1
@ রমনআপ্পালায় নির্বাহকের স্মৃতি ব্যবহৃত হয়। ক্যাশিংয়ের জন্য ব্যবহৃত এক্সিকিউটার মেমরির ভগ্নাংশটি কনফিগার দ্বারা নিয়ন্ত্রিত হয় spark.storage.memoryFraction। কোন এক্সিকিউটারের কোন ডেটা রয়েছে সে সম্পর্কে, কোনও আরডিডি এক্সিকিউটারদের উপর বিতরণ করা তার পার্টিশনগুলির উপর নজর রাখবে।
maasg

5
@maasg আমাকে সঠিক যদি আমি ভুল কিন্তু কেউই নই cacheকিংবা persist করতে বংশ বিরতি
শূন্য323

উপরের উদাহরণে আমাদের কাছে .cache () বিবৃতি না থাকলে শব্দগুলি আরডিডি কোথায় সংরক্ষণ করা হবে?
সূর্য_দিরে 24'17

যদি দুটি গণনার আগে, আমরা দুটি শাখাটিকে আবার এক ডিডি এবং গণনা করি? এক্ষেত্রে ক্যাশে কি উপকারী?
জিয়াওয়ে জাং

30

আরডিডি ডেটা মেমরিতে রাখার জন্য আমাদের কি স্পষ্টভাবে "ক্যাশে" বা "জেদ" রাখতে হবে?

হ্যাঁ, প্রয়োজন হলেই।

আরডিডি ডেটা ডিফল্টরূপে মেমরিতে ডিস্ট্রিবিউট উপায়ে সঞ্চিত হয়?

না!

এবং এই কারণগুলি:

  • স্পার্ক দুটি প্রকারের ভাগ করা ভেরিয়েবলগুলি সমর্থন করে: ব্রডকাস্ট ভেরিয়েবল, যা সমস্ত নোডে মেমরির একটি মান ক্যাশে করতে ব্যবহৃত হতে পারে এবং সংযোজকগুলি, যা কেবল পরিবর্তনকারী যা কাউন্টার এবং অঙ্কগুলির মতো কেবল "যুক্ত" হয়।

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

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

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

আরও তথ্যের জন্য দয়া করে স্পার্ক প্রোগ্রামিং গাইডটি দেখুন


1
এটা আমার প্রশ্নের উত্তর দেয় নি।
রমনা

এর উত্তর কি দেয় না?
ইলিয়াসহ

1
যখন আরডিডি এর ডেটা মেমরি ডিফল্টে সংরক্ষণ করা হয়, তখন আমাদের কেন ক্যাশে বা পার্সিস্ট কল করার দরকার হয়?
রমনা

আরডিডিগুলি ডিফল্টরূপে মেমরিতে সঞ্চয় হয় না, তাই
আরডিডি অবিচল করে স্পার্ককে

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

11

নীচে তিনটি পরিস্থিতিতে আপনার আরডিডিগুলি ক্যাশে করা উচিত:

একটি আরডিডি বহুবার ব্যবহার করা

একই আরডিডিতে একাধিক ক্রিয়া সম্পাদন করা

(বা খুব ব্যয়বহুল) রূপান্তরগুলির দীর্ঘ চেইনের জন্য


7

cacheপদ্ধতির কল যোগ করার জন্য (বা অস্থায়ীভাবে যুক্ত করা) অন্য কারণ যুক্ত করা ।

ডিবাগ মেমরি সমস্যা জন্য

সঙ্গে cacheপদ্ধতি, স্পার্ক RDD আকার সংক্রান্ত ডিবাগ তথ্য দিতে হবে। সুতরাং স্পার্ক ইন্টিগ্রেটেড ইউআইতে আপনি আরডিডি মেমরির ব্যবহারের তথ্য পাবেন। এবং এটি মেমরির সমস্যাগুলি নির্ণয় করতে খুব সহায়ক প্রমাণিত।

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