স্পার্ক - পুনরায় বিভাজন () বনাম কোলেসেস ()


251

লার্নিং স্পার্ক অনুযায়ী

মনে রাখবেন যে আপনার ডেটা পুনরায় ভাগ করা মোটামুটি ব্যয়বহুল ক্রিয়াকলাপ। স্পার্কে repartition()ডাকা একটি অপ্টিমাইজড সংস্করণ রয়েছে যা coalesce()ডেটা চলাচল এড়াতে দেয় তবে কেবল যদি আপনি আরডিডি পার্টিশনের সংখ্যা হ্রাস করে থাকেন।

একটি পার্থক্য যা আমি পাই তা হ'ল repartition()পার্টিশনের সংখ্যা বাড়িয়ে / হ্রাস করা যায়, তবে coalesce()পার্টিশনের সংখ্যার সাথে কেবল হ্রাস করা যায়।

পার্টিশনগুলি যদি একাধিক মেশিনে ছড়িয়ে পড়ে এবং coalesce()চালিত হয় তবে কীভাবে এটি ডেটা চলাচল এড়াতে পারে?

উত্তর:


351

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

সুতরাং, এটি কিছু এই যেতে হবে:

Node 1 = 1,2,3
Node 2 = 4,5,6
Node 3 = 7,8,9
Node 4 = 10,11,12

তারপরে coalesce2 টি পার্টিশন পর্যন্ত নামিয়ে দিন:

Node 1 = 1,2,3 + (10,11,12)
Node 3 = 7,8,9 + (4,5,6)

লক্ষ্য করুন নোড 1 এবং নোড 3 এর সরানোর জন্য এটির আসল ডেটার প্রয়োজন হয় না।


114
উত্তরের জন্য ধন্যবাদ. ডকুমেন্টেশন minimize data movementপরিবর্তে ভাল বলা উচিত ছিল avoiding data movement
প্রবীণ শ্রীপতি

12
এর repartitionপরিবর্তে কখন ব্যবহার করা উচিত coalesce?
নিয়মান্ড

20
@Niemand আমি মনে করি বর্তমান ডকুমেন্টেশন কভার এই চমত্কার: github.com/apache/spark/blob/... মন যে সব রাখুন repartitionকরে কল coalesceসঙ্গে shuffleসত্যতে প্যারামিটার সেট। যদি এটি সাহায্য করে তবে আমাকে জানান।
জাস্টিন পিহনি

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

2
বিভাগটি পরিসংখ্যানগতভাবে ধীর হবে কারণ এটি জানেন না যে এটি সঙ্কুচিত হচ্ছে ... যদিও তারা এটি অপ্টিমাইজ করতে পারে। অভ্যন্তরীণভাবে এটি কেবল একটি shuffle = trueপতাকার সাথে
কোলেসেসকে

169

জাস্টিনের উত্তর দুর্দান্ত এবং এই প্রতিক্রিয়া আরও গভীরতর মধ্যে যায়।

repartitionঅ্যালগরিদম একটি পূর্ণ এলোমেলো করে এবং ডেটা সমানভাবে বিতরণ হচ্ছে সাথে নতুন পার্টিশন তৈরি করে। 1 থেকে 12 নম্বর সহ একটি ডেটা ফ্রেম তৈরি করা যাক।

val x = (1 to 12).toList
val numbersDf = x.toDF("number")

numbersDf আমার মেশিনে 4 টি পার্টিশন রয়েছে।

numbersDf.rdd.partitions.size // => 4

পার্টিশনের উপর ডেটা কীভাবে ভাগ করা যায় তা এখানে:

Partition 00000: 1, 2, 3
Partition 00001: 4, 5, 6
Partition 00002: 7, 8, 9
Partition 00003: 10, 11, 12

আসুন repartitionপদ্ধতিটির সাথে একটি পূর্ণ শ্যফেল করুন এবং দুটি নোডে এই ডেটাটি নিয়ে আসি।

val numbersDfR = numbersDf.repartition(2)

numbersDfRআমার মেশিনে ডেটা কীভাবে বিভক্ত করা হয়েছে তা এখানে :

Partition A: 1, 3, 4, 6, 7, 9, 10, 12
Partition B: 2, 5, 8, 11

repartitionপদ্ধতি নতুন পার্টিশন করে তোলে এবং সমানভাবে নতুন পার্টিশন ডাটা বিতরণ (ডাটা বন্টন আরো এমনকি বড় ডেটা সেটের জন্য) হয়।

coalesceএবং মধ্যে পার্থক্যrepartition

coalesceযে পরিমাণে ডেটা বদলে গেছে তা হ্রাস করতে বিদ্যমান পার্টিশন ব্যবহার করে। repartitionনতুন পার্টিশন তৈরি করে এবং পুরো শ্যাফেল করে। coalesceবিভিন্ন পরিমাণে ডেটা (অনেক সময় পার্টিশনের মধ্যে অনেক বেশি আকার রয়েছে) এর repartitionপার্টিশনের ফলাফল এবং প্রায় সমান আকারের পার্টিশনের ফলাফল।

কি coalesceবা repartitionদ্রুততর?

coalesceতুলনায় দ্রুত চলতে পারে repartition, তবে অসম আকারের পার্টিশনগুলি সমান আকারের পার্টিশনের তুলনায় সাধারণত ধীর হয়। একটি বড় ডেটা সেট ফিল্টার করার পরে আপনার সাধারণত ডেটাসেটগুলি পুনরায় ভাগ করতে হবে। আমি repartitionসামগ্রিকভাবে দ্রুত হতে পেরেছি কারণ স্পার্ক সমান আকারের পার্টিশনগুলির সাথে কাজ করতে নির্মিত।

এনবি আমি কৌতূহলবশত পর্যবেক্ষণ করেছি যে পুনরায় বিভাজন ডিস্কে ডেটার আকার বাড়াতে পারে । আপনি যখন বড় ডেটাসেটগুলিতে বিভাগ / coalesce ব্যবহার করছেন তখন পরীক্ষা চালানোর বিষয়ে নিশ্চিত হন।

আপনি আরও বিশদ জানতে চাইলে এই ব্লগ পোস্টটি পড়ুন

আপনি যখন অনুশীলনে কোলেসেস এবং পার্টিশন ব্যবহার করবেন


8
দুর্দান্ত উত্তর @ পাওয়ার্স, তবে পার্টিশন এ এবং বি এর ডেটাগুলি স্কিউড নয়? এটি কীভাবে সমানভাবে বিতরণ করা হয়?
আনোয়ার্থেরভিয়ান

এছাড়াও, OOM ত্রুটি না পেয়ে পার্টিশন আকার পাওয়ার সর্বোত্তম উপায়। আমি ব্যবহার করি rdd.glom().map(len).collect()তবে এটি প্রচুর OOM ত্রুটি দেয়।
আনোয়ার্থেরভিয়ান

8
@ উত্তরওয়ারিভিয়ান - পার্টিশন এ এবং পার্টিশন বি বিভিন্ন আকারের কারণ repartitionঅ্যালগরিদম খুব অল্প ডেটা সেটগুলির জন্য সমানভাবে ডেটা বিতরণ করে না। আমি repartition13 টি পার্টিশনে 5 মিলিয়ন রেকর্ডগুলি সংগঠিত করতাম এবং প্রতিটি ফাইল 89.3 এমবি এবং 89.6 মেগাবাইটের মধ্যে ছিল - এটি বেশ সমান!
পাওয়ার

1
@ পাওয়ারগুলি এই বর্ণনটির সাথে আরও ভাল উত্তর দেবে।
সবুজ

1
এটি পার্থক্যটি আরও অনেক ভাল ব্যাখ্যা করে। ধন্যবাদ!
অভি

