কোডটি নিয়ে আলোচনা করা মূল উত্তরটি নীচে পাওয়া যাবে।
প্রথমত, আপনাকে আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা API API আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা নাਲੇর না হয়ে যায় তার দ্বারা নিখুঁত করা যায় এমন জায়গা।।।।।।।।।।।।।।।।।।।।।।।।।।।। প্রথমত, আপনাকে বিভিন্ন ধরণের এপিআইয়ের মধ্যে পার্থক্য করতে হবে, প্রতিটি তার নিজস্ব কার্যকারিতা বিবেচনা করে।
আরডিডি এপিআই
(জেভিএম ভিত্তিক অর্কেস্ট্রেশন সহ খাঁটি পাইথন কাঠামো)
এটি সেই উপাদান যা পাইথন কোডের কার্য সম্পাদন এবং পাইস্পার্ক বাস্তবায়নের বিশদ দ্বারা সবচেয়ে বেশি প্রভাবিত হবে। পাইথনের পারফরম্যান্সে সমস্যা হওয়ার সম্ভাবনা কম থাকলেও আপনাকে অন্তত কয়েকটি কারণ বিবেচনা করতে হবে:
- জেভিএম যোগাযোগের ওভারহেড। ব্যবহারিকভাবে পাইথন নির্বাহকের কাছে আসা এবং আসা সমস্ত ডেটা সকেট এবং একটি জেভিএম কর্মীর মধ্য দিয়ে যেতে হবে। যদিও এটি তুলনামূলকভাবে দক্ষ স্থানীয় যোগাযোগ এটি এখনও নিখরচায় নয়।
প্রক্রিয়া-ভিত্তিক নির্বাহক (পাইথন) বনাম থ্রেড ভিত্তিক (একক জেভিএম একাধিক থ্রেড) এক্সিকিউটর (স্কালা)। প্রতিটি পাইথন এক্সিকিউটিউটর নিজস্ব প্রক্রিয়াতে চলে। পার্শ্ব প্রতিক্রিয়া হিসাবে, এটি এর JVM অংশের চেয়ে শক্তিশালী বিচ্ছিন্নতা এবং এক্সিকিউটার লাইফসাইকের উপর কিছু নিয়ন্ত্রণ সরবরাহ করে তবে সম্ভাব্যভাবে উল্লেখযোগ্যভাবে উচ্চতর মেমরির ব্যবহার করে:
- দোভাষী মেমরি পদচিহ্ন
- লোডড লাইব্রেরির পদাঙ্ক
- কম দক্ষ সম্প্রচার (প্রতিটি প্রক্রিয়াটির একটি সম্প্রচারের নিজস্ব কপি প্রয়োজন)
পাইথন কোড নিজেই সম্পাদনা। সাধারণত স্ক্যালালা বলতে পাইথনের চেয়ে দ্রুত তবে তা টাস্কে আলাদা হয়ে যায়। তাছাড়া তোমার মত JITs একাধিক অপশন আছে Numba , সি Extensions ( Cython ) অথবা মত বিশেষ লাইব্রেরি Theano । অবশেষে, আপনি যদি এমএল / MLlib (বা শুধু NumPy স্ট্যাক) ব্যবহার করে না , ব্যবহারের বিষয়ে বিবেচনা PyPy একটি বিকল্প দোভাষী হিসেবে। স্পার্ক -3094 দেখুন ।
- পাইস্পার্ক কনফিগারেশন
spark.python.worker.reuse
বিকল্প সরবরাহ করে যা প্রতিটি কাজের জন্য পাইথন প্রক্রিয়াটি ফোরকিং এবং বিদ্যমান প্রক্রিয়া পুনরায় ব্যবহারের মধ্যে চয়ন করতে ব্যবহার করা যেতে পারে। পরবর্তী বিকল্পটি ব্যয়বহুল আবর্জনা সংগ্রহ এড়াতে দরকারী বলে মনে হচ্ছে (এটি নিয়মিত পরীক্ষার ফলাফলের চেয়ে বেশি ছাপ), তবে ব্যয়বহুল সম্প্রচার এবং আমদানির ক্ষেত্রে পূর্বেরটি (ডিফল্ট) অনুকূল।
- সিপিথনে প্রথম লাইনের আবর্জনা সংগ্রহের পদ্ধতি হিসাবে ব্যবহৃত রেফারেন্স গণনা টিপিকাল স্পার্ক ওয়ার্কলোডগুলি (স্ট্রিমের মতো প্রক্রিয়াজাতকরণ, কোনও রেফারেন্স চক্র) নিয়ে বেশ ভাল কাজ করে এবং দীর্ঘ জিসি বিরতির ঝুঁকি হ্রাস করে।
MLlib
(পাইথন এবং জেভিএম মিশ্রিত)
বুনিয়াদি বিবেচনাগুলি কয়েকটি অতিরিক্ত সমস্যা নিয়ে আগের মতো একই are যদিও এমএলিবের সাথে ব্যবহৃত বেসিক স্ট্রাকচারগুলি সরল পাইথন আরডিডি অবজেক্ট, সমস্ত অ্যালগরিদমগুলি সরাসরি স্কালা ব্যবহার করে কার্যকর করা হয়।
এর অর্থ পাইথন অবজেক্টগুলিকে স্কালা অবজেক্টে রূপান্তর করার অতিরিক্ত ব্যয় এবং অন্যান্য উপায়ে, মেমরির ব্যবহার বৃদ্ধি করা এবং কিছু অতিরিক্ত সীমাবদ্ধতা যা আমরা পরে কভার করব।
এখন (স্পার্ক 2.x) হিসাবে, আরডিডি-ভিত্তিক এপিআই একটি রক্ষণাবেক্ষণ মোডে রয়েছে এবং স্পার্ক 3.0 এ অপসারণের সময় নির্ধারিত হয়েছে ।
ডেটা ফ্রেম এপিআই এবং স্পার্ক এমএল
(পাইথন কোড সহ জেভিএম কার্যকরকরণ ড্রাইভারের মধ্যে সীমাবদ্ধ)
এগুলি সম্ভবত স্ট্যান্ডার্ড ডেটা প্রসেসিংয়ের জন্য সেরা পছন্দ। যেহেতু পাইথন কোডটি বেশিরভাগ ড্রাইভারের উপর উচ্চ-স্তরের লজিক্যাল অপারেশনে সীমাবদ্ধ তাই পাইথন এবং স্কালার মধ্যে পারফরম্যান্সের পার্থক্য থাকা উচিত নয়।
একক ব্যতিক্রম হ'ল সারি-ভিত্তিক পাইথন ইউডিএফ ব্যবহার যা তাদের স্কাল সমতুল্যের তুলনায় উল্লেখযোগ্যভাবে কম দক্ষ। উন্নতির জন্য কিছু সুযোগ থাকলেও (স্পার্ক ২.০.০-তে যথেষ্ট বিকাশ হয়েছে), সর্বাধিক সীমাবদ্ধতা হ'ল অভ্যন্তরীণ উপস্থাপনা (জেভিএম) এবং পাইথন ইন্টারপ্রেটারের মধ্যে পূর্ণ বৃত্তাকার। যদি সম্ভব হয় তবে আপনার বিল্ট-ইন এক্সপ্রেশনগুলির একটি সংমিশ্রনের পক্ষে হওয়া উচিত ( উদাহরণস্বরূপ । পাইথন ইউডিএফ আচরণটি স্পার্ক ২.০.০-তে উন্নত করা হয়েছে, তবে এটি এখনও দেশীয় মৃত্যুদন্ড কার্যকর করার তুলনায় সাব-ইস্টিমাল।
এই উন্নত ভবিষ্যৎ পারে উল্লেখযোগ্যভাবে প্রবর্তনের সঙ্গে উন্নতি হয়েছে ভেক্টরকৃত UDFs (স্পার্ক-21190 এবং আরও এক্সটেনশানগুলি) , যা শূন্য-অনুলিপি deserialization সঙ্গে দক্ষ ডাটা বিনিময় জন্য অ্যারো স্ট্রীমিং ব্যবহার করে। বেশিরভাগ অ্যাপ্লিকেশনগুলির জন্য তাদের গৌণ ওভারহেডগুলি কেবল উপেক্ষা করা যেতে পারে।
DataFrames
এবং এর মধ্যে অপ্রয়োজনীয় পাসিং ডেটা এড়াতে ভুলবেন না RDDs
। এটিতে ব্যয়বহুল সিরিয়ালাইজেশন এবং ডিসরিয়ালাইজেশন প্রয়োজন, পাইথন ইন্টারপ্রেটারে এবং থেকে ডেটা স্থানান্তরের কথা উল্লেখ না করা।
এটি লক্ষণীয় যে পাই 4 জে কলগুলির উচ্চতর বিলম্ব রয়েছে। এর মধ্যে সহজ কলগুলি অন্তর্ভুক্ত রয়েছে:
from pyspark.sql.functions import col
col("foo")
সাধারণত, এটি বিবেচনা করা উচিত নয় (ওভারহেড ধ্রুবক এবং তথ্যের পরিমাণের উপর নির্ভর করে না) তবে নরম রিয়েল-টাইম অ্যাপ্লিকেশনগুলির ক্ষেত্রে, আপনি জাভা মোড়কে ক্যাশে / পুনঃব্যবহারের বিষয়টি বিবেচনা করতে পারেন।
গ্রাফএক্স এবং স্পার্ক ডেটাসেটস
এখনকার হিসাবে (স্পার্ক 1.6 2.1) একটিও পাইসপার্ক এপিআই সরবরাহ করে না তাই আপনি বলতে পারেন যে পাইসপার্ক স্কালার চেয়ে সীমিতভাবে খারাপ।
GraphX
বাস্তবে, GraphX উন্নয়ন প্রায় পুরোপুরি থামিয়ে প্রকল্পের সঙ্গে রক্ষণাবেক্ষণ মোডে বর্তমানে যেমন বন্ধ সংশ্লিষ্ট জির টিকেট ঠিক হবে না । গ্রাফ্রেমস লাইব্রেরি পাইথন বাইন্ডিং সহ একটি বিকল্প গ্রাফ প্রসেসিং লাইব্রেরি সরবরাহ করে।
ডেটা সেটটি
বিষয়গতভাবে বলতে গেলে পাইথনগুলিতে স্ট্যাটিকালি টাইপের জন্য খুব বেশি জায়গা নেই Datasets
এবং যদি বর্তমান স্কাল বাস্তবায়ন খুব সরল এবং এটির মতো পারফরম্যান্স সুবিধা দেয় না তবে DataFrame
।
স্ট্রিমিং
আমি এখন পর্যন্ত যা দেখেছি সেখান থেকে আমি পাইথনের ওপরে স্কালার ব্যবহারের জন্য দৃ strongly়তার সাথে পরামর্শ দেব। এটি ভবিষ্যতে পরিবর্তন হতে পারে যদি পাইসপার্ক কাঠামোগত স্ট্রিমগুলির জন্য সমর্থন পায় তবে এখনই স্কেলা এপিআই আরও বেশি শক্তিশালী, বিস্তৃত এবং দক্ষ বলে মনে হচ্ছে। আমার অভিজ্ঞতা বেশ সীমাবদ্ধ।
স্পার্ক ২.x এ স্ট্রাকচার্ড স্ট্রিমিংয়ের মাধ্যমে ভাষার মধ্যকার ব্যবধান হ্রাস পেতে পারে তবে আপাতত এটি এখনও তার প্রাথমিক দিনগুলিতে রয়েছে। তবুও, আরডিডি ভিত্তিক এপিআইটি ইতিমধ্যে ডেটাব্রিক্স ডকুমেন্টেশনে "লিগ্যাসি স্ট্রিমিং" হিসাবে উল্লেখ করা হয়েছে (অ্যাক্সেসের তারিখ 2017-03-03)) সুতরাং আরও একীকরণের প্রচেষ্টা আশা করা যুক্তিসঙ্গত।
অ-কর্মক্ষমতা বিবেচনা
বৈশিষ্ট্য সমতা
সমস্ত স্পার্ক বৈশিষ্ট্য পাইসপার্ক এপিআই এর মাধ্যমে প্রকাশিত হয় না। আপনার প্রয়োজনীয় অংশগুলি ইতিমধ্যে বাস্তবায়িত হয়েছে কিনা তা পরীক্ষা করে দেখুন এবং সম্ভাব্য সীমাবদ্ধতাগুলি বোঝার চেষ্টা করুন।
এটি বিশেষভাবে গুরুত্বপূর্ণ যখন আপনি এমএলিব এবং অনুরূপ মিশ্র প্রসঙ্গ ব্যবহার করেন ( কোনও কাজ থেকে জাভা / স্কালা ফাংশন কলিং দেখুন )। পাইস্পার্ক এপিআই-এর কিছু অংশ ন্যায্য হওয়ার জন্য mllib.linalg
, স্কালার চেয়ে আরও বিস্তৃত পদ্ধতির সেট সরবরাহ করে।
এপিআই নকশা
পাইস্পার্ক এপিআই এর স্কেল সমকক্ষকে ঘনিষ্ঠভাবে প্রতিফলিত করে এবং যেমনটি পাইথোনিক নয় exactly এর অর্থ এটি যে ভাষাগুলির মধ্যে মানচিত্র তৈরি করা বেশ সহজ তবে একই সাথে পাইথন কোডটি বোঝাও যথেষ্ট কঠিন।
জটিল স্থাপত্য
খালি জেভিএম প্রয়োগের তুলনায় পাইস্পার্ক ডেটা প্রবাহ তুলনামূলকভাবে জটিল। পাইস্পার্ক প্রোগ্রামগুলি বা ডিবাগ সম্পর্কে যুক্তিযুক্ত হওয়া অনেক কঠিন। তদুপরি সাধারণভাবে স্কেলা এবং জেভিএম সম্পর্কে কমপক্ষে প্রাথমিক বোঝাপড়াটি অবশ্যই খুব বেশি হওয়া উচিত।
2.x এবং এর বাইরেও স্পার্ক করুন
Dataset
হিমায়িত আরডিডি এপিআই সহ এপিআই-র দিকে চলমান শিফট পাইথন ব্যবহারকারীদের জন্য উভয় সুযোগ এবং চ্যালেঞ্জ এনেছে। যদিও পাইথনে API এর উচ্চ স্তরের অংশগুলি প্রকাশ করা আরও সহজ, আরও উন্নত বৈশিষ্ট্যগুলি সরাসরি ব্যবহার করা বেশ অসম্ভব ।
তবুও পাইথন ফাংশনগুলি এসকিউএল বিশ্বের দ্বিতীয় শ্রেণির নাগরিক হিসাবে অবিরত রয়েছে। আশা করি এটি ভবিষ্যতে অ্যাপাচি অ্যারো সিরিয়ালাইজেশনের মাধ্যমে উন্নতি করবে ( বর্তমান প্রচেষ্টা লক্ষ্যমাত্রার ডেটাcollection
কিন্তু ইউডিএফ সেরড দীর্ঘমেয়াদী লক্ষ্য )।
পাইথন কোডবেসের উপর দৃ depending়ভাবে নির্ভর প্রকল্পগুলির জন্য, খাঁটি পাইথন বিকল্পগুলি (ডেস্ক বা রায়ের মতো ) একটি আকর্ষণীয় বিকল্প হতে পারে।
এটি একটি বনাম অন্য হতে হবে না
স্পার্ক ডেটাফ্রেম (এসকিউএল, ডেটাসেট) এপিআই পাইসপার্ক অ্যাপ্লিকেশনটিতে স্কালা / জাভা কোডকে সংহত করার জন্য একটি মার্জিত উপায় সরবরাহ করে। আপনি DataFrames
কোনও নেটিভ জেভিএম কোডে ডেটা প্রকাশ করতে এবং ফলাফলগুলি আবার পড়তে ব্যবহার করতে পারেন । আমি অন্য কোথাও কয়েকটি বিকল্প ব্যাখ্যা করেছি এবং পাইপপার্কের ভিতরে স্ক্যালার ক্লাসটি কীভাবে ব্যবহার করতে হয় সে সম্পর্কে পাইথন-স্কালা রাউন্ডট্রিপের একটি কার্যকারী উদাহরণ খুঁজে পেতে পারেন ।
এটি ব্যবহারকারী সংজ্ঞায়িত প্রকার প্রবর্তন করে আরও বাড়ানো যেতে পারে ( স্পার্ক এসকিউএল-তে কাস্টম টাইপের জন্য স্কিমা কীভাবে সংজ্ঞায়িত করবেন? )।
প্রশ্নে প্রদত্ত কোডের সাথে কী ভুল
(অস্বীকৃতি: পাইথনিস্ট দৃষ্টিকোণ Most সম্ভবত আমি কিছু স্কাল কৌশল মিস করেছি)
প্রথমত, আপনার কোডের একটি অংশ রয়েছে যা মোটেই বোঝা যায় না। আপনার যদি ইতিমধ্যে (key, value)
জোড় ব্যবহার করে তৈরি করা থাকে zipWithIndex
বা enumerate
স্ট্রিং তৈরি করার অর্থ কী তবে এটি ঠিক পরে বিভক্ত হবে? flatMap
পুনরাবৃত্তির সাথে কাজ করে না যাতে আপনি কেবল টুপলস উত্পাদন করতে পারেন এবং যা map
কিছু অনুসরণ করে এড়িয়ে যেতে পারেন ।
আর একটি অংশ যা আমি সমস্যাযুক্ত তা পাই reduceByKey
। সাধারণভাবে বলতে গেলে, reduceByKey
কার্যকর যদি অগ্রিগেট ফাংশন প্রয়োগ করা হয় এমন ডেটার পরিমাণ হ্রাস করতে পারে যা পরিবর্তন করতে হয়। যেহেতু আপনি কেবল স্ট্রিংগুলিকে একত্রিত করেন এখানে লাভ করার কিছুই নেই। রেফারেন্সের সংখ্যার মতো নিম্ন-স্তরের জিনিসগুলি উপেক্ষা করা, আপনাকে যে পরিমাণ ডেটা ট্রান্সফার করতে হবে তা ঠিক একই রকম groupByKey
।
সাধারণত আমি এটিতে বাস করব না, তবে যতদূর আমি এটি বলতে পারি এটি আপনার স্কাল কোডের একটি বাধা। জেভিএম-এ স্ট্রিংগুলিতে যোগদান করা বরং একটি ব্যয়বহুল অপারেশন (উদাহরণস্বরূপ: স্ক্যালায় স্ট্রিং কংক্রিটেশন যেমন জাভা তেমন ব্যয়বহুল? ) এর অর্থ এই যে এরকম কিছু _.reduceByKey((v1: String, v2: String) => v1 + ',' + v2)
যা input4.reduceByKey(valsConcat)
আপনার কোডের সমান, এটি ভাল ধারণা নয়।
আপনি এড়াতে চান তাহলে groupByKey
আপনি ব্যবহার করার চেষ্টা করতে পারেন aggregateByKey
সঙ্গে StringBuilder
। এর অনুরূপ কিছুতে কৌশলটি করা উচিত:
rdd.aggregateByKey(new StringBuilder)(
(acc, e) => {
if(!acc.isEmpty) acc.append(",").append(e)
else acc.append(e)
},
(acc1, acc2) => {
if(acc1.isEmpty | acc2.isEmpty) acc1.addString(acc2)
else acc1.append(",").addString(acc2)
}
)
তবে আমি সন্দেহ করি যে এটি সমস্ত দোলাচলে মূল্যবান।
উপরের বিষয়টি মাথায় রেখে, আমি আপনার কোডটি নিম্নরূপ লিখেছি:
স্কেল :
val input = sc.textFile("train.csv", 6).mapPartitionsWithIndex{
(idx, iter) => if (idx == 0) iter.drop(1) else iter
}
val pairs = input.flatMap(line => line.split(",").zipWithIndex.map{
case ("true", i) => (i, "1")
case ("false", i) => (i, "0")
case p => p.swap
})
val result = pairs.groupByKey.map{
case (k, vals) => {
val valsString = vals.mkString(",")
s"$k,$valsString"
}
}
result.saveAsTextFile("scalaout")
পাইথন :
def drop_first_line(index, itr):
if index == 0:
return iter(list(itr)[1:])
else:
return itr
def separate_cols(line):
line = line.replace('true', '1').replace('false', '0')
vals = line.split(',')
for (i, x) in enumerate(vals):
yield (i, x)
input = (sc
.textFile('train.csv', minPartitions=6)
.mapPartitionsWithIndex(drop_first_line))
pairs = input.flatMap(separate_cols)
result = (pairs
.groupByKey()
.map(lambda kv: "{0},{1}".format(kv[0], ",".join(kv[1]))))
result.saveAsTextFile("pythonout")
ফলাফল
ইন local[6]
মোড (ইন্টেল (রাঃ) জিওন (রাঃ) CPU- র E3-1245 থেকে V2 @ 3.40GHz) 4GB মেমরি প্রতি নির্বাহক এটা লাগে (ঢ = 3) ঃ
- স্কেলা - গড়: 250.00 সে, স্টেডিভি: 12.49
- পাইথন - গড়: 246.66 এস, স্টেডিভ: 1.15
আমি নিশ্চিত যে বেশিরভাগ সময় বদলানো, সিরিয়ালাইজেশন, ডিসরিয়ালাইজেশন এবং অন্যান্য গৌণ কার্যগুলিতে ব্যয় হয়। কেবল মজাদার জন্য, পাইথনে এই নিষ্পাপ একক থ্রেডযুক্ত কোড যা এই মেশিনে এক মিনিটেরও কম সময়ে একই কার্য সম্পাদন করে:
def go():
with open("train.csv") as fr:
lines = [
line.replace('true', '1').replace('false', '0').split(",")
for line in fr]
return zip(*lines[1:])