আপনি যখন থামেন এবং দৈনন্দিন জীবন সম্পর্কে চিন্তা করেন, আপনি সহজেই সবকিছুকে একটি ইভেন্ট হিসাবে দেখতে পারেন। নিম্নলিখিত ক্রম বিবেচনা করুন:
আমরা এখানে এবং চলতে পারি, কিন্তু আমি আমার পয়েন্ট তৈরি করেছি: জীবন ঘটনাগুলির একটি ক্রম। যে সত্য দেওয়া, আপনি কিভাবে আজ একটি নতুন সফ্টওয়্যার সিস্টেম ডিজাইন করবেন? আপনি কি বিভিন্ন ফলাফল সংগ্রহ করবেন এবং কিছু নির্বিচারে সেগুলি প্রক্রিয়া করবেন বা সেগুলি প্রক্রিয়া করার জন্য দিনের শেষ পর্যন্ত অপেক্ষা করবেন? না, তুমি করবে না; আপনি প্রতিটি ইভেন্ট যত তাড়াতাড়ি ঘটবে তার উপর কাজ করতে চাই। অবশ্যই, এমন কিছু ক্ষেত্রে হতে পারে যেখানে আপনি পৃথক পরিস্থিতিতে অবিলম্বে প্রতিক্রিয়া জানাতে পারবেন না... একবারে একদিনের মূল্যের লেনদেনের ডাম্প পাওয়ার কথা ভাবুন। কিন্তু তারপরও, আপনি ডেটা পাওয়ার সাথে সাথেই কাজ করবেন, যদি আপনি চান তবে একটি বড় পরিমাণের ঘটনা।
সুতরাং, ইভেন্টগুলির সাথে কাজ করার জন্য আপনি কীভাবে একটি সফ্টওয়্যার সিস্টেম বাস্তবায়ন করবেন? উত্তর হল স্ট্রিম প্রসেসিং।
ইভেন্ট ডেটা নিয়ে কাজ করার জন্য ডি ফ্যাক্টো প্রযুক্তিতে পরিণত হওয়া, স্ট্রিম প্রসেসিং হল সফ্টওয়্যার বিকাশের একটি পদ্ধতি যা ইভেন্টগুলিকে একটি অ্যাপ্লিকেশনের প্রাথমিক ইনপুট বা আউটপুট হিসাবে দেখে। উদাহরণস্বরূপ, তথ্যের উপর কাজ করার জন্য বা সম্ভাব্য প্রতারণামূলক ক্রেডিট কার্ড ক্রয়ের প্রতিক্রিয়া জানাতে অপেক্ষা করার কোন অর্থ নেই। অন্য সময় এটি একটি মাইক্রোসার্ভিসে রেকর্ডের একটি আগত প্রবাহ পরিচালনার সাথে জড়িত হতে পারে এবং সেগুলিকে সবচেয়ে দক্ষতার সাথে প্রক্রিয়া করা আপনার আবেদনের জন্য সেরা।
ব্যবহারের ক্ষেত্রে যাই হোক না কেন, এটা বলা নিরাপদ যে একটি ইভেন্ট স্ট্রিমিং পদ্ধতি ইভেন্ট পরিচালনার জন্য সর্বোত্তম পদ্ধতি।
এই ব্লগ পোস্টে, আমরা Apache Kafka®, .NET প্রযোজক এবং ভোক্তা ক্লায়েন্ট এবং Microsoft এর টাস্ক প্যারালাল লাইব্রেরি (TPL) ব্যবহার করে একটি ইভেন্ট স্ট্রিমিং অ্যাপ্লিকেশন তৈরি করব৷ প্রথম নজরে, একসাথে কাজ করার সম্ভাব্য প্রার্থী হিসাবে আপনি স্বয়ংক্রিয়ভাবে এই তিনটিকে একসাথে রাখতে পারবেন না। অবশ্যই, কাফকা এবং .NET ক্লায়েন্টরা একটি দুর্দান্ত জুটি, কিন্তু ছবিতে TPL কোথায় ফিট করে?
প্রায়শই না, থ্রুপুট একটি মূল প্রয়োজনীয়তা এবং কাফকা এবং ডাউনস্ট্রিম প্রক্রিয়াকরণের মধ্যে প্রতিবন্ধকতার অমিলের কারণে বাধা এড়ানোর জন্য, আমরা সাধারণত যেখানেই সুযোগ আসে সেখানে প্রক্রিয়ার সমান্তরালকরণের পরামর্শ দিই।
একটি শক্তিশালী এবং দক্ষ ইভেন্ট-স্ট্রিমিং অ্যাপ্লিকেশন তৈরি করতে কীভাবে তিনটি উপাদান একসাথে কাজ করে তা দেখতে পড়ুন। সবচেয়ে ভালো দিক হল কাফকা ক্লায়েন্ট এবং টিপিএল বেশিরভাগ ভারী উত্তোলনের যত্ন নেয়; আপনাকে শুধুমাত্র আপনার ব্যবসার যুক্তিতে ফোকাস করতে হবে।
আমরা অ্যাপ্লিকেশনটিতে ডুব দেওয়ার আগে, আসুন প্রতিটি উপাদানের একটি সংক্ষিপ্ত বিবরণ দেওয়া যাক।
যদি স্ট্রিম প্রক্রিয়াকরণ ইভেন্ট স্ট্রীম পরিচালনার জন্য ডি ফ্যাক্টো স্ট্যান্ডার্ড হয়, তাহলে Apache Kafka হল ইভেন্ট স্ট্রিমিং অ্যাপ্লিকেশন তৈরির জন্য ডি ফ্যাক্টো স্ট্যান্ডার্ড। Apache Kafka হল একটি বিতরণকৃত লগ যা অত্যন্ত পরিমাপযোগ্য, স্থিতিস্থাপক, ত্রুটি-সহনশীল এবং নিরাপদ পদ্ধতিতে প্রদান করা হয়। সংক্ষেপে, কাফকা ব্রোকার (সার্ভার) এবং ক্লায়েন্ট ব্যবহার করে। দালালরা কাফকা ক্লাস্টারের ডিস্ট্রিবিউটেড স্টোরেজ লেয়ার গঠন করে, যা ডেটা সেন্টার বা ক্লাউড অঞ্চলগুলিকে বিস্তৃত করতে পারে। ক্লায়েন্টরা ব্রোকার ক্লাস্টার থেকে ইভেন্ট ডেটা পড়তে এবং লেখার ক্ষমতা প্রদান করে। কাফকা ক্লাস্টারগুলি দোষ-সহনশীল: কোনো দালাল ব্যর্থ হলে, অন্য দালালরা ক্রমাগত অপারেশন নিশ্চিত করার জন্য কাজটি গ্রহণ করবে।
আমি আগের অনুচ্ছেদে উল্লেখ করেছি যে ক্লায়েন্টরা হয় কাফকা ব্রোকার ক্লাস্টার থেকে লেখে বা পড়ে। Apache Kafka জাভা ক্লায়েন্টদের সাথে বান্ডিল, কিন্তু অন্যান্য ক্লায়েন্ট পাওয়া যায়, যথা .NET কাফকা প্রযোজক এবং ভোক্তা, যা এই ব্লগ পোস্টে অ্যাপ্লিকেশনের কেন্দ্রবিন্দুতে রয়েছে। .NET প্রযোজক এবং ভোক্তা কাফকার সাথে ইভেন্ট স্ট্রিমিং এর শক্তি .NET বিকাশকারীর কাছে নিয়ে আসে৷ .NET ক্লায়েন্ট সম্পর্কে আরও তথ্যের জন্য, ডকুমেন্টেশন দেখুন।
টাস্ক প্যারালাল লাইব্রেরি ( টিপিএল ) হল "সিস্টেম. থ্রেডিং এবং সিস্টেম. থ্রেডিং. টাস্ক নেমস্পেসগুলিতে পাবলিক টাইপ এবং API-এর একটি সেট," সমসাময়িক অ্যাপ্লিকেশন লেখার কাজকে সহজ করে তোলে। TPL নিম্নলিখিত বিশদ বিবরণগুলি পরিচালনা করার মাধ্যমে সমবায় যোগ করাকে আরও পরিচালনাযোগ্য কাজ করে তোলে:
1. কাজের বিভাজন পরিচালনা করা 2. থ্রেডপুলে থ্রেড নির্ধারণ করা 3. নিম্ন-স্তরের বিবরণ যেমন বাতিলকরণ, রাষ্ট্র পরিচালনা ইত্যাদি।
মূল কথা হল যে টিপিএল ব্যবহার করে আপনার অ্যাপ্লিকেশনের প্রক্রিয়াকরণ কর্মক্ষমতা সর্বাধিক করতে পারে এবং আপনাকে ব্যবসায়িক যুক্তিতে ফোকাস করার অনুমতি দেয়। বিশেষভাবে, আপনি TPL এর ডেটাফ্লো লাইব্রেরি উপসেট ব্যবহার করবেন।
ডেটাফ্লো লাইব্রেরি হল একটি অভিনেতা-ভিত্তিক প্রোগ্রামিং মডেল যা ইন-প্রসেস মেসেজ পাসিং এবং পাইপলাইন করার কাজগুলিকে অনুমতি দেয়। ডেটাফ্লো উপাদানগুলি TPL-এর ধরন এবং সময়সূচী পরিকাঠামোর উপর ভিত্তি করে তৈরি করে এবং C# ভাষার সাথে নির্বিঘ্নে একত্রিত করে। কাফকা থেকে পড়া সাধারণত বেশ দ্রুত, কিন্তু প্রক্রিয়াকরণ (একটি ডিবি কল বা আরপিসি কল) সাধারণত একটি বাধা। যেকোন সমান্তরাল সুযোগ আমরা ব্যবহার করতে পারি যা উচ্চতর থ্রুপুট অর্জন করবে যখন অর্ডারিং গ্যারান্টিগুলিকে ত্যাগ না করে তা বিবেচনার যোগ্য।
এই ব্লগ পোস্টে, আমরা .NET কাফকা ক্লায়েন্টদের সাথে এই ডেটাফ্লো উপাদানগুলিকে একটি স্ট্রিম প্রসেসিং অ্যাপ্লিকেশন তৈরি করতে ব্যবহার করব যা ডেটা উপলব্ধ হওয়ার সাথে সাথে প্রক্রিয়া করবে৷
আপনি যে অ্যাপ্লিকেশনটি তৈরি করতে যাচ্ছেন আমরা তাতে প্রবেশ করার আগে; টিপিএল ডেটাফ্লো লাইব্রেরি কী তৈরি করে সে সম্পর্কে আমাদের কিছু পটভূমির তথ্য দেওয়া উচিত। এখানে বিস্তারিত পদ্ধতিটি সবচেয়ে বেশি প্রযোজ্য যখন আপনার কাছে CPU এবং I/O- নিবিড় কাজ থাকে যার জন্য উচ্চ থ্রুপুট প্রয়োজন। টিপিএল ডেটাফ্লো লাইব্রেরিতে এমন ব্লক রয়েছে যা ইনকামিং ডেটা বা রেকর্ডগুলিকে বাফার এবং প্রক্রিয়া করতে পারে এবং ব্লকগুলি তিনটি বিভাগের মধ্যে একটিতে পড়ে:
উত্স ব্লক - ডেটার উত্স হিসাবে কাজ করে এবং অন্যান্য ব্লকগুলি এটি থেকে পড়তে পারে।
টার্গেট ব্লক - ডেটার রিসিভার বা একটি সিঙ্ক, যা অন্য ব্লক দ্বারা লেখা যেতে পারে।
প্রচারক ব্লক - উত্স এবং লক্ষ্য ব্লক উভয় হিসাবে আচরণ করুন।
আপনি বিভিন্ন ব্লক নিন এবং একটি রৈখিক প্রক্রিয়াকরণ পাইপলাইন বা প্রক্রিয়াকরণের আরও জটিল গ্রাফ তৈরি করতে তাদের সংযোগ করুন। নিম্নলিখিত চিত্রগুলি বিবেচনা করুন:
ডেটাফ্লো লাইব্রেরি বেশ কয়েকটি পূর্বনির্ধারিত ব্লক প্রকার সরবরাহ করে যা তিনটি বিভাগে পড়ে: বাফারিং, এক্সিকিউশন এবং গ্রুপিং। আমরা এই ব্লগ পোস্টের জন্য তৈরি করা প্রকল্পের জন্য বাফারিং এবং এক্সিকিউশন প্রকারগুলি ব্যবহার করছি৷ BufferBlock<T> হল একটি সাধারণ-উদ্দেশ্য কাঠামো যা ডেটা বাফার করে এবং প্রযোজক/ভোক্তা অ্যাপ্লিকেশনে ব্যবহারের জন্য আদর্শ। বাফারব্লক ইনকামিং ডেটা পরিচালনার জন্য একটি প্রথম-ইন, প্রথম-আউট সারি ব্যবহার করে।
BufferBlock (এবং যে ক্লাসগুলি এটিকে প্রসারিত করে) ডেটাফ্লো লাইব্রেরির একমাত্র ব্লক প্রকার যা সরাসরি বার্তা লেখা এবং পড়ার জন্য প্রদান করে; অন্যান্য প্রকারগুলি ব্লক থেকে বার্তা গ্রহণ বা বার্তা পাঠাতে আশা করে। এই কারণে, সোর্স ব্লক তৈরি করার সময় এবং ISourceBlock
ইন্টারফেস এবং ITargetBlock
ইন্টারফেস বাস্তবায়নকারী সিঙ্ক ব্লক বাস্তবায়ন করার সময় আমরা প্রতিনিধি হিসাবে একটি BufferBlock
ব্যবহার করেছি।
আমাদের অ্যাপ্লিকেশনে ব্যবহৃত অন্যান্য ডেটাফ্লো ব্লকের ধরনটি হল একটি ট্রান্সফর্মব্লক <টিনপুট, টআউটপুট> । ডেটাফ্লো লাইব্রেরির বেশিরভাগ ব্লকের মতো, আপনি একটি প্রতিনিধি হিসাবে কাজ করার জন্য একটি Func<TInput, TOutput>
প্রদান করে TransformBlock-এর একটি উদাহরণ তৈরি করেন যা প্রতিটি ইনপুট রেকর্ডের জন্য ট্রান্সফর্ম ব্লক কার্যকর করে।
ডেটাফ্লো ব্লকের দুটি অপরিহার্য বৈশিষ্ট্য হল যে আপনি এটির বাফার রেকর্ডের সংখ্যা এবং সমান্তরালতার স্তর নিয়ন্ত্রণ করতে পারেন।
একটি সর্বাধিক বাফার ক্ষমতা সেট করে, আপনার অ্যাপ্লিকেশনটি স্বয়ংক্রিয়ভাবে ব্যাক প্রেসার প্রয়োগ করবে যখন অ্যাপ্লিকেশনটি প্রক্রিয়াকরণ পাইপলাইনের কিছু সময়ে দীর্ঘক্ষণ অপেক্ষার সম্মুখীন হয়। এই ব্যাক চাপ তথ্য একটি অত্যধিক জমা প্রতিরোধ করা প্রয়োজন. তারপর একবার সমস্যা কমে গেলে এবং বাফারের আকার কমে গেলে, এটি আবার ডেটা ব্যবহার করবে।
একটি ব্লকের জন্য সঙ্গতি সেট করার ক্ষমতা কর্মক্ষমতার জন্য গুরুত্বপূর্ণ। যদি একটি ব্লক একটি CPU বা I/O নিবিড় কাজ করে, তাহলে থ্রুপুট বাড়ানোর জন্য কাজকে সমান্তরাল করার একটি স্বাভাবিক প্রবণতা রয়েছে। কিন্তু কনকারেন্সি যোগ করলে সমস্যা হতে পারে—প্রসেসিং অর্ডার। আপনি যদি ব্লকের টাস্কে থ্রেডিং যোগ করেন, আপনি ডেটার আউটপুট অর্ডারের গ্যারান্টি দিতে পারবেন না। কিছু ক্ষেত্রে, অর্ডার কোন ব্যাপার না, কিন্তু যখন এটি গুরুত্বপূর্ণ, এটি বিবেচনা করার জন্য একটি গুরুতর ট্রেড-অফ: কনকারেন্সি বনাম প্রসেসিং অর্ডার আউটপুট সহ উচ্চতর থ্রুপুট। ভাগ্যক্রমে, আপনাকে ডেটাফ্লো লাইব্রেরির সাথে এই ট্রেড-অফ করতে হবে না।
আপনি যখন একটি ব্লকের সমান্তরালতা একাধিক তে সেট করেন, ফ্রেমওয়ার্ক গ্যারান্টি দেয় যে এটি ইনপুট রেকর্ডের মূল ক্রম বজায় রাখবে (মনে রাখবেন যে সমান্তরালতার সাথে ক্রম বজায় রাখা কনফিগারযোগ্য, ডিফল্ট মান সত্য হওয়াতে)। ডেটার মূল ক্রম A, B, C হলে আউটপুট অর্ডার A, B, C হবে। সন্দেহজনক? আমি জানি আমি ছিলাম, তাই আমি এটি পরীক্ষা করেছি এবং আবিষ্কার করেছি যে এটি বিজ্ঞাপন হিসাবে কাজ করেছে। আমরা এই পোস্টে একটু পরে এই পরীক্ষা সম্পর্কে কথা বলব। মনে রাখবেন যে সমান্তরালতা বৃদ্ধি শুধুমাত্র রাষ্ট্রহীন ক্রিয়াকলাপগুলির সাথে করা উচিত বা রাষ্ট্রীয় ক্রিয়াকলাপগুলির সাথে করা উচিত যেগুলি সহযোগী এবং পরিবর্তনশীল , যার অর্থ ক্রম পরিবর্তন করা বা অপারেশনগুলির গ্রুপিং ফলাফলকে প্রভাবিত করবে না৷
এই মুহুর্তে, আপনি এটি কোথায় যাচ্ছে তা দেখতে পারেন। আপনার কাছে একটি কাফকা বিষয় রয়েছে যা ইভেন্টগুলিকে উপস্থাপন করে যা আপনাকে দ্রুততম উপায়ে পরিচালনা করতে হবে৷ সুতরাং আপনি একটি .NET KafkaConsumer-এর সাথে একটি সোর্স ব্লক, ব্যবসায়িক যুক্তি সম্পন্ন করার জন্য প্রসেসিং ব্লক এবং একটি .NET KafkaProducer সমন্বিত একটি সিঙ্ক ব্লকের সমন্বয়ে একটি স্ট্রিমিং অ্যাপ্লিকেশন তৈরি করতে যাচ্ছেন যাতে একটি কাফকা বিষয়ে চূড়ান্ত ফলাফল লিখতে পারেন৷ এখানে অ্যাপ্লিকেশনটির একটি উচ্চ-স্তরের দৃশ্যের একটি দৃষ্টান্ত রয়েছে:
অ্যাপ্লিকেশনের নিম্নলিখিত কাঠামো থাকবে:
BufferBlock
প্রতিনিধি মোড়ানোBufferBlock
প্রতিনিধিকে মোড়ানো
এর পরে রয়েছে অ্যাপ্লিকেশনটির সামগ্রিক প্রবাহের একটি বিবরণ এবং একটি শক্তিশালী ইভেন্ট-স্ট্রিমিং অ্যাপ্লিকেশন তৈরির জন্য কাফকা এবং ডেটাফ্লো লাইব্রেরি ব্যবহার করার বিষয়ে কিছু গুরুত্বপূর্ণ পয়েন্ট।
এখানে আমাদের পরিস্থিতি: আপনার কাছে একটি কাফকা বিষয় রয়েছে যা আপনার অনলাইন স্টোর থেকে কেনাকাটার রেকর্ড গ্রহণ করে এবং ইনকামিং ডেটা ফরম্যাট হল JSON। আপনি ক্রয়ের বিবরণে ML অনুমান প্রয়োগ করে এই ক্রয় ইভেন্টগুলি প্রক্রিয়া করতে চান৷ উপরন্তু, আপনি JSON রেকর্ডগুলিকে Protobuf ফর্ম্যাটে রূপান্তর করতে চান, কারণ এটি ডেটার জন্য কোম্পানি-ব্যাপী ফর্ম্যাট। অবশ্যই, অ্যাপ্লিকেশনের জন্য থ্রুপুট অপরিহার্য। এমএল অপারেশনগুলি সিপিইউ নিবিড়, তাই অ্যাপ্লিকেশন থ্রুপুট সর্বাধিক করার জন্য আপনার একটি উপায় প্রয়োজন, তাই আপনি অ্যাপ্লিকেশনটির সেই অংশটিকে সমান্তরাল করার সুবিধা নেবেন৷
সোর্স ব্লক দিয়ে শুরু করে স্ট্রিমিং অ্যাপ্লিকেশনের গুরুত্বপূর্ণ পয়েন্টগুলো ঘুরে দেখি। আমি আগে ISourceBlock
ইন্টারফেস বাস্তবায়নের কথা উল্লেখ করেছি, এবং যেহেতু BufferBlock
এছাড়াও ISourceBlock
প্রয়োগ করে, আমরা এটিকে সমস্ত ইন্টারফেস পদ্ধতি সন্তুষ্ট করতে প্রতিনিধি হিসাবে ব্যবহার করব। সুতরাং উৎস ব্লক বাস্তবায়ন একটি KafkaConsumer এবং BufferBlock মোড়ানো হবে। আমাদের সোর্স ব্লকের ভিতরে, আমাদের কাছে একটি আলাদা থ্রেড থাকবে যার একমাত্র দায়িত্ব ভোক্তাদের বাফারে গ্রাস করা রেকর্ডগুলি পাস করার জন্য। সেখান থেকে, বাফারটি পাইপলাইনের পরবর্তী ব্লকে রেকর্ড ফরোয়ার্ড করবে।
বাফারে রেকর্ড ফরোয়ার্ড করার আগে, ConsumeRecord
( Consumer.consume
কল দ্বারা ফেরত) একটি Record
বিমূর্ততা দ্বারা মোড়ানো হয় যা, কী এবং মান ছাড়াও, মূল পার্টিশন এবং অফসেট ক্যাপচার করে, যা অ্যাপ্লিকেশনের জন্য গুরুত্বপূর্ণ—এবং আমি শীঘ্রই ব্যাখ্যা করব কেন. পুরো পাইপলাইনটি Record
বিমূর্ততার সাথে কাজ করে তা লক্ষ্য করার মতো, তাই যেকোন রূপান্তরের ফলে একটি নতুন Record
অবজেক্ট কী, মান এবং অন্যান্য প্রয়োজনীয় ক্ষেত্রগুলিকে মোড়ানো হয় যেমন মূল অফসেট পুরো পাইপলাইনের মাধ্যমে সংরক্ষণ করে।
অ্যাপ্লিকেশনটি প্রক্রিয়াকরণকে বিভিন্ন ব্লকে বিভক্ত করে। প্রতিটি ব্লক প্রসেসিং চেইনের পরবর্তী ধাপে লিঙ্ক করে, তাই সোর্স ব্লক প্রথম ব্লকের সাথে লিঙ্ক করে, যা ডিসিরিয়ালাইজেশন পরিচালনা করে। যদিও .NET KafkaConsumer রেকর্ডের ডিসিরিয়ালাইজেশন পরিচালনা করতে পারে, আমাদের কাছে সিরিয়ালাইজড পেলোডে ভোক্তা পাস আছে এবং একটি ট্রান্সফর্ম ব্লকে ডিসিরিয়ালাইজ করা হয়েছে। ডিসিরিয়ালাইজেশন সিপিইউ নিবিড় হতে পারে, তাই এটিকে এর প্রসেসিং ব্লকে রাখা আমাদের প্রয়োজনে অপারেশনটিকে সমান্তরাল করতে দেয়।
ডিসিরিয়ালাইজেশনের পরে, রেকর্ডগুলি অন্য ট্রান্সফর্ম ব্লকে প্রবাহিত হয় যা JSON পেলোডকে প্রোটোবাফ ফর্ম্যাটে একটি ক্রয় ডেটা মডেল অবজেক্টে রূপান্তর করে। আরও আকর্ষণীয় অংশটি আসে যখন ডেটা পরবর্তী ব্লকে যায়, যা ক্রয় লেনদেন সম্পূর্ণরূপে সম্পূর্ণ করার জন্য প্রয়োজনীয় একটি CPU-নিবিড় কাজ উপস্থাপন করে। অ্যাপ্লিকেশনটি এই অংশটিকে অনুকরণ করে, এবং সরবরাহকৃত ফাংশনটি এক থেকে তিন সেকেন্ডের মধ্যে যে কোনও জায়গায় র্যান্ডম সময়ের সাথে ঘুমায়।
এই সিমুলেটেড প্রসেসিং ব্লকটি হল যেখানে আমরা ডেটাফ্লো ব্লক ফ্রেমওয়ার্কের শক্তিকে কাজে লাগাই। যখন আপনি একটি ডেটাফ্লো ব্লক ইনস্ট্যান্ট করেন, আপনি একটি প্রতিনিধি ফাঙ্ক দৃষ্টান্ত প্রদান করেন যা এটি সম্মুখীন হওয়া প্রতিটি রেকর্ডের জন্য প্রযোজ্য হয় এবং একটি ExecutionDataflowBlockOptions
উদাহরণ। আমি আগে ডেটাফ্লো ব্লকগুলি কনফিগার করার কথা উল্লেখ করেছি, কিন্তু আমরা সেগুলি আবার এখানে দ্রুত পর্যালোচনা করব। ExecutionDataflowBlockOptions
দুটি অপরিহার্য বৈশিষ্ট্য রয়েছে: সেই ব্লকের সর্বোচ্চ বাফার আকার এবং সমান্তরালকরণের সর্বোচ্চ ডিগ্রি।
যখন আমরা পাইপলাইনের সমস্ত ব্লকের জন্য বাফার সাইজ কনফিগারেশন 10,000 রেকর্ডে সেট করি, তখন আমরা আমাদের সিমুলেটেড সিপিইউ ইনটেনসিভ ব্যতীত 1-এর ডিফল্ট সমান্তরাল স্তরের সাথে লেগে থাকি, যেখানে আমরা এটি 4 এ সেট করি। মনে রাখবেন যে ডিফল্ট ডেটাফ্লো বাফার আকার সীমাহীন আমরা পরবর্তী বিভাগে পারফরম্যান্সের প্রভাব নিয়ে আলোচনা করব, কিন্তু আপাতত, আমরা অ্যাপ্লিকেশন ওভারভিউ সম্পূর্ণ করব।
নিবিড় প্রক্রিয়াকরণ ব্লক একটি সিরিয়ালাইজিং ট্রান্সফর্ম ব্লকের দিকে এগিয়ে যায় যা সিঙ্ক ব্লককে ফিড করে, যা পরে একটি .NET কাফকা প্রযোজককে মোড়ানো হয় এবং একটি কাফকা বিষয়ের চূড়ান্ত ফলাফল তৈরি করে। সিঙ্ক ব্লকটি একটি প্রতিনিধি BufferBlock
এবং উত্পাদনের জন্য একটি পৃথক থ্রেড ব্যবহার করে। থ্রেডটি বাফার থেকে পরবর্তী উপলব্ধ রেকর্ড পুনরুদ্ধার করে। তারপরে এটি DeliveryReport
মোড়ানো Action
প্রতিনিধির মাধ্যমে KafkaProducer.Produce
প্রোডাকশন পদ্ধতিকে বলে—প্রযোজক I/O থ্রেড প্রোডাক্ট রিকোয়েস্ট সম্পূর্ণ হলে Action
ডেলিগেটকে এক্সিকিউট করবে।
এটি অ্যাপ্লিকেশনটির উচ্চ-স্তরের ওয়াকথ্রু সম্পূর্ণ করে। এখন, আমাদের সেটআপের একটি গুরুত্বপূর্ণ অংশ নিয়ে আলোচনা করা যাক—কীভাবে কমিট অফসেটগুলি পরিচালনা করা যায়—যা অত্যাবশ্যক এই কারণে যে আমরা ভোক্তাদের কাছ থেকে রেকর্ড পাইপলাইন করছি।
কাফকার সাথে ডেটা প্রক্রিয়া করার সময়, আপনি নির্দিষ্ট সময়ে আপনার অ্যাপ্লিকেশনটি সফলভাবে প্রসেস করা রেকর্ডগুলির অফসেট (একটি কাফকা বিষয়ে একটি রেকর্ডের যৌক্তিক অবস্থান) কমিট করবেন। তাহলে কেন একজন অফসেট কমিট করে? এটি একটি সহজ প্রশ্নের উত্তর: যখন আপনার ভোক্তা নিয়ন্ত্রিত পদ্ধতিতে বা ত্রুটির কারণে বন্ধ হয়ে যায়, তখন এটি শেষ পরিচিত প্রতিশ্রুতিবদ্ধ অফসেট থেকে প্রক্রিয়াকরণ পুনরায় শুরু করবে। পর্যায়ক্রমে অফসেটগুলি কমিট করার মাধ্যমে, আপনার ভোক্তা রেকর্ডগুলি পুনঃপ্রসেস করবেন না বা কমপক্ষে একটি ন্যূনতম পরিমাণে আপনার অ্যাপ্লিকেশনটি কয়েকটি রেকর্ড প্রক্রিয়া করার পরে কিন্তু কমিট করার আগে বন্ধ হওয়া উচিত। এই পদ্ধতিটি অন্তত একবার প্রক্রিয়াকরণ হিসাবে পরিচিত, যা গ্যারান্টি দেয় যে রেকর্ডগুলি অন্তত একবার প্রক্রিয়াকরণ করা হবে এবং ত্রুটির ক্ষেত্রে, তাদের মধ্যে কিছু পুনঃপ্রক্রিয়া করা যেতে পারে, তবে এটি একটি দুর্দান্ত বিকল্প যখন বিকল্পটি ডেটা ক্ষতির ঝুঁকি থাকে। কাফকা ঠিক-একবার প্রক্রিয়াকরণের গ্যারান্টিও প্রদান করে, এবং আমরা এই ব্লগ পোস্টে লেনদেন করতে পারব না, আপনি কাফকার লেনদেন সম্পর্কে আরও পড়তে পারেন
অফসেট কমিট করার বিভিন্ন উপায় থাকলেও, সবচেয়ে সহজ এবং সবচেয়ে মৌলিক হল স্বয়ংক্রিয়-কমিট পদ্ধতি। ভোক্তা রেকর্ড পড়ে, এবং অ্যাপ্লিকেশন তাদের প্রক্রিয়া করে। কনফিগারযোগ্য পরিমাণ সময় অতিবাহিত হওয়ার পরে (রেকর্ড টাইমস্ট্যাম্পের উপর ভিত্তি করে), ভোক্তা ইতিমধ্যেই গ্রাস করা রেকর্ডগুলির অফসেটগুলিকে প্রতিশ্রুতিবদ্ধ করবে। সাধারণত, স্বয়ংক্রিয় প্রতিশ্রুতি একটি যুক্তিসঙ্গত পদ্ধতি; একটি সাধারণ কনজিউম-প্রসেস লুপে, আপনি ভোক্তার কাছে ফিরে আসবেন না যতক্ষণ না আপনি পূর্বে ব্যবহার করা সমস্ত রেকর্ড(গুলি) সফলভাবে প্রক্রিয়া না করেন। যদি কোনও অপ্রত্যাশিত ত্রুটি বা শাটডাউন হয়ে থাকে, কোডটি কখনই ভোক্তার কাছে ফিরে আসে না, তাই কোনও প্রতিশ্রুতি ঘটে না। কিন্তু এখানে আমাদের অ্যাপ্লিকেশনে, আমরা পাইপলাইন করছি—আমরা গ্রাসকৃত রেকর্ডগুলি নিয়েছি এবং সেগুলিকে একটি বাফারে ঠেলে দিয়েছি এবং আরও বেশি ব্যবহার করতে ফিরে এসেছেন-সফল প্রক্রিয়াকরণের জন্য কোনও অপেক্ষা নেই৷
পাইপলাইনিং পদ্ধতির সাথে, আমরা কীভাবে অন্তত-একবার প্রক্রিয়াকরণের গ্যারান্টি দেব? আমরা IConsumer.StoreOffset
পদ্ধতিটি ব্যবহার করব , যা একটি একক প্যারামিটার-একটি TopicPartitionOffset
কে কাজ করে এবং পরবর্তী প্রতিশ্রুতির জন্য এটি (অন্যান্য অফসেটের সাথে) সংরক্ষণ করে। নোট করুন যে অফসেট ম্যানেজমেন্টের এই পদ্ধতিটি জাভা API-এর সাথে স্বয়ংক্রিয়-প্রতিশ্রুতি কীভাবে কাজ করে তা বৈপরীত্য করে।
তাই কমিট পদ্ধতিটি এইভাবে কাজ করে: যখন সিঙ্ক ব্লক কাফকার কাছে উৎপাদনের জন্য একটি রেকর্ড পুনরুদ্ধার করে, এটি অ্যাকশন প্রতিনিধিকেও প্রদান করে। যখন প্রযোজক কলব্যাকটি চালায়, তখন এটি ভোক্তার কাছে আসল অফসেটটি পাস করে (উৎস ব্লকে একই উদাহরণ), এবং ভোক্তা স্টোরঅফসেট পদ্ধতি ব্যবহার করে। আপনি এখনও ভোক্তাদের জন্য স্বয়ংক্রিয়-কমিট সক্ষম করেছেন, কিন্তু আপনি কমিট করার জন্য অফসেটগুলি প্রদান করছেন বনাম ভোক্তাকে অন্ধভাবে এই বিন্দু পর্যন্ত ব্যবহার করা সর্বশেষ অফসেটগুলিকে প্রতিশ্রুতিবদ্ধ করে৷
সুতরাং যদিও অ্যাপ্লিকেশনটি পাইপলাইনিং ব্যবহার করে, এটি ব্রোকারের কাছ থেকে একটি অ্যাক পাওয়ার পরেই কমিট করে, যার অর্থ ব্রোকার এবং নূন্যতম সেট রেপ্লিকা ব্রোকার রেকর্ডটি সংরক্ষণ করেছে। এইভাবে কাজ করা অ্যাপ্লিকেশনটিকে দ্রুত অগ্রগতির অনুমতি দেয় কারণ ব্লকগুলি তাদের কাজ করার সময় গ্রাহক ক্রমাগত পাইপলাইন আনতে এবং ফিড করতে পারে। এই পদ্ধতিটি সম্ভব কারণ .NET ভোক্তা ক্লায়েন্ট থ্রেড-নিরাপদ (কিছু পদ্ধতি এমন নয় এবং নথিভুক্ত করা হয়), তাই আমরা আমাদের একক ভোক্তাকে নিরাপদে উত্স এবং সিঙ্ক ব্লক থ্রেড উভয় ক্ষেত্রেই কাজ করতে পারি।
উত্পাদন পর্যায়ে যেকোন ত্রুটির জন্য, অ্যাপ্লিকেশন ত্রুটিটি লগ করে এবং রেকর্ডটিকে নেস্টেড BufferBlock
মধ্যে ফিরিয়ে দেয় যাতে প্রযোজক দালালের কাছে রেকর্ডটি পাঠানোর পুনরায় চেষ্টা করবে। কিন্তু এই পুনরায় চেষ্টা করার যুক্তি অন্ধভাবে করা হয়, এবং বাস্তবে, আপনি সম্ভবত একটি আরও শক্তিশালী সমাধান চাইবেন।
এখন যেহেতু আমরা অ্যাপ্লিকেশনটি কীভাবে কাজ করে তা কভার করেছি, আসুন পারফরম্যান্স নম্বরগুলি দেখি। সমস্ত পরীক্ষা স্থানীয়ভাবে একটি macOS Big Sur (11.6) ল্যাপটপে সম্পাদিত হয়েছিল, তাই এই পরিস্থিতিতে আপনার মাইলেজ পরিবর্তিত হতে পারে। কর্মক্ষমতা পরীক্ষা সেটআপ সহজবোধ্য:
JSON ফর্ম্যাটে কাফকা বিষয়ে 1M রেকর্ড তৈরি করুন। এই পদক্ষেপটি সময়ের আগে করা হয়েছিল এবং পরীক্ষার পরিমাপে অন্তর্ভুক্ত করা হয়নি।
কাফকা ডেটাফ্লো-সক্ষম অ্যাপ্লিকেশন শুরু করুন এবং সমস্ত ব্লক জুড়ে সমান্তরালকরণ সেট করুন 1 (ডিফল্ট)
1M রেকর্ড সফলভাবে প্রক্রিয়া না করা পর্যন্ত অ্যাপ্লিকেশনটি চলে, তারপর এটি বন্ধ হয়ে যায়
সমস্ত রেকর্ড প্রক্রিয়া করতে সময় রেকর্ড করুন
দ্বিতীয় রাউন্ডের জন্য একমাত্র পার্থক্য হল সিমুলেটেড CPU-নিবিড় ব্লকের জন্য MaxDegreeOfParallelism কে চারটিতে সেট করা।
এখানে ফলাফল আছে:
রেকর্ডের সংখ্যা | কনকারেন্সি ফ্যাক্টর | সময় (মিনিট) |
---|---|---|
1 মি | 1 | 38 |
1 মি | 4 | 9 |
তাই কেবল একটি কনফিগারেশন সেট করার মাধ্যমে, আমরা ইভেন্ট অর্ডার বজায় রেখে থ্রুপুট উল্লেখযোগ্যভাবে উন্নত করেছি। সুতরাং চারের সমান্তরালতার সর্বাধিক ডিগ্রি সক্ষম করার মাধ্যমে, আমরা চারের বেশি একটি ফ্যাক্টর দ্বারা প্রত্যাশিত গতি-আপ পাই। কিন্তু এই পারফরম্যান্সের উন্নতির গুরুত্বপূর্ণ অংশ হল আপনি কোনো সমসাময়িক কোড লেখেননি, যা সঠিকভাবে করা কঠিন হবে।
এর আগে ব্লগ পোস্টে, আমি ডেটাফ্লো ব্লকের সাথে একযোগে ইভেন্ট অর্ডার সংরক্ষণ করে তা যাচাই করার জন্য একটি পরীক্ষা উল্লেখ করেছি, তাই এখন এটি সম্পর্কে কথা বলা যাক। বিচারে নিম্নলিখিত পদক্ষেপগুলি জড়িত ছিল:
একটি কাফকা বিষয়ে 1M পূর্ণসংখ্যা (0-999,999) তৈরি করুন
পূর্ণসংখ্যার প্রকারের সাথে কাজ করার জন্য রেফারেন্স অ্যাপ্লিকেশনটি পরিবর্তন করুন
সিমুলেটেড রিমোট প্রসেস ব্লকের জন্য একটি সমগতি স্তরের সাথে অ্যাপ্লিকেশনটি চালান—একটি কাফকা বিষয়ের জন্য তৈরি করুন
চারটির সমগতি স্তরের সাথে অ্যাপ্লিকেশনটি পুনরায় চালান এবং অন্য কাফকা বিষয়ে সংখ্যা তৈরি করুন
উভয় ফলাফলের বিষয় থেকে পূর্ণসংখ্যা গ্রহণ করার জন্য একটি প্রোগ্রাম চালান এবং সেগুলিকে মেমরিতে একটি অ্যারেতে সংরক্ষণ করুন
উভয় অ্যারে তুলনা করুন এবং নিশ্চিত করুন যে তারা অভিন্ন ক্রমে রয়েছে
এই পরীক্ষার ফলাফল ছিল যে উভয় অ্যারেতে 0 থেকে 999,999 পর্যন্ত পূর্ণসংখ্যা রয়েছে, প্রমাণ করে যে একাধিক সমান্তরালতার স্তর সহ একটি ডেটাফ্লো ব্লক ব্যবহার করে আগত ডেটার প্রক্রিয়াকরণের ক্রম বজায় রাখে। আপনি ডকুমেন্টেশনে ডেটাফ্লো সমান্তরাল সম্পর্কে আরও বিস্তারিত তথ্য পেতে পারেন।
আমি এই পোস্টে, আমরা একটি শক্তিশালী, উচ্চ-থ্রুপুট ইভেন্ট স্ট্রিমিং অ্যাপ্লিকেশন তৈরি করতে .NET কাফকা ক্লায়েন্ট এবং টাস্ক প্যারালাল লাইব্রেরি কীভাবে ব্যবহার করতে হয় তা উপস্থাপন করেছি। কাফকা উচ্চ-পারফরম্যান্স ইভেন্ট স্ট্রিমিং প্রদান করে, এবং টাস্ক প্যারালাল লাইব্রেরি আপনাকে সমস্ত বিবরণ পরিচালনা করার জন্য বাফারিং সহ সমসাময়িক অ্যাপ্লিকেশন তৈরি করার জন্য বিল্ডিং ব্লক দেয়, যা বিকাশকারীদের ব্যবসায়িক যুক্তিতে ফোকাস করতে দেয়। যদিও অ্যাপ্লিকেশনটির জন্য দৃশ্যকল্পটি কিছুটা বিকৃত, আশা করি, আপনি দুটি প্রযুক্তির সমন্বয়ের উপযোগিতা দেখতে পাবেন। একবার চেষ্টা করে দেখো-
এছাড়াও এখানে প্রকাশিত.