22

এখানে আরও একটি লক্ষণীয় বিষয় উল্লেখযোগ্য হ'ল স্পার্ক আরডিডি-র মূল নীতিটি হ'ল অপরিবর্তনীয়তা। পুনঃভাগ বা coalesce নতুন আরডিডি তৈরি করবে। বেস আরডিডি এর পার্টিশনের মূল সংখ্যার সাথে অস্তিত্ব রাখতে থাকবে। যদি ব্যবহারের ক্ষেত্রে আরডিডি ক্যাশে রাখার দাবি করে তবে সদ্য তৈরি আরডিডি-তেও এটি করতে হবে for

scala> pairMrkt.repartition(10)
res16: org.apache.spark.rdd.RDD[(String, Array[String])] =MapPartitionsRDD[11] at repartition at <console>:26

scala> res16.partitions.length
res17: Int = 10

scala>  pairMrkt.partitions.length
res20: Int = 2

সুন্দর! এটি সমালোচিত এবং কমপক্ষে এই অভিজ্ঞ স্কেল দেবের কাছে, সুস্পষ্ট নয় - অর্থাত্, কীভাবে নোডগুলিতে এটি বিতরণ করা হয় তা ঠিক কীভাবে পুনর্বিবেচনা বা কোলেসেসের প্রচেষ্টা নয়
ডগ

1
@ হারিকৃষ্ণান তাই যদি আমি অন্যান্য উত্তরগুলি সঠিকভাবে বুঝতে পারি তবে কোলেসিস স্পার্কের ক্ষেত্রে বিদ্যমান পার্টিশনগুলি ব্যবহার করে তবে আরডিডি অপরিবর্তনীয় আপনি কীভাবে কোলেসকে বিদ্যমান পার্টিশন ব্যবহার করতে পারবেন তা বর্ণনা করতে পারবেন? আমার উপলব্ধি অনুসারে আমি ভেবেছিলাম স্পার্ক কোলেসেসের বিদ্যমান পার্টিশনে নতুন পার্টিশন যুক্ত করে।
এক্সপ্লোরার

কিন্তু "পুরাতন" আরডিডি যদি আর ব্যবহার না করা হয় যেমন এক্সিকিউশন গ্রাফ দ্বারা জানা যায় এটি যদি না ধরে থাকে তবে এটি মেমরি থেকে সাফ হয়ে যায়, তাই না?
মার্কাস

15

repartition - পার্টিশনের সংখ্যা বাড়ানোর সময় এটি ব্যবহার করার পরামর্শ দেওয়া হয়েছে, কারণ এতে সমস্ত ডেটা পরিবর্তন করা জড়িত।

coalesce- পার্টিশনের সংখ্যা হ্রাস করার সময় এটি ব্যবহার করার পরামর্শ দেওয়া হচ্ছে। উদাহরণস্বরূপ আপনার যদি 3 টি পার্টিশন থাকে এবং আপনি এটি 2 এ হ্রাস করতে চান coalesceতবে তৃতীয় পার্টিশন ডেটাটি পার্টিশন 1 এবং 2 এ সরানো হবে Part পার্টিশন 1 এবং 2 একই ধারকতে থাকবে। অন্যদিকে, repartitionসমস্ত পার্টিশনে ডেটা বদল করা হবে, তাই এক্সিকিউটারদের মধ্যে নেটওয়ার্কের ব্যবহার বেশি হবে এবং এটি কর্মক্ষমতাকে প্রভাবিত করবে।

coalescerepartitionপার্টিশনের সংখ্যা হ্রাস করার চেয়ে ভাল পারফর্ম করে ।


দরকারী ব্যাখ্যা।
নরেন্দ্র মারু

11

কোড এবং কোড ডক্স থেকে যা যা অনুসরণ করে তা coalesce(n)হ'ল একই coalesce(n, shuffle = false)এবং repartition(n)একই রকমcoalesce(n, shuffle = true)

