মেসেজ কিউ (Message Queues)
মেসেজ কিউ (Message Queues) কেন ব্যবহার করা হয়?
কল্পনা করুন আপনি বিয়েবাড়িতে বা বড় কোনো খাবারের হোটেলে আছেন। আপনি যখন খাবার অর্ডার দেন, ওয়েটার কিন্তু চুলার সামনে দাঁড়িয়ে আপনার খাবার তৈরি হওয়ার জন্য অপেক্ষা করেন না। তারা আপনার অর্ডারটি একটি টিকিটে লিখে লাইনে দাঁড় করিয়ে দেন। এরপর বাবুর্চি বা কুকরা ক্রমানুসারে টিকিটগুলো স্ক্যান করে এবং অর্ডারগুলো তৈরি করতে থাকেন। আর এদিকে ওয়েটার আবার নতুন কোনো গ্রাহকের অর্ডার নিতে ফিরে যেতে পারেন।
সেই টিকিটের লাইনটিই হলো একটি মেসেজ কিউ (message queue)। এটি সেন্ডার (ওয়েটার) এবং রিসিভারকে (বাবুর্চি) আলাদা করে বা ডিকাপল (decouple) করে দেয় যাতে তারা উভয়েই নিজের মতো করে কাজ চালিয়ে যেতে পারেন।
সফটওয়্যারের ভাষায় মেসেজ কিউ মূলত বিভিন্ন সার্ভিসগুলোর মাঝখানে কাজ করে। সার্ভিস A সরাসরি সার্ভিস B কে কল করে কোনো রেসপন্সের জন্য অপেক্ষা করার পরিবর্তে, সার্ভিস A একটি মেসেজ ড্রপ করে কিউতে দিয়ে দেয় এবং অন্য কাজে চলে যায়। এরপর যখন সার্ভিস B ফ্রি হয়, তখন সে ওই মেসেজটি পিক করে নেয়।
এই প্যাটার্নটি তিনটি গুরুত্বপূর্ণ সমস্যার সমাধান করে:
- ডিকাপলিং (Decoupling) — সার্ভিসগুলোকে একে অপরের সম্পর্কে বিস্তারিত জানার কোনো দরকার নেই। সার্ভিস A শুধু একটি মেসেজ পাঠায়; এই মেসেজটি কে প্রসেস করবে সেটি জানার তার কোনো দরকার নেই।
- বাফারিং (Buffering) — যদি হঠাৎ ট্র্যাফিক বেড়ে যায়, তবে কিউ সেই চাপ সামলে নিতে পারে। কনজিউমাররা বাফারিংয়ের কোনো সমস্যা ছাড়াই নিজেদের মতো করে ডেটা প্রসেস করতে পারে।
- নির্ভরযোগ্যতা (Reliability) — যদি সার্ভিস B ক্র্যাশ করে, তবে মেসেজগুলো নিরাপদে কিউতে স্টোর হয়ে থাকে। কোনো ডেটাই হারায় না।
মেসেজিং প্যাটার্নসমূহ
পয়েন্ট-টু-পয়েন্ট (Queue)
একজন প্রডিউসার (producer) একটি মেসেজ পাঠায় এবং ঠিক একজন কনজিউমার (consumer) সেটি গ্রহণ করে। এটিকে আপনি টাস্ক কিউ এর মতো ভাবতে পারেন — একবার একজন কর্মী একটি টাস্ক গ্রহণ করলে, অন্য কোনো কর্মী সেটি আর পায় না। জব প্রসেসিং (job processing), অর্ডার হ্যান্ডলিং বা যেকোনো কাজের ক্ষেত্রে এটি দুর্দান্ত, যেখানে কাজটি ঠিক একবারই করা উচিত।
পাবলিশ/সাবস্ক্রাইব (Pub/Sub)
একজন প্রডিউসার একটি মেসেজ টপিক (topic) বা ক্যাটাগরিতে পাবলিশ করে এবং সকল সাবস্ক্রাইবার তার একটি করে কপি পায়। এটি রেডিও সম্প্রচারের মতো — চ্যানেলে টিউন করা সবাই মেসেজটি শুনতে পায়। ইভেন্ট নোটিফিকেশন, রিয়েল-টাইম আপডেট বা ফ্যান-আউট প্রসেসিংয়ের জন্য এটি দুর্দান্ত।
উদাহরণস্বরূপ, যখন কোনো ব্যবহারকারী একটি ছবি আপলোড করেন:
- ইমেজ সার্ভিস একটি টপিকে "photo-uploaded" নামের একটি ইভেন্ট পাবলিশ করে
- থাম্বনেইল (thumbnail) সার্ভিসটি এটি সাবস্ক্রাইব করে এবং ছবির থাম্বনেইল জেনারেট করে
- নোটিফিকেশন সার্ভিস সাবস্ক্রাইব করে এবং ব্যবহারকারীর ফলোয়ারদের অ্যালার্ট করে
- অ্যানালিটিক্স সার্ভিস এই ইভেন্টটি সাবস্ক্রাইব করে এবং লগ স্টোর করে রাখে
প্রতিটি সার্ভিস স্বাধীনভাবে কাজ করে। নতুন কোনো সাবস্ক্রাইবার যুক্ত করতে চাইলে (যেমন কোনো মডারেশন সার্ভিস) পাবলিশার অংশে কোনো পরিবর্তন করার প্রয়োজন পড়ে না।
একটি সাধারণ কিউ সহ Producer/Consumer প্যাটার্ন
জনপ্রিয় মেসেজ ব্রোকারসমূহ
Apache Kafka — একটি ডিস্ট্রিবিউটেড স্ট্রিমিং প্ল্যাটফর্ম যা হাই থ্রুপুট বা উচ্চ ক্ষমতা সরবরাহের জন্য তৈরি। মেসেজগুলো লগ (log) আকারে সংরক্ষিত হয় এবং এগুলো টপিক এবং পার্টিশনে বিভক্ত থাকে। কনজিউমাররা তাদের পজিশন (offset) ট্র্যাক করে রাখে এবং মেসেজগুলো পরে পুনরায় প্লে করতে পারে। এটি প্রতি সেকেন্ডে লক্ষ লক্ষ মেসেজ পরিচালনা করতে পারে এবং দিন বা সপ্তাহ ধরে ডেটা ধরে রাখতে পারে। মূলত বা উপযুক্ত ব্যবহার: ইভেন্ট স্ট্রিমিং, লগ এগ্রিগেশন, রিয়েল-টাইম অ্যানালিটিক্স।
RabbitMQ — একটি সাধারণ মেসেজ ব্রোকার যা যেকোনো জটিল রাউটিংয়ে অসাধারণ কাজ করে। এটি ডিরেক্ট, টপিক, ফ্যান-আউট, এবং হেডার্স এক্সচেঞ্জ ইত্যাদির মতো মাল্টিপল মেসেজিং প্যাটার্ন সমর্থন করে। কনজিউম করার পরে মেসেজগুলো মুছে ফেলা হয়। উপযুক্ত ব্যবহার: টাস্ক কিউ, রিকোয়েস্ট-রিপ্লাই প্যাটার্ন, জটিল রাউটিং লজিক।
Amazon SQS — এটি AWS থেকে সম্পূর্ণ নিয়ন্ত্রিত একটি কিউ পরিষেবা। এতে কোনো ইনফ্রাস্ট্রাকচার বা পরিকাঠামো পরিচালনা করার প্রয়োজন নেই। মূলত ২ ধরণের SQS রয়েছে: Standard (বেস্ট-এফর্ট অর্ডারিং, অন্তত একবার ডেলিভারি) এবং FIFO (স্ট্রিক্ট অর্ডারিং, যথাযথ একবার প্রসেসিং)। উপযুক্ত ব্যবহার: সহজ ক্লাউড ওয়ার্কলোড বা কাজ, সার্ভারলেস আর্কিটেকচার, এমন টিম যে ইনফ্রাস্ট্রাকচার মেইন্টেইন করতে চায় না।
সংক্ষিপ্ত তুলনা:
- Throughput (থ্রুপুট): Kafka >> RabbitMQ > SQS
- Message replay (মেসেজ রিপ্লে): Kafka (হ্যাঁ) এবং RabbitMQ/SQS (না, কনজিউম করার পর মুছে ফেলা হয়)
- Complexity (জটিলতা): Kafka (খুব বেশি) বনাম RabbitMQ (মাঝারি) বনাম SQS (খুব কম)
- Managed option (নিয়ন্ত্রিত বিকল্প): SQS (সম্পূর্ণ), Kafka (Confluent Cloud, AWS MSK), RabbitMQ (Amazon MQ)
ডেলিভারি গ্যারান্টি (Delivery Guarantees)
একজন কনজিউমার (consumer) প্রতিটি মেসেজ কতবার গ্রহণ করে? ডিস্ট্রিবিউটেড সিস্টেমের অন্যতম কঠিন সমস্যা এটি।
সর্বোচ্চ একবার (At-most-once): মেসেজটি শূন্য বা একবার ডেলিভারি করা হয়। যদি কিছু ভুল হয়ে যায় তবে মেসেজটি হারিয়ে যায়। এটি দ্রুত কিন্তু অনির্ভরযোগ্য। একটি পোস্টকার্ড পাঠানোর মতো — এটি পৌঁছাতেও পারে নাও পারে। আপনি কখনও তা জানতে পারবেন না।
অন্তত একবার (At-least-once): মেসেজটি এক বা একাধিকবার ডেলিভারি করা হয়। কনজিউমার স্বীকার করার আগেই ক্র্যাশ করলে মেসেজটি পুনরায় ডেলিভারি করা হয়। আপনি এটি দুবার প্রসেস করতে পারেন, তাই আপনার কনজিউমারকে অবশ্যই ইডম্পোটেন্ট (idempotent) হতে হবে (একই মেসেজ দুবার প্রসেস করলে এবং একবার পড়লে এর ফলাফল একই হবে)। এটি সবচেয়ে প্রচলিত ডেলিভারি গ্যারান্টি।
যথাযথ একবার (Exactly-once): এর সবচেয়ে বড় চ্যালেঞ্জ হলো প্রতিটি মেসেজ কেবল ঠিক একবারই ডেলিভারি করা হয়। ডিস্ট্রিবিউটেড সিস্টেমগুলোতে এটি করা বেশ কঠিন। এটি অর্জনের জন্য ইডম্পোটেন্ট প্রডিউসার এবং ট্রানজাকশনাল কনজিউমার ব্যবহার করা হয়। Kafka তে এই বৈশিষ্ট্য আছে, তবে এটি সিস্টেমে পারফরম্যান্সে কিছুটা প্রভাব ফেলে।
বাস্তবে, অধিকাংশ সিস্টেম idempotent consumers-দের সাথে at-least-once ডেলিভারি ব্যবহার করে। উদাহরণস্বরূপ, একটি পেমেন্ট প্রসেস করার সময় কার্ড থেকে পুনরায় চার্জ কাটার আগে চেক করুন পেমেন্ট আইডিটি ইতোমধ্যে রিড করা হয়েছে কিনা।
ডেড লেটার কিউ (Dead Letter Queues)
মেসেজগুলো প্রসেস হতে ব্যর্থ হলে কী হয়? ডেটা হয়তো বিকৃত বা ত্রুটিপূর্ণ হতে পারে, অথবা কোনো ডিপেন্ডেন্সি হয়তো সাময়িক সময়ের জন্য স্থগিত বা ডাউন হয়ে গেছে। আপনি যদি বারবার পুনরায় চেষ্টা করতে থাকেন, তবে খারাপ মেসেজগুলো পুরো কিউ আটকে বা ব্লক করে দিতে পারে — আর এটাই হলো একটি পয়জন পিল (poison pill)।
এর সমাধান: একটি ডেড লেটার কিউ (Dead Letter Queue, DLQ)। একটি মেসেজ N বার (যেমন, ৩টি চেষ্টা) ফেইল করার পর, এটি পরীক্ষা করার জন্য অন্য একটি কিউ-তে সরিয়ে নেওয়া হয়। মেইন কিউ এর কাজ চলতে থাকে এবং কোনো প্রকৌশলী পরবর্তীতে ডেড লেটার কিউ টি পরীক্ষা করে এর সমস্যা সমাধানের ব্যবস্থা নিতে পারেন।
প্রোডাকশন বা লাইভ সিস্টেমের জন্য DLQ অপরিহার্য। এটি একটি মাত্র খারাপ মেসেজের জন্য পুরো সিস্টেম থামিয়ে দেওয়া থেকে রক্ষা করে।
ব্যাকপ্রেসার (Backpressure)
কনজিউমার যে গতিতে মেসেজগুলো প্রসেস করছে, প্রডিউসার যদি কনজিউমারদের চেয়ে দ্রুত মেসেজ জেনারেট করে তবে কী হবে? মেমোরির ডিস্ক ফুরিয়ে না যাওয়া পর্যন্ত কিউ এর আকার বা সাইজ বাড়তেই থাকে। এটিকে ব্যাকপ্রেসার (backpressure) সমস্যা বলা হয়।
এটি সমাধানের জন্য কিছু কৌশল বা স্ট্রাটেজি ব্যবহার করা যেতে পারে:
- মেসেজ বাতিল (Drop messages): যখন কিউ ভর্তি হয়ে যায়, তখন নতুন মেসেজ প্রত্যাখ্যান বা বাতিল করা। এটি করা সহজ কিন্তু এর ফলে ডেটা হারিয়ে যায়। ম্যাট্রিক্স বা লগের জন্য এটি ওকে হলেও, অর্ডারের জন্য একদমই ওকে না।
- প্রডিউসারকে ব্লক করে দেওয়া: মেসেজ রাখার জায়গা তৈরি না হওয়া পর্যন্ত প্রডিউসারকে অপেক্ষা করিয়ে রাখা। এতে সিস্টেম সামগ্রিকভাবে ধীরগতিতে কাজ করে এবং ক্যাসকেডিং (cascading slow downs) সমস্যা সৃষ্টি করতে পারে।
- কনজিউমারের স্টোরেজ বৃদ্ধি: যখন কিউয়ের গভীরতা বা ডেপথ (depth) একটি নির্দিষ্ট সীমা অতিক্রম করে, তখন স্বয়ংক্রিয়ভাবে আরও কনজিউমার যোগ করা। এটি সবচেয়ে প্রচলিত একটি ক্লাউড পদ্ধতি বা অপশন।
- কিউ-এর সীমা নির্ধারণ করা: কিউ-এর সর্বোচ্চ সাইজ নির্ধারণ করে একটি 'overflow policy' (যেমন ডেড লেটার, পুরানো মেসেজ ফেলে দেওয়া ইত্যাদি) ব্যবহার করা।
কিউয়ের সাইজ মনিটর বা পর্যবেক্ষণ করা অত্যন্ত গুরুত্বপূর্ণ। যদি তা ক্রমাগত বাড়তে থাকে, তবে আপনার আরও কনজিউমার বা প্রোডিউসার প্রয়োজন। কারণ, যদি কিউ বাড়তেই থাকে তবে একসময় তা সিস্টেম ক্র্যাশ করতে বাধ্য করবে যা একটি টিকিং টাইম বোমার মতো।
Key Metrics
ছোট কুইজ
পড়া চালিয়ে যান