আমি মানচিত্র / হ্রাস সম্পর্কে প্রচুর শুনি, বিশেষত গুগলের ব্যাপকভাবে সমান্তরাল কম্পিউট সিস্টেমের প্রসঙ্গে। এটা ঠিক কি?
আমি মানচিত্র / হ্রাস সম্পর্কে প্রচুর শুনি, বিশেষত গুগলের ব্যাপকভাবে সমান্তরাল কম্পিউট সিস্টেমের প্রসঙ্গে। এটা ঠিক কি?
উত্তর:
গুগলের মানচিত্রের গবেষণা প্রকাশনার পৃষ্ঠাটির বিমূর্ততা থেকে :
ম্যাপ্রেডস হ'ল একটি প্রোগ্রামিং মডেল এবং প্রক্রিয়াকরণ এবং বড় ডেটা সেট উত্পাদন করার জন্য একটি সম্পর্কিত বাস্তবায়ন। ব্যবহারকারীরা একটি মানচিত্রের ফাংশন নির্দিষ্ট করে যা মধ্যবর্তী কী / মান জোড়ার একটি সেট তৈরি করতে একটি কী / মান জোড় প্রক্রিয়া করে এবং একটি হ্রাস ফাংশন যা একই মধ্যবর্তী কীটির সাথে সম্পর্কিত সমস্ত মধ্যবর্তী মানগুলিকে মার্জ করে।
মানচিত্রের সুবিধাটি হ'ল একাধিক প্রসেসিং নোডের (একাধিক সার্ভার) সমান্তরালে প্রক্রিয়াজাতকরণ করা যায় তাই এটি এমন একটি সিস্টেম যা খুব ভাল স্কেল করতে পারে।
যেহেতু এটি কার্যকরী প্রোগ্রামিং মডেলের ভিত্তিতে , তাই map
এবং reduce
প্রতিটি পদক্ষেপের কোনও পার্শ্ব-প্রতিক্রিয়া নেই (কোনও map
প্রক্রিয়াটির প্রতিটি অনুচ্ছেদ থেকে রাষ্ট্র এবং ফলাফলগুলি অন্যের উপর নির্ভর করে না), সুতরাং ম্যাপ করা এবং হ্রাস করা ডেটা সেট প্রতিটি পৃথক করা যায় একাধিক প্রসেসিং নোডের ওপরে।
জোলের আপনার প্রোগ্রামিং ভাষা কি এটি করতে পারে? টুকরা আলোচনা করে যে কীভাবে গুগলটিতে ক্র্যাশিয়াল প্রোগ্রামিং বোঝা অপরিহার্য ছিল ম্যাপ্রেডুস নিয়ে আসে, যা এর অনুসন্ধান ইঞ্জিনকে শক্তি দেয়। আপনি কার্যকরী প্রোগ্রামিং সম্পর্কে অপরিচিত এবং কীভাবে এটি স্কেলযোগ্য কোডটিকে মঞ্জুরি দেয় তা খুব ভাল পঠিত।
আরও দেখুন: উইকিপিডিয়া: মানচিত্রে uce
সম্পর্কিত প্রশ্ন: দয়া করে ম্যাপ্রেডসকে সহজভাবে ব্যাখ্যা করুন
আমি যা পারি তার থেকে এটি আরও ভাল ব্যাখ্যা করে। এটি সাহায্য করে?
মানচিত্র এমন একটি ফাংশন যা এতে সমস্ত ফিরতি মান সহ অন্য তালিকা তৈরি করতে তালিকার সমস্ত আইটেমের জন্য অন্য ফাংশন প্রয়োগ করে। ("অ্যাপ্লিকেশন এফ থেকে এক্স" বলার আরেকটি উপায় হ'ল "কল এফ, এটি এক্স পাস করে দিন।" তাই কখনও কখনও "কল" এর পরিবর্তে "প্রয়োগ" বলা ভাল লাগে))
এইভাবে মানচিত্রটি সম্ভবত সি # তে লিখিত হয়েছে (এটি বলা Select
হয় এবং এটি স্ট্যান্ডার্ড লাইব্রেরিতে রয়েছে):
public static IEnumerable<R> Select<T, R>(this IEnumerable<T> list, Func<T, R> func)
{
foreach (T item in list)
yield return func(item);
}
যেহেতু আপনি একজন জাভা বন্ধু, এবং জোল স্পোলস্কি জাভা কতটা কৃপণ তা সম্পর্কে গ্রোসলি অনাবশ্যক মিথ্যা বলতে পছন্দ করেন (আসলে তিনি মিথ্যা বলছেন না, এটি কৃপণ, তবে আমি আপনাকে জিততে চাইছি), এখানে আমার খুব রুক্ষ চেষ্টা একটি জাভা সংস্করণ (আমার কোনও জাভা সংকলক নেই, এবং আমি অস্পষ্টভাবে জাভা সংস্করণ 1.1 মনে করি!):
// represents a function that takes one arg and returns a result
public interface IFunctor
{
object invoke(object arg);
}
public static object[] map(object[] list, IFunctor func)
{
object[] returnValues = new object[list.length];
for (int n = 0; n < list.length; n++)
returnValues[n] = func.invoke(list[n]);
return returnValues;
}
আমি নিশ্চিত যে এটি এক মিলিয়ন উপায়ে উন্নত করা যেতে পারে। তবে এটি প্রাথমিক ধারণা।
হ্রাস হ'ল এমন একটি ফাংশন যা তালিকার সমস্ত আইটেমকে একক মানে পরিণত করে। এটি করার জন্য, এটিতে অন্য একটি ফাংশন দেওয়া দরকার func
যা দুটি আইটেমকে একক মানের করে তোলে। এটি প্রথম দুটি আইটেম দিয়ে কাজ করবে func
। তারপরে তৃতীয় আইটেমের সাথে তার ফলাফল। তারপরে চতুর্থ আইটেমের সাথে এর ফলাফল এবং সমস্ত আইটেম চলে না যাওয়া পর্যন্ত এবং আমরা একটি মান রেখে চলেছি।
সি # কমতে বলা হয় Aggregate
এবং এটি আবার স্ট্যান্ডার্ড লাইব্রেরিতে থাকে। আমি সরাসরি জাভা সংস্করণে চলে যাব:
// represents a function that takes two args and returns a result
public interface IBinaryFunctor
{
object invoke(object arg1, object arg2);
}
public static object reduce(object[] list, IBinaryFunctor func)
{
if (list.length == 0)
return null; // or throw something?
if (list.length == 1)
return list[0]; // just return the only item
object returnValue = func.invoke(list[0], list[1]);
for (int n = 1; n < list.length; n++)
returnValue = func.invoke(returnValue, list[n]);
return returnValue;
}
এই জাভা সংস্করণগুলিতে তাদের জেনেরিকগুলি যুক্ত করা দরকার, তবে জাভাতে কীভাবে তা করা যায় তা আমি জানি না। তবে ফ্যান্টেক্টর সরবরাহ করতে আপনার তাদের বেনামে অভ্যন্তরীণ ক্লাসগুলি পাস করতে সক্ষম হওয়া উচিত:
string[] names = getLotsOfNames();
string commaSeparatedNames = (string)reduce(names,
new IBinaryFunctor {
public object invoke(object arg1, object arg2)
{ return ((string)arg1) + ", " + ((string)arg2); }
}
আশা করি জেনেরিকস কাস্ট থেকে মুক্তি পাবেন। সি # তে টাইপসেফ সমতুল্য:
string commaSeparatedNames = names.Aggregate((a, b) => a + ", " + b);
কেন এই "দুর্দান্ত"? বৃহত্তর গণনাগুলি ছোট ছোট টুকরো টুকরো করার সহজ উপায়, যাতে এগুলি আবার বিভিন্ন উপায়ে একসাথে রাখা যায়, সর্বদা দুর্দান্ত। গুগল এই ধারণাটি যেভাবে প্রয়োগ করে তা হ'ল সমান্তরালকরণ, কারণ মানচিত্র এবং হ্রাস উভয়ই বেশ কয়েকটি কম্পিউটারে ভাগ করা যায়।
তবে মূল প্রয়োজনীয়তাটি নয় যে আপনার ভাষা ফাংশনকে মান হিসাবে বিবেচনা করতে পারে। যে কোনও ওও ভাষা এটি করতে পারে। সমান্তরালনের জন্য আসল প্রয়োজনীয়তা হ'ল আপনি যে ছোট্ট func
ফাংশন মানচিত্রে কমাচ্ছেন এবং হ্রাস করতে হবে তা অবশ্যই কোনও রাষ্ট্র ব্যবহার বা আপডেট করবেন না। তাদের অবশ্যই একটি মান ফেরৎ দিতে হবে যা কেবলমাত্র তাদের কাছে প্রেরিত যুক্তির (গুলি) এর উপর নির্ভরশীল। অন্যথায়, আপনি সমান্তরালভাবে পুরো জিনিসটি চালানোর চেষ্টা করার সময় ফলাফলগুলি পুরোপুরি বিভ্রান্ত হবে।
খুব দীর্ঘ ওয়াফলি বা খুব সংক্ষিপ্ত অস্পষ্ট ব্লগ পোস্টগুলির সাথে সবচেয়ে হতাশ হওয়ার পরে অবশেষে আমি এই খুব ভাল কঠোর সংক্ষিপ্ত কাগজটি আবিষ্কার করেছি ।
তারপরে আমি এগিয়ে গিয়ে স্কালায় অনুবাদ করে আরও সংক্ষিপ্ত করে তুলেছিলাম, যেখানে আমি সিম্পল কেস সরবরাহ করেছি যেখানে কোনও ব্যবহারকারী কেবল আবেদনের অংশ map
এবং reduce
অংশ নির্দিষ্ট করে দেয় specif হ্যাডোপ / স্পার্কে, কঠোরভাবে বলতে গেলে প্রোগ্রামিংয়ের আরও জটিল মডেল নিয়োগ করা হয়েছে যার জন্য ব্যবহারকারীকে এখানে বর্ণিত আরও 4 টি কার্যাদি নির্দিষ্ট করে দেওয়া দরকার: http://en.wikedia.org/wiki/MapReduce# ডেটাফ্লো
import scalaz.syntax.id._
trait MapReduceModel {
type MultiSet[T] = Iterable[T]
// `map` must be a pure function
def mapPhase[K1, K2, V1, V2](map: ((K1, V1)) => MultiSet[(K2, V2)])
(data: MultiSet[(K1, V1)]): MultiSet[(K2, V2)] =
data.flatMap(map)
def shufflePhase[K2, V2](mappedData: MultiSet[(K2, V2)]): Map[K2, MultiSet[V2]] =
mappedData.groupBy(_._1).mapValues(_.map(_._2))
// `reduce` must be a monoid
def reducePhase[K2, V2, V3](reduce: ((K2, MultiSet[V2])) => MultiSet[(K2, V3)])
(shuffledData: Map[K2, MultiSet[V2]]): MultiSet[V3] =
shuffledData.flatMap(reduce).map(_._2)
def mapReduce[K1, K2, V1, V2, V3](data: MultiSet[(K1, V1)])
(map: ((K1, V1)) => MultiSet[(K2, V2)])
(reduce: ((K2, MultiSet[V2])) => MultiSet[(K2, V3)]): MultiSet[V3] =
mapPhase(map)(data) |> shufflePhase |> reducePhase(reduce)
}
// Kinda how MapReduce works in Hadoop and Spark except `.par` would ensure 1 element gets a process/thread on a cluster
// Furthermore, the splitting here won't enforce any kind of balance and is quite unnecessary anyway as one would expect
// it to already be splitted on HDFS - i.e. the filename would constitute K1
// The shuffle phase will also be parallelized, and use the same partition as the map phase.
abstract class ParMapReduce(mapParNum: Int, reduceParNum: Int) extends MapReduceModel {
def split[T](splitNum: Int)(data: MultiSet[T]): Set[MultiSet[T]]
override def mapPhase[K1, K2, V1, V2](map: ((K1, V1)) => MultiSet[(K2, V2)])
(data: MultiSet[(K1, V1)]): MultiSet[(K2, V2)] = {
val groupedByKey = data.groupBy(_._1).map(_._2)
groupedByKey.flatMap(split(mapParNum / groupedByKey.size + 1))
.par.flatMap(_.map(map)).flatten.toList
}
override def reducePhase[K2, V2, V3](reduce: ((K2, MultiSet[V2])) => MultiSet[(K2, V3)])
(shuffledData: Map[K2, MultiSet[V2]]): MultiSet[V3] =
shuffledData.map(g => split(reduceParNum / shuffledData.size + 1)(g._2).map((g._1, _)))
.par.flatMap(_.map(reduce))
.flatten.map(_._2).toList
}
মানচিত্রটি একটি দেশীয় জেএস পদ্ধতি যা অ্যারেতে প্রয়োগ করা যেতে পারে। এটি মূল অ্যারেটিতে প্রতিটি উপাদানকে ম্যাপ করা কিছু ফাংশনের ফলস্বরূপ একটি নতুন অ্যারে তৈরি করে। সুতরাং আপনি যদি কোনও ফাংশন (উপাদান) {রিটার্ন এলিমেন্ট * 2; ma ম্যাপ করে থাকেন তবে এটি প্রতিটি উপাদান দ্বিগুণ করে একটি নতুন অ্যারে প্রদান করবে। মূল অ্যারেটি অবিস্মরণীয় হয়ে যাবে।
https://developer.mozilla.org/en-US/docs/Web/JavaScript/ উল্লেখ / গ্লোবাল_অবজেক্টস / অ্যারে / ম্যাপ
হ্রাস হ'ল একটি নেটিভ জেএস পদ্ধতি যা অ্যারেতে প্রয়োগ করা যেতে পারে। এটি একটি অ্যারেতে একটি ফাংশন প্রয়োগ করে এবং এতে একটি প্রাথমিক আউটপুট মান থাকে যা একটি জড়িত সংস্থাপক বলে। এটি অ্যারের প্রতিটি উপাদানের মধ্য দিয়ে লুপ করে, একটি ফাংশন প্রয়োগ করে এবং সেগুলিকে একক মানকে হ্রাস করে (যা সঞ্চয়ের হিসাবে শুরু হয়)। এটি দরকারী কারণ আপনার যে কোনও আউটপুট আপনি চান করতে পারেন, আপনাকে কেবলমাত্র সেই ধরণের সঞ্চয়ের সাথে শুরু করতে হবে। সুতরাং যদি আমি কোনও জিনিসে কোনও কিছু হ্রাস করতে চাই, তবে আমি একটি সঞ্চালক start with দিয়ে শুরু করব}
মানচিত্র কমাতে:
বড় কিছু চালানোর জন্য, আমরা আমাদের অফিসে বিভিন্ন কম্পিউটারের গণনা শক্তি ব্যবহার করতে পারি। কঠিন অংশটি হ'ল বিভিন্ন কম্পিউটারের মধ্যে কাজকে বিভক্ত করা Map এটি ম্যাপ্রেডুস লাইব্রেরি দ্বারা সম্পন্ন হয়।
প্রাথমিক ধারণাটি হ'ল আপনি কাজটি দুটি ভাগে ভাগ করেছেন: একটি মানচিত্র এবং একটি হ্রাস। মানচিত্রটি মূলত সমস্যাটি গ্রহণ করে, উপ-অংশে বিভক্ত করে এবং উপ-অংশগুলি বিভিন্ন মেশিনে প্রেরণ করে - সুতরাং সমস্ত টুকরো একই সাথে চালিত হয়। হ্রাস উপ-অংশগুলি থেকে ফলাফলগুলি নেয় এবং একক উত্তর পেতে তাদের আবার একত্রিত করে।
ইনপুট রেকর্ডগুলির একটি তালিকা the মানচিত্রের গণনার ফলাফল কী / মান জোড়ার একটি তালিকা of হ্রাস হ'ল প্রতিটি কী একই মান রয়েছে এমন মানগুলির সেট করে এবং সেগুলিকে একক মানের সাথে সংযুক্ত করে You কাজটি 100 টুকরো বা 2 টুকরোতে বিভক্ত হয়েছিল কিনা তা আপনি বলতে পারবেন না; শেষের ফলাফলটি দেখতে অনেকটা একক মানচিত্রের ফলাফলের মতো দেখাচ্ছে।
সহজ মানচিত্র দেখুন এবং প্রোগ্রাম হ্রাস করুন:
মানচিত্র ফাংশনটি আমাদের মূল তালিকায় কিছু ফাংশন প্রয়োগ করতে ব্যবহৃত হয় এবং তাই একটি নতুন তালিকা তৈরি করা হয়। পাইথনের মানচিত্র () ফাংশনটি একটি ফাংশন এবং যুক্তি হিসাবে একটি তালিকা গ্রহণ করে। তালিকার প্রতিটি আইটেমে ফাংশন প্রয়োগ করে একটি নতুন তালিকা ফিরে আসে।
li = [5, 7, 4, 9]
final_list = list(map(lambda x: x*x , li))
print(final_list) #[25, 49, 16, 81]
পাইথনের হ্রাস () ফাংশনটি একটি ফাংশন এবং যুক্তি হিসাবে একটি তালিকা গ্রহণ করে। ফাংশনটি ল্যাম্বডা ফাংশন এবং একটি তালিকা দিয়ে ডাকা হয় এবং একটি নতুন হ্রাস ফলাফল ফিরে আসে। এটি তালিকার জোড়গুলির উপরে পুনরাবৃত্ত ক্রিয়াকলাপ সম্পাদন করে।
#reduce func to find product/sum of list
x=(1,2,3,4)
from functools import reduce
reduce(lambda a,b:a*b ,x) #24