সুতরাং, উভয় coalesceএবং repartitionপার্টিশনের সংখ্যা বৃদ্ধি করতে ব্যবহার করা যেতে পারে

এর সাথে shuffle = true, আপনি আসলে বৃহত সংখ্যক পার্টিশনে একত্রিত করতে পারেন। আপনার যদি কয়েকটি সংখ্যক পার্টিশন থাকে তবে এটি কার্যকর হয়, ১০০ বলুন, কয়েকটি পার্টিশনটি অস্বাভাবিকভাবে বড় হওয়ার কারণে সম্ভাব্য ally

উচ্চারণ করার জন্য আরেকটি গুরুত্বপূর্ণ নোট হ'ল আপনি যদি পার্টিশনের সংখ্যা হ্রাস করতে পারেন তবে আপনার পরিবর্তিত সংস্করণ coalesce(সেই repartitionক্ষেত্রে একই ) ব্যবহার করা উচিত । এটি আপনার গণনাগুলি প্যারেন্ট পার্টিশনের (একাধিক টাস্ক) সমান্তরালে সঞ্চালনের অনুমতি দেবে ।

তবে, আপনি যদি একটি কঠোর coalesce করছেন, উদাহরণস্বরূপ numPartitions = 1, এটি আপনার গণনাটি আপনার পছন্দের চেয়ে কম নোডে স্থান নিতে পারে (যেমন, একটি নোডের ক্ষেত্রে numPartitions = 1)। এটি এড়াতে, আপনি পাস করতে পারেন shuffle = true। এটি একটি বদল পদক্ষেপ যোগ করবে, তবে এর অর্থ বর্তমান প্রবাহের পার্টিশনগুলি সমান্তরালভাবে কার্যকর করা হবে (বর্তমান পার্টিশন যা-ই হোক না কেন)

দয়া করে এখানে সম্পর্কিত উত্তরটি দেখুন


10

সমস্ত উত্তর এই প্রায়শই জিজ্ঞাসিত প্রশ্নে কিছু দুর্দান্ত জ্ঞান যুক্ত করছে।

সুতরাং এই প্রশ্নের টাইমলাইনের traditionতিহ্য অনুসারে, আমার 2 সেন্ট এখানে রয়েছে।

আমি খুব সুনির্দিষ্ট ক্ষেত্রে, কোএলেসেসের চেয়ে দ্রুততর অবস্থা দেখতে পেয়েছি ।

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

এখানে আমি যা বলতে চাইছি তা এখানে

if(numFiles > 20)
    df.coalesce(numFiles).write.mode(SaveMode.Overwrite).parquet(dest)
else
    df.repartition(numFiles).write.mode(SaveMode.Overwrite).parquet(dest)

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

অবশ্যই, এই সংখ্যা (20) শ্রমিকের সংখ্যা এবং ডেটা পরিমাণের উপর নির্ভর করবে।

আশা করি এইটি কাজ করবে.


6

পুনঃবিভাজন : পার্টিশনের একটি নতুন সংখ্যায় ডেটা পরিবর্তন করুন।

যেমন। প্রাথমিক ডেটা ফ্রেমটি 200 পার্টিশনে বিভক্ত হয়।

df.repartition(500): ডেটা 200 পার্টিশন থেকে নতুন 500 টি পার্টিশনে স্থানান্তরিত হবে।

কোলেসেস : পার্টিশনের বিদ্যমান সংখ্যার সাথে ডেটা পরিবর্তন করুন।

df.coalesce(5): বাকী 195 টি পার্টিশন থেকে 5 টি বিদ্যমান পার্টিশনে ডেটা বদলানো হবে।


3

আমি জাস্টিন এবং পাওয়ার উত্তরে যুক্ত করতে চাই যে -

repartitionবিদ্যমান পার্টিশনগুলি উপেক্ষা করবে এবং একটি নতুন তৈরি করবে। সুতরাং আপনি ডেটা স্কিউ ঠিক করতে এটি ব্যবহার করতে পারেন। আপনি বিতরণ সংজ্ঞায়িত করতে পার্টিশন কী উল্লেখ করতে পারেন mention ডেটা স্কিউ 'বিগ ডেটা' সমস্যা স্থানের বৃহত্তম সমস্যাগুলির মধ্যে একটি।

coalesceবিদ্যমান পার্টিশনগুলির সাথে কাজ করবে এবং সেগুলির একটি উপসেটটি বদল করবে। এটি যতটা repartitionকরে তা ডেটা স্কিউ ঠিক করতে পারে না । সুতরাং এটি কম ব্যয়বহুল হলেও আপনার প্রয়োজনীয় জিনিসটি এটি নাও হতে পারে।


3

সমস্ত দুর্দান্ত উত্তরের সাথে আমি যুক্ত করতে চাই যে repartitionএটি ডেটা প্যারালাইজালাইজের সুবিধা নেওয়ার সেরা বিকল্প। যদিও coalesceএকটি সস্তা পার্টিশন কমাতে বিকল্প দেয় এবং এটি খুবই দরকারী যখন HDFS অথবা অন্য কোনো বেসিনে ডেটা লিখন বড় লিখেছেন সুবিধা গ্রহণ করতে।

পূর্ণ সুবিধা পেতে তোড়জোড় ফর্ম্যাটে ডেটা লেখার সময় আমি এই দরকারীটি পেয়েছি।


2

যার যার জন্য পাইসপার্ক (এডাব্লুএস ইএমআর) থেকে আউটপুট হিসাবে একটি সিএসভি ফাইল উত্পন্ন করার এবং পুনরায় বিভাগ ব্যবহার করে এটি এস 3 এ সংরক্ষণ করার ক্ষেত্রে সমস্যা ছিল। কারণ হ'ল, কোলেসেস পুরোপুরি পরিবর্তন করতে পারে না, তবে পার্টিশন পারে। মূলত, আপনি পুনরায় বিভাজন ব্যবহার করে পার্টিশনের সংখ্যা বাড়াতে বা হ্রাস করতে পারেন, তবে কেবলমাত্র কোয়েলস ব্যবহার করে পার্টিশনের সংখ্যা (তবে 1 নয়) হ্রাস করতে পারবেন। যে কেউ এইডাব্লুএস ইএমআর থেকে এস 3 তে সিএসভি লেখার চেষ্টা করছে তার কোড এখানে:

df.repartition(1).write.format('csv')\
.option("path", "s3a://my.bucket.name/location")\
.save(header = 'true')

0

একটি সহজ উপায়ে COALESCE: - কেবলমাত্র পার্টিশনের সংখ্যা হ্রাস করার জন্য, ডেটা বদলানো এটি কেবলমাত্র পার্টিশনকে সংকুচিত করে না

পার্টিশন: - পার্টিশনের সংখ্যা বৃদ্ধি এবং হ্রাস উভয়ের জন্য, তবে বদলে যায়

উদাহরণ: -

val rdd = sc.textFile("path",7)
rdd.repartition(10)
rdd.repartition(2)

উভয়ই ঠিকঠাক কাজ করে

তবে আমরা সাধারণত এই দুটি জিনিসের জন্য যাই যখন আমাদের একটি ক্লাস্টারে আউটপুট দেখতে হয়, আমরা এটি নিয়ে যাই।


9
কোলেসের সাথে ডেটা চলাচলও থাকবে।
সূর্য_দিরে

0

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

সমাহার এবং পুনরায় বিভাজনের মধ্যে নির্বাচন করতে বুদ্ধিমান হন।


0

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

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

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

আপনি আরও বিশদ জানতে চাইলে এই ব্লগ পোস্টটি পড়ুন

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