KoderKoder.ai
প্রাইসিংএন্টারপ্রাইজএডুকেশনবিনিয়োগকারীদের জন্য
লগ ইনশুরু করুন

প্রোডাক্ট

প্রাইসিংএন্টারপ্রাইজবিনিয়োগকারীদের জন্য

রিসোর্স

আমাদের সাথে যোগাযোগ করুনসহায়তাএডুকেশনব্লগ

লিগ্যাল

প্রাইভেসি পলিসিটার্মস অফ ইউজসিকিউরিটিঅ্যাকসেপ্টেবল ইউজ পলিসিঅ্যাবিউজ রিপোর্ট করুন

সোশ্যাল

LinkedInTwitter
Koder.ai
ভাষা

© 2026 Koder.ai. সর্বস্বত্ব সংরক্ষিত।

হোম›ব্লগ›Kafka ইভেন্ট স্ট্রিমিং: কখন একটি কিউ কাজ করে এবং কখন একটি লগ জিতবে
১১ অক্টো, ২০২৫·7 মিনিট

Kafka ইভেন্ট স্ট্রিমিং: কখন একটি কিউ কাজ করে এবং কখন একটি লগ জিতবে

Kafka ইভেন্ট স্ট্রিমিং সিস্টেম ডিজাইন বদলে দেয় ঘটনাগুলোকে একটি অর্ডার্ড লগ হিসেবে দেখে। শিখুন কখন একটি সাধারণ কিউ যথেষ্ট এবং কখন লগ ব্যবহার করা উচিত।

Kafka ইভেন্ট স্ট্রিমিং: কখন একটি কিউ কাজ করে এবং কখন একটি লগ জিতবে

কেন দলগুলো ঐতিহ্যবাহী ইন্টিগ্রেশনে বারান্দায় আটকে পড়ে\n\nঅধিকাংশ প্রোডাক্ট সহজ পয়েন্ট-টু-পয়েন্ট ইন্টিগ্রেশন দিয়ে শুরু করে: সিস্টেম A সিস্টেম B-কে কল করে, বা একটি ছোট স্ক্রিপ্ট এক জায়গা থেকে ডেটা কপি করে। সেটা কাজ করে যতক্ষণ প্রোডাক্ট ছোট থাকে, দল আলাদা হয় না, এবং সংযোগের সংখ্যা বেশি নয়। কিন্তু প্রোডাক্ট বড় হলে, দলগুলো ভাগ হলে, সংযোগ গুণতে শুরু করলে সমস্যা দেখা দেয়। দ্রুত ছোট একটি ফিল্ড বা স্ট্যাটাস আপডেট বহু সার্ভিসে তরঙ্গের মত ছড়িয়ে যেতে পারে।\n\nগতিই সাধারণত প্রথম যে জিনিস ভেঙে পড়ে। একটি নতুন ফিচার যোগ করতে হলে বহু ইন্টিগ্রেশন আপডেট করতে হয়, কয়েকটি সার্ভিস রিডিপ্লয় করতে হয়, এবং আশা করতে হয় আগের আচরণের ওপর আর কেউ নির্ভর করে নি।\n\nতারপর ডিবাগ করা কষ্টদায়ক হয়ে ওঠে। UI-তে কিছু ভুল দেখলে মৌলিক প্রশ্নগুলো করা কঠিন: কী ঘটেছে, কী ক্রমে ঘটেছে, এবং কোন সিস্টেম আপনাকে যে মানটি দেখাচ্ছে তা লিখেছে?\n\nঅনেক সময় সমস্যার মুলটুকু হলো নিরীক্ষা ট্রেইল। যদি ডেটা সরাসরি এক ডাটাবেস থেকে আরেকটায় পাঠানো হয় (বা পথে ট্রান্সফর্ম হয়ে যায়), আপনি ইতিহাস হারান। আপনি হয়ত চূড়ান্ত স্টেট দেখবেন, কিন্তু সেই স্টেটে পৌঁছানোর জন্য কি ঘটেছে তার সিকোয়েন্স আপনি পাবেন না। ইনসিডেন্ট রিভিউ ও কাস্টমার সাপোর্ট দুটোই কষ্ট পায় কারণ আপনি অতীত আবার প্লে করে নিশ্চিত করতে পারেন না কী পরিবর্তিত হয়েছে এবং কেন।\n\nএখানেই "Who owns the truth" আর্কুমেন্টটা শুরু হয়। একটি টিম বলে, “বিলিং সার্ভিসই সোর্স অফ ট্রুথ।” অন্যটি বলে, “অর্ডার সার্ভিস।” বাস্তবে প্রতিটি সিস্টেমের আংশিক ভিউ থাকে, এবং পয়েন্ট-টু-পয়েন্ট ইন্টিগ্রেশনগুলো সেই অমতকে প্রতিদিনের ঘর্ষণে পরিণত করে।\n\nএকটি সাধারণ উদাহরণ: একটি অর্ডার তৈরি হয়, তারপর পেমেন্ট হয়, তারপর রিফান্ড হয়। যদি তিনটি সিস্টেম একে অপরকে সরাসরি আপডেট করে, রিট্রাই, টাইমআউট, বা ম্যানুয়াল ফিক্সের কারণে প্রতিটির কাছে ভিন্ন গল্প থাকা স্বাভাবিক।\n\nএটাই Kafka ইভেন্ট স্ট্রিমিংয়ের নীতিগত প্রশ্ন: আপনি কি শুধু কাজ এক জায়গা থেকে আরেকটা জায়গায় সরাতে চান (একটি কিউ), নাকি এমন একটি শেয়ার্ড, টেকসই রেকর্ড চান যা বহু সিস্টেম পড়তে, রিওয়াইন্ড করতে এবং বিশ্বাস করতে পারে (একটি লগ)? এর উত্তর আপনার সিস্টেম বানানো, ডিবাগ করা এবং বিকাশের পথ বদলে দেয়।\n\n## Jay Kreps, Kafka এবং লগের ধারণা\n\nJay Kreps Kafka গঠনে সাহায্য করেছেন এবং আরও গুরুত্বপূর্ণভাবে অনেক দলের ডেটা মুভমেন্ট সম্পর্কে চিন্তাধারা বদলে দিয়েছেন। দরকারী শিফটটা হলো মানসিকতা: ম্যাসেজগুলোকে একবারের ডেলিভারি হিসেবে দেখা বন্ধ করুন, এবং সিস্টেমের কার্যকলাপকে একটি রেকর্ড হিসেবে দেখুন।\n\nমূল ধারণাটা সহজ। গুরুত্বপূর্ণ পরিবর্তনগুলোকে অপরিবর্তনীয় ফ্যাক্টস হিসেবে স্ট্রিম আকারে মডেল করুন:\n\n- একটি অর্ডার তৈরি হল।\n- একটি পেমেন্ট অথরাইজড হলো।\n- একজন ব্যবহারকারী ইমেইল বদলালেন।\n\nপ্রতিটি ইভেন্ট এমন একটি ফ্যাক্ট যা পরে এডিট হওয়া উচিত নয়। যদি পরে কিছু বদলে যায়, আপনি একটি নতুন ইভেন্ট যোগ করেন যা নতুন সত্য বলে। সময়ের সাথে সেই ফ্যাক্টগুলো একটি লগ গঠন করে: আপনার সিস্টেমের একটি অ্যাপেন্ড-ওনলি ইতিহাস।\n\nএখানেই Kafka ইভেন্ট স্ট্রিমিং অনেক বেসিক মেসেজিং সেটআপ থেকে আলাদা। অনেক কিউ "পাঠাও, প্রসেস কর, মুছে ফেল"-ভিত্তিক। যখন কাজ শুধু হ্যান্ড-অফ, তখন তা ঠিক আছে। লগ ভিউ বলে, "ইতিহাস রাখুন যাতে বহু কনজিউমার তা এখনো এবং পরে ব্যবহার করতে পারে।"\n\nইতিহাস পুনরায় চালানো হল ব্যবহারিক সুপারপাওয়ার।\n\nযদি একটি রিপোর্ট ভুল হয়, আপনি একই ইভেন্ট ইতিহাসকে একটি ফিক্সড অ্যানালিটিক্স জবের মধ্য দিয়ে পুনরায় চালাতে পারেন এবং দেখতে পারেন কোথায় সংখ্যা বদলালো। যদি কোনো বাগ ভুল ইমেইল পাঠায়, আপনি ইভেন্টগুলো টেস্ট এনভায়রনমেন্টে রেপ্লে করে একই টাইমলাইন পুনরায় উৎপাদন করতে পারেন। যদি একটি নতুন ফিচার পুরনো ডেটা চান, আপনি একটি নতুন কনজিউমার বানিয়ে শুরু থেকেই পড়তে দিতে পারেন এবং নিজ গতিতে ক্যাচ-আপ করতে পারেন।\n\nএকটি কংক্রিট উদাহরণ: ধরুন আপনি পরে ফ্রড চেক যোগ করেন যখন ইতিমধ্যেই মাসব্যাপী পেমেন্ট প্রসেস করেছেন। পেমেন্ট ও অ্যাকাউন্ট ইভেন্টগুলোর একটি লগ থাকলে আপনি অতীতটি রেপ্লে করে বাস্তব সিকোয়েন্সের ওপর রুল ট্রেইন/ক্যালিব্রেট করতে পারেন, পুরোনো লেনদেনের জন্য রিস্ক স্কোর হিসাব করতে পারেন, এবং ডাটাবেস রিরাইট না করে "fraud_review_requested" ইভেন্ট ব্যাকফিল করতে পারেন।\n\nদেখুন এটা আপনাকে কী বাধ্য করে। লগ-বেসড পদ্ধতি আপনাকে ইভেন্টগুলোর স্পষ্ট নাম রাখতে, তাদের স্থিতিশীল রাখতে এবং একাধিক দল/সার্ভিস তাদের ওপর নির্ভর করবে এটা মেনে নিতে বাধ্য করে। এটি ব্যবহারিক প্রশ্নও জাগায়: কোনটি সোর্স অফ ট্রুথ? এই ইভেন্টের দীর্ঘমেয়াদী অর্থ কী? আমরা ভুল করলে কী করব?\n\nমূল্যটা ব্যক্তিগতত্বে নয়। এটি উপলব্ধি করা যে একটি শেয়ার্ড লগ আপনার সিস্টেমের মেমোরি হয়ে উঠতে পারে, এবং মেমোরিই এমন জিনিস যা সিস্টেমগুলোকে নতুন কনজিউমার যোগ করলেও ভেঙে ফেলতে দেয় না।\n\n## কিউ বনাম লগ: সবচেয়ে সরল মানসিক মডেল\n\nএকটি মেসেজ কিউ হলো আপনার সফটওয়্যারের জন্য একটি টু-ডু লাইন। প্রোডিউসার কাজ লাইনটিতে রাখে, কনজিউমার পরের আইটেম নেয়, কাজ করে, এবং আইটেমটাকে মুছে ফেলা হয়। সিস্টেমটি মূলত প্রতিটি টাস্ক যত দ্রুত সম্ভব হ্যান্ডেল করা নিয়ে।\n\nএকটি লগ ভিন্ন। এটি ঘটনাগুলোর একটি অর্ডার্ড রেকর্ড যা টেকসইভাবে সংরক্ষিত থাকে। কনজিউমার ইভেন্টগুলো "নেই করে" না; তারা নিজ গতিতে লগ পড়ে এবং পরে আবারও পড়তে পারে। Kafka ইভেন্ট স্ট্রিমিংয়ে সেই লগই মূল ধারণা।\n\nমনে রাখার সহজ উপায়:\n\n- Queue = করার কাজ। একজন ওয়ার্কার নিশ্চিত করলে তা অদৃশ হয়।\n- Log = কী ঘটেছে তার ইতিহাস। ইভেন্টগুলো একটি রিটেনশন পিরিয়ডের জন্য থাকে।\n\nরিটেনশন ডিজাইন বদলে দেয়। কিউতে যদি পরে কোনো নতুন ফিচার পুরোনো মেসেজের ওপর নির্ভর করে (অ্যানালিটিক্স, ফ্রড চেক, বাগের পরে রেপ্লে), আপনাকে আলাদা একটি ডাটাবেস যোগ করতে হতে পারে বা অতিরিক্ত কপি ধরতে হতে পারে। লগে রেপ্লে স্বাভাবিক: আপনি শুরু থেকে (অথবা একটি জানা চেকপয়েন্ট থেকে) পড়ে একটি ডেরাইভড ভিউ পুনর্নির্মাণ করতে পারেন।\n\nফ্যান-আউটও একটি বড় পার্থক্য। ধরা যাক চেকআউট সার্ভিস "OrderPlaced" ইমিট করে। কিউতে সাধারণত আপনি একটি ওয়ার্কার গ্রুপ বেছে নেন এটি প্রসেস করার জন্য, অথবা একাধিক কিউতে কাজ ডুপ্লিকেট করে ফেলেন। লগে billing, email, inventory, search indexing, এবং analytics একই ইভেন্ট স্ট্রিম স্বাধীনভাবে পড়তে পারে। প্রতিটি টিম নিজ গতিতে কাজ করতে পারে, এবং পরে একটি নতুন কনজিউমার যোগ করতে প্রোডিউসারকে বদলাতে হয় না।\n\nসুতরাং মানসিক মডেল সরল: যখন আপনি টাস্ক সরাতে চান কিউ ব্যবহার করুন; যখন আপনি এমন ইভেন্ট রেকর্ড করতে চান যা কোম্পানির অনেক অংশ পরে বা এখনও পড়তে চায়, লগ ব্যবহার করুন।\n\n## ইভেন্ট স্ট্রিমিং সিস্টেম ডিজাইনকে কীভাবে বদले\n\nইভেন্ট স্ট্রিমিং ডিফল্ট প্রশ্নটাকে উল্টো করে দেয়। "আমি এই মেসেজটা কাকে পাঠাব?" জিজ্ঞাসা করার বদলে আপনি শুরু করেন "এখন কী ঘটেছে?" দিয়ে। এটা ছোট মনে হলেও আপনার সিস্টেম মডেল করা বদলে দেয়।\n\nআপনি OrderPlaced বা PaymentFailed-এর মতো ফ্যাক্ট পাবলিশ করেন, এবং সিস্টেমের অন্যান্য অংশই সিদ্ধান্ত নেয় তারা কীভাবে, কখন ও কিভাবে প্রতিক্রিয়া দেখাবে।\n\nKafka ইভেন্ট স্ট্রিমিংয়ে প্রোডিউসারদের কাছে সরাসরি ইন্টিগ্রেশনগুলোর তালিকা থাকতে হয় না। একটি চেকআউট সার্ভিস একটি ইভেন্ট পাবলিশ করলে সেটি জানে না analytics, email, fraud checks, বা ভবিষ্যতের recommendation সার্ভিস এটা ব্যবহার করবে কি না। নতুন কনজিউমার পরে আসতে পারে, পুরনোগুলো পজ করা যায়, এবং প্রোডিউসারের আচরণ অপরিবর্তিত থেকে যায়।\n\nএটি কিভাবে ভুল থেকে পুনরুদ্ধার করা হয় তাও বদলে দেয়। কেবল মেসেজিং দুনিয়ায়, একবার কনজিউমার কিছু মিস করলে বা বাগ করলে ডেটা প্রায়ই "চলে যায়" যদি না আপনি কাস্টম ব্যাকআপ তৈরি করে রাখেন। লগ থাকলে আপনি কোড ঠিক করে ইতিহাস রেপ্লে করে সঠিক স্টেট পুনর্নির্মাণ করতে পারেন। বেশিরভাগ সময় সেটা ম্যানুয়াল ডাটাবেস এডিট বা এক-বারের স্ক্রিপ্টের চাইতে ভালো।\n\nপ্রায়োগিকভাবে এই শিফট কিছু নির্ভরযোগ্য উপায়ে দেখা যায়: আপনি ইভেন্টগুলোকে একটি স্থায়ী রেকর্ড হিসেবে বিবেচনা করেন, ফিচার যোগ করতে সাবস্ক্রাইব করেন बजाय প্রোডিউসার পরিবর্তনের, আপনি রিড-মডেল (সার্চ ইন্ডেক্স, ড্যাশবোর্ড) শূন্য থেকে পুনর্নির্মাণ করতে পারেন, এবং সার্ভিসগুলো জুড়ে কী ঘটেছে তার স্পষ্ট টাইমলাইন পান।\n\nঅবজারভেবিলিটি উন্নত হয় কারণ ইভেন্ট লগ একটি শেয়ার্ড রেফারেন্স হিসেবে কাজ করে। যখন কিছু ভুল হয়, আপনি একটি ব্যবসায়িক সিকোয়েন্স অনুধাবন করতে পারেন: order created, inventory reserved, payment retried, shipment scheduled। সেই টাইমলাইন সাধারণত ছড়িয়ে থাকা অ্যাপ্লিকেশন লগের চেয়ে বুঝতে সহজ কারণ এটা ব্যবসায়িক ফ্যাক্টের ওপর ফোকাস করে।\n\nএকটি কংক্রিট উদাহরণ: যদি দু'ঘন্টার জন্য একটি ডিসকাউন্ট বাগ অর্ডারগুলো ভুল মূল্য নির্ধারণ করে, আপনি একটি ফিক্স পাঠান এবং প্রভাবিত ইভেন্টগুলো রেপ্লে করে টোটাল পুনর্গণনা, ইনভয়েস আপডেট এবং অ্যানালিটিক্স রিফ্রেশ করতে পারেন। আপনি আউটকামগুলো পুনরায়derive করে ঠিক করছেন, কারো টেবিল ম্যানুয়ালি প্যাচ করে অনুমান করে ঠিক করছেন না।\n\n## কখন একটি সাধারণ কিউই যথেষ্ট\n\nএকটি সাধারণ কিউ ঠিক টুল যখন আপনি কাজ সরাতে চান, ইতিহাস তৈরি করতে চান না। লক্ষ্য হলো টাস্কটি ওয়ার্কারকে হস্তান্তর করা, চালানো, এবং তারপর ভুলে যাওয়া। যদি কেউ অতীত পুনরায় চালাতে না চায়, পুরোনো ইভেন্টগুলো পরীক্ষা করতে না চায়, বা ভবিষ্যতে নতুন কনজিউমার যোগ হবে না, একটি কিউ সরল রাখে।\n\nকিউ ব্যাকগ্রাউন্ড জবের জন্য উপযুক্ত: সাইনআপ ইমেইল পাঠানো, আপলোডের পর ছবি রিসাইজ করা, নাইটলি রিপোর্ট জেনারেট করা, বা ধীর থার্ড-পার্টি API কল করা। এই পরিস্থিতিগুলোতে মেসেজটি কেবল একটি কাজের টিকিট। যখন ওয়ার্কার কাজ শেষ করে, টিকিটের কাজও সম্পন্ন।\n\nএকটি কিউ সাধারণত মালিকানার সাদৃশ্য পূরণ করে: একটি কনজিউমার গ্রুপ টাস্কটির দায় নেয়, এবং অন্য সার্ভিসগুলো একই মেসেজ স্বাধীনভাবে পড়ার আশা করে না।\n\nএকটি কিউ সাধারণত যথেষ্ট যখন নিচের অধিকাংশ সত্য:\n\n- ডেটার মূল্য স্বল্পমেয়াদী।\n- এক দল বা এক সার্ভিস কাজটি end-to-end মালিকানায় রাখে।\n- রেপ্লে ও দীর্ঘ রিটেনশন আবশ্যক নয়।\n- ডিবাগিং ইতিহাস পুনরায় চালানোর উপর নির্ভর করে না।\n\nউদাহরণ: একজন ব্যবহারকারী ছবি আপলোড করে। অ্যাপ একটি "resize image" টাস্ক কিউতে লিখে। ওয়ার্কার A তা নেয়, থাম্বনেইল তৈরি করে, স্টোর করে, এবং টাস্কটি সম্পন্ন হিসেবে চিহ্নিত করে। যদি টাস্কটি দুইবার চলে, আউটপুট একই (idempotent), তাই at-least-once ডেলিভারি ঠিক আছে। আর কোনো সার্ভিস পরে সেই টাস্কটি স্বাধীনভাবে পড়তে চায় না।\n\nআপনার প্রয়োজন যদি ধীরে ধীরে শেয়ার্ড ফ্যাক্টস, রেপ্লে, অডিট, বা "গত সপ্তাহে সিস্টেম কী বিশ্বাস করেছিল?" এর দিকে সরে যায়, তখন Kafka ইভেন্ট স্ট্রিমিং ও লগ-বেসড পদ্ধতি ব্যবহার করে সুবিধা পাওয়া শুরু হবে।\n\n## কখন লগ-বেসড পদ্ধতি উপকারী\n\nএকটি লগ-বেসড সিস্টেম তখন উপকারী যখন ইভেন্টগুলো একবারের মেসেজ না থেকে শেয়ার্ড ইতিহাস হয়ে ওঠে। "পাঠাও এবং ভুলে যাও"-এর বদলে আপনি একটি অর্ডার্ড রেকর্ড রাখেন যা বহু টিম স্বাধীনভাবে এখন বা পরে পড়তে পারে।\n\nসবচেয়ে স্পষ্ট সংকেতটি হলো বহু কনজিউমার। একটি ইভেন্ট যেমন "OrderPlaced" billing, email, fraud checks, search indexing এবং analytics—সবকিছু খাওয়াতে পারে। লগে প্রতিটি কনজিউমার একই স্ট্রীম স্বাধীনভাবে পড়ে। আপনাকে কাস্টম ফ্যান-আউট পাইপলাইন বানাতে বা কে প্রথম মেসেজ পাবে তা সমন্বয় করতে হয় না।\n\nআরেকটি সুবিধা: আপনি প্রশ্নের উত্তর দিতে পারেন, "তখন আমরা কী জানতাম?" একজন কাস্টমার চার্জ নিয়ে বিরোধ করলে বা কোনো রিকমেন্ডেশন ভুল হলে, একটি অ্যাপেন্ড-ওনলি ইতিহাস আপনাকে আসল সময়ে যে ফ্যাক্টগুলো এসেছিল সেগুলো রেপ্লে করে দেখতে দেয়। এটি একটি সাধারন কিউ-তে পরে ঝুট করে লাগানো কঠিন।\n\nআপনি নতুন ফিচার যোগ করতে পারেন পুরনোগুলো রিরাইট না করে। যদি আপনি কয়েক মাস পরে একটি নতুন "shipping status" পেজ যোগ করতে চান, একটি নতুন সার্ভিস ইতিহাস থেকে সাবস্ক্রাইব করে ব্যাকফিল করে নিজের স্টেট তৈরি করতে পারে, বরং প্রতিটি upstream সিস্টেমকে এক্সপোর্ট দিতে বলার দরকার পড়ে না।\n\nলগ-বেসড পদ্ধতি প্রায়ই লাভজনক যখন নিচের কোনগুলোর প্রয়োজন দেখা দেয়:\n\n- একই ইভেন্টকে বহু সিস্টেম (analytics, search, billing, support) খাওয়াতে হবে।\n- রেপ্লে, অডিটিং, বা অতীত ফ্যাক্টের ওপর তদন্ত প্রয়োজন।\n- নতুন সার্ভিসগুলোকে ইতিহাস থেকে ব্যাকফিল করতে হবে কোনো এক-বারের জব ছাড়াই।\n\n- নির্দিষ্ট সত্তা অনুসারে অর্ডারিং গুরুত্বপূর্ণ (প্রতি অর্ডার, প্রতি ব্যবহারকারী)।\n- ইভেন্ট ফরম্যাট বিবর্তিত হবে এবং আপনাকে ভার্সনিং কন্ট্রোল করতে হবে।\n\nএকটি সাধারণ প্যাটার্ন: প্রথমে একটি প্রোডাক্ট অর্ডার ও ইমেইল নিয়ে শুরু করে। পরে ফাইন্যান্স রেভিনিউ রিপোর্ট চায়, প্রোডাক্ট ফানেল চায়, এবং অপস লাইভ ড্যাশবোর্ড চায়। যদি প্রতিটি নতুন প্রয়োজন আপনাকে নতুন পাইপলাইন কপি করতে বাধ্য করে, খরচ দ্রুত বেড়ে যায়। একটি শেয়ার্ড ইভেন্ট লগ টিমগুলোকে একই সোর্স অফ ট্রুথে কাজ করতে দেয়, এমনকি সিস্টেম বড় হলেও ও ইভেন্টের গঠন বদলেও।\n\n## কীভাবে সিদ্ধান্ত নেবেন, ধাপে ধাপে\n\nকিউ এবং লগ-বেসড পদ্ধতির মধ্যে নির্বাচন একটি প্রোডাক্ট সিদ্ধান্তের মত করা সহজ। আজকের জন্য কাজ করছে তা না দেখে, এক বছরের পরে কী থাকা উচিত সেই দিক থেকে শুরু করুন।\n\n### একটি ব্যবহারিক ৫-ধাপ সিদ্ধান্ত\n\n1) প্রকাশক এবং পাঠক ম্যাপ করুন। লিখে রাখুন কারা ইভেন্ট তৈরি করে এবং কারা আজ পড়ে, তারপর সম্ভাব্য ভবিষ্যৎ কনজিউমার যোগ করুন (analytics, search indexing, fraud checks, customer notifications)। যদি আপনি বহু টিম একই ইভেন্ট স্বাধীনভাবে পড়বে বলে মনে করেন, লগ যুক্তির পক্ষে যায়।\n\n2) জিজ্ঞাসা করুন আপনি ইতিহাস পুনরায় পড়তে চাইবেন কি না। কেন নির্দিষ্টভাবে: বাগের পরে রেপ্লে, ব্যাকফিল, বা যা ভিন্ন গতিতে পড়ে। কিউ একবার হ্যান্ড-অফের জন্য দুর্দান্ত। লগ তখন ভালো যখন আপনি এমন একটি রেকর্ড চান যা আপনি রেপ্লে করতে পারবেন।\n\n3) নির্ধারণ করুন "ডান হওয়া" মানে কী। কিছু ওয়ার্কফ্লোরে ডান হওয়া মানে "জবটি চালানো হলো" (ইমেইল পাঠানো, ছবি রিসাইজ)। অন্যগুলোর জন্য ডান হওয়া মানে "ইভেন্টটি একটি টেকসই ফ্যাক্ট" (অর্ডার প্লেসড, পেমেন্ট অথরাইজড)। টেকসই ফ্যাক্টস আপনাকে লগের দিকে ধাক্কা দেয়।\n\n4) ডেলিভারি প্রত্যাশা বেছে নিন এবং কিভাবে ডুপ্লিকেট হ্যান্ডেল করবেন তা সিদ্ধান্ত নিন। at-least-once ডেলিভারি সাধারণ, যার মানে ডুপ্লিকেট হতে পারে। যদি ডুপ্লিকেট ক্ষতিকর (যেমন দ্বিগুণ চার্জ), তাহলে idempotency পরিকল্পনা করুন: প্রক্রিয়াকৃত ইভেন্ট ID সংরক্ষণ, ইউনিক কনস্ট্রেইন্ট ব্যবহার, বা এমনভাবে আপডেট করুন যাতে বারবার প্রয়োগ করা নিরাপদ।\n\n5) একটি পাতলা স্লাইস দিয়ে শুরু করুন। একটি ইভেন্ট স্ট্রিম বেছে নিন যা সহজে বোঝা যায় এবং সেখান থেকে বাড়ান। যদি আপনি Kafka ইভেন্ট স্ট্রিমিং বেছে নেন, প্রথম টপিকটিকে ফোকাসেড রাখুন, ইভেন্টগুলোকে স্পষ্টভাবে নাম দিন, এবং অপ্রাসঙ্গিক ইভেন্ট টাইপ মিশাবেন না।\n\nএকটি কংক্রিট উদাহরণ: যদি "OrderPlaced" পরে শিপিং, ইনভয়সিং, সাপোর্ট, এবং অ্যানালিটিক্স খাওয়াবে, একটি লগ প্রতিটি টিমকে নিজ গতিতে পড়তে এবং ভুল হলে রেপ্লে করে ক্যাচ-আপ করতে দেয়। যদি আপনি শুধুমাত্র ব্যাকগ্রাউন্ড ওয়ার্কার দিয়ে রসিদ ইমেইল পাঠাবেন, সাধারণ কিউ সাধারণত যথেষ্ট।\n\n## উদাহরণ: একটি বাড়তে থাকা প্রোডাক্টে অর্ডার ইভেন্ট\n\nএকটি ছোট অনলাইন স্টোর কল্পনা করুন। প্রথমে শুধু অর্ডার নিতে, কার্ড চার্জ দিতে, এবং শিপিং রিকোয়েস্ট তৈরি করতে হবে। সবচেয়ে সহজ ভার্সন হলো চেকআউটের পর একটি ব্যাকগ্রাউন্ড জব: "process order"। এটি পেমেন্ট API-কে কল করে, অর্ডার রো আপডেট করে, তারপর শিপিং কল করে।\n\nএই কিউ স্টাইল তখন ভালো কাজ করে যখন একটি স্পষ্ট ওয়ার্কফ্লো থাকে, একটি কনজিউমারই থাকে (ওয়ার্কার), এবং রিট্রাই ও ডেড-লেটার বেশিরভাগ ব্যর্থতা কভার করে।\n\nস্টোর বড় হলে সমস্যাটা শুরু হয়। সাপোর্ট স্বয়ংক্রিয় "অর্ডার কোথায়?" আপডেট চায়। ফাইন্যান্স ডেইলি রেভিনিউ চান। প্রোডাক্ট টিম কাস্টমার ইমেইল চায়। শিপিংয়ের আগে ফ্রড চেক করা উচিত। একটি একক "process order" জব থাকলে আপনি বারংবার সেই ওয়ার্কারটি এডিট করতে থাকেন, শাখা বাড়ান, এবং কোর ফ্লোতে নতুন বাগের ঝুঁকি নেন।\n\nলগ-বেসড পদ্ধতিতে চেকআউট ছোট ফ্যাক্টগুলো ইভেন্ট হিসেবে প্রকাশ করে, এবং প্রতিটি টিম তা ব্যবহার করে। সাধারণ ইভেন্টগুলো হতে পারে:\n\n- OrderPlaced\n- PaymentConfirmed\n- ItemShipped\n- RefundIssued\n\nমূল বদলটা হলো মালিকানা। চেকআউট সার্ভিস OrderPlaced এর মালিক। পেমেন্ট সার্ভিস PaymentConfirmed এর মালিক। শিপিং ItemShipped এর মালিক। পরে নতুন কনজিউমার আসলে প্রোডিউসার বদলাতে হয় না: একটি ফ্রড সার্ভিস OrderPlaced ও PaymentConfirmed পড়ে রিস্ক স্কোর করে, একটি ইমেইল সার্ভিস রসিদ পাঠায়, অ্যানালিটিক্স ফানেল তৈরি করে, এবং সাপোর্ট টুল টাইমলাইন রাখে।\n\nএখানেই Kafka ইভেন্ট স্ট্রিমিং সুবিধা দেয়: লগ ইতিহাস রাখে, তাই নতুন কনজিউমার শুরু থেকেই বা একটি নির্দিষ্ট পয়েন্ট থেকে রিওয়াইন্ড করে নিজের অবস্থান তৈরি করতে পারে, প্রতিটি upstream টিমকে নতুন ওয়েবহুক যোগ করতে বলার বদলে।\n\nলগ আপনার ডাটাবেস বদলে না দেয়। আপনাকে এখনও বর্তমান স্টেটের জন্য একটি ডাটাবেস রাখতে হবে: সর্বশেষ অর্ডার স্ট্যাটাস, কাস্টমার রেকর্ড, ইনভেন্টরি কাউন্ট, এবং লেনদেনগত নিয়ম (যেমন "পেমেন্ট নিশ্চিত না হওয়া পর্যন্ত শিপ করবেন না")। লগকে মনে করুন পরিবর্তনের রেকর্ড হিসেবে এবং ডাটাবেসকে মনে করুন "এখন কী সত্য" জবাব দেয়ার জায়গা হিসেবে।\n\n## সাধারণ ভুল ও ফাঁদগুলো\n\nইভেন্ট স্ট্রিমিং সিস্টেমগুলোকে পরিষ্কার করে তুলতে পারে, কিন্তু কয়েকটি সাধারণ ভুল সুবিধাগুলো মুছে দিতে পারে। বেশিরভাগই আসে লগকে একটি রিমোট কন্ট্রোল হিসেবে ট্রিট করার কারণে, রেকর্ড হিসেবে নয়।\n\nএকটি সাধারণ ফাঁদ হলো ইভেন্টগুলোকে কমান্ড হিসেবে লেখা, যেমন "SendWelcomeEmail" বা "ChargeCardNow"। এতে কনজিউমারগুলো প্রযোজনার ইন্টেনশনের সাথে কঠিনভাবে যুক্ত হয়ে যায়। ইভেন্টগুলো ফ্যাক্ট হিসেবে ভাল কাজ করে: "UserSignedUp" বা "PaymentAuthorized"। ফ্যাক্টগুলো সময়ের সাথে ভালোভাবে স্থায়ী হয়ে যায়। নতুন টিমগুলো পরে সহজে ব্যবহার করতে পারে।\n\nডুপ্লিকেট ও রিট্রাই আরেকটি বড় সমস্যা। বাস্তব সিস্টেমে প্রোডিউসার রিট্রাই করে এবং কনজিউমার পুনরায় প্রসেস করে। আপনি যদি এটির জন্য পরিকল্পনা না করেন, দ্বিগুণ চার্জ, দ্বিগুণ ইমেইল, এবং রেগে যাওয়া সাপোর্ট টিকেট পাবেন। সমাধান জটিল নয়, কিন্তু এটি ইচ্ছাকৃত হতে হবে: idempotent হ্যান্ডলার, স্থির ইভেন্ট ID, এবং "ইতিমধ্যেই প্রয়োগ হয়েছে" সনাক্তকরণ ব্যবসায়িক নিয়ম।\n\nসাধারণ ফাঁদসমূহ:\n\n- কমান্ড-স্টাইল ইভেন্ট ব্যবহার করা যা সার্ভিসগুলোকে কী করতে হবে বলে—বজায়—রেকর্ড করার বদলে।\n- এমন কনজিউমার বানানো যা একই ইভেন্ট দুইবার দেখলে ভেঙে যায়।\n- খুব দ্রুত স্ট্রিম বিভক্ত করা, ফলে একটি ব্যবসায়িক ফ্লো খুব বেশি টপিকে ছড়িয়ে পড়ে।\n- স্কিমা নিয়ম উপেক্ষা করা যতক্ষণ না একটি ছোট পরিবর্তন পুরানো কনজিউমারকে ভেঙে দেয়।\n- স্ট্রিমিংকে ভালো ডাটাবেস ডিজাইনের বিকল্প ভাবা।\n\nস্কিমা ও ভার্সনিং বিশেষ মনোযোগ দাবি করে। আপনি JSON দিয়ে শুরু করলেও একটি পরিষ্কার কন্ট্রাক্ট দরকার: প্রয়োজনীয় ফিল্ড, ঐচ্ছিক ফিল্ড, এবং কীভাবে পরিবর্তনগুলো রোলআউট হবে। একটি ছোট পরিবর্তন যেমন ফিল্ড নাম পরিবর্তন অ্যানালিটিক্স, বিলিং, বা মোবাইল অ্যাপে চুপচাপ ভাঙতে পারে।\n\nআরেকটি ফাঁদ হল অতিরিক্ত বিভাজন। দলগুলো প্রায়ই প্রতিটি ফিচারের জন্য একটি নতুন স্ট্রিম তৈরি করে। এক মাস পরে কেউ উত্তর দিতে পারেনা "অর্ডারের বর্তমান অবস্থা কী?" কারণ কাহিনী অনেক স্থানে ছড়িয়ে আছে।\n\nইভেন্ট স্ট্রিমিং ভাল ডেটা মডেলের প্রয়োজনীয়তা শেষ করে না। আপনাকে এখনও এমন একটি ডাটাবেস দরকার যা বর্তমান সত্য উপস্থাপন করে। লগ ঐতিহাস নয়, পুরো অ্যাপ্লিকেশন নয়।\n\n## দ্রুত চেকলিস্ট এবং পরবর্তী ধাপ\n\nআপনি যদি কিউ আর Kafka ইভেন্ট স্ট্রিমিংয়ের মধ্যে আটকে থাকেন, কয়েকটি দ্রুত চেক শুরু করুন। এগুলো বলবে আপনি কি কেবল ওয়ার্কারদের মধ্যে হ্যান্ডঅফ চান, না কি এমন একটি লগ চান যা বছরগুলো ধরে পুনঃব্যবহৃত হবে।\n\n### দ্রুত চেকসমূহ\n\n- আপনি কি রেপ্লে প্রয়োজন (ব্যাকফিল, বাগ ফিক্স, বা নতুন ফিচার), এবং কতটা পেছন পর্যন্ত?\n- একই ইভেন্টটি একাধিক কনজিউমার প্রয়োজন হবে কি শীঘ্রই (analytics, search, ইমেইল, ফ্রড, বিলিং)?\n- আপনি কি এমন রিটেনশন চান যাতে টিমগুলো প্রযোজককে আবার বলার প্রয়োজন ছাড়াই ইতিহাস পুনরায় পড়তে পারে?\n- অর্ডারিং কত গুরুত্বপূর্ণ, এবং কোন স্তরে: প্রতি সত্তা (প্রতি অর্ডার, প্রতি ব্যবহারকারী) নাকি গ্লোবাল?\n- কনজিউমাররা কি idempotent হতে পারবে (একই ইভেন্ট পুনরায় প্রয়োগ করে দ্বিগুণ চার্জ/ইমেইল/আপডেট হবে না)?\n\nআপনি যদি "না" বলেন রেপ্লে, "একই কনজিউমার মাত্র", এবং "স্বল্পমেয়াদী মেসেজ"—তাহলে একটি বেসিক কিউ সাধারণত যথেষ্ট। যদি আপনি "হ্যাঁ" বলেন রেপ্লে, বহু কনজিউমার, বা দীর্ঘ রিটেনশন—তাহলে লগ-বেসড পদ্ধতি অধিক ফলপ্রসূ কারণ এটি এক স্ট্রিম অফ ফ্যাক্টকে শেয়ার্ড সোর্স অফ ট্রুথে পরিণত করে।\n\n### পরবর্তী ধাপ\n\nউত্তরগুলোকে একটি ছোট, টেস্টেবল প্ল্যানে পরিণত করুন।\n\n- 5-10টি মূল ইভেন্ট সাধারণ ভাষায় তালিকাভুক্ত করুন (উদাহরণ: OrderPlaced, PaymentAuthorized, OrderShipped) এবং লিখে রাখুন কে প্রকাশ করে এবং কে প্রতিটি খায়।\n- অর্ডারিং কী (প্রায়ই প্রতি সত্তা, যেমন orderId) নির্ধারণ করুন এবং কীভাবে "সঠিক অর্ডার" বোঝানো হবে তা ডকুমেন্ট করুন।\n- প্রতিটি কনজিউমারের জন্য একটি idempotency নিয়ম নির্ধারণ করুন (উদাহরণ: প্রতিটি অর্ডারের জন্য সর্বশেষ প্রক্রিয়াকৃত ইভেন্ট ID সংরক্ষণ)।\n- আপনার প্রয়োজন মেটানোর জন্য রিটেনশন টার্গেট বেছে নিন (কিউ-রকমের ওয়ার্কফ্লো হলে দিন, রেপ্লে গুরুত্বপূর্ণ হলে সপ্তাহ/মাস)।\n- পুরো সিস্টেম কমিট করার আগে একটি স্যান্ডবক্সে একটি end-to-end স্লাইস চালান।\n\nপ্রোটোটাইপ তাড়াতাড়ি করতে চাইলে আপনি Koder.ai planning mode-এ ইভেন্ট ফ্লো স্কেচ করতে পারেন এবং ডিজাইন ইটারেট করতে পারেন। কারণ Koder.ai সোর্স কোড এক্সপোর্ট, স্ন্যাপশট এবং রোলব্যাক সাপোর্ট করে, এটি একটি ছোট প্রোডিউসার-কনজিউমার স্লাইস পরীক্ষা করে ইভেন্ট শেপ অ্যাডজাস্ট করার নিরাপদ উপায়। একবার স্থিতিশীল হলে কোড এক্সপোর্ট করে যেকোন জায়গায় চালান।

সাধারণ প্রশ্ন

What’s the simplest way to explain “queue vs log”?

একটি কিউ হচ্ছে সেই কাজের টিকিটগুলোর জন্য উপযুক্ত যা আপনি সম্পন্ন করে ভুলে যেতে চান (ইমেইল পাঠানো, ছবি রিসাইজ করা, কোনো ব্যাচ জব চালানো)। একটি লগ হলো সেই তথ্যের জন্য উপযুক্ত যা আপনি রেকর্ড হিসেবে রাখতে চান এবং যেকোনো সময় বহু সিস্টেম পড়তে ও পুনরায় প্লে করতে পারে (OrderPlaced, PaymentAuthorized, RefundIssued)।

How do I know my point-to-point integrations are becoming a problem?

আপনি সেটি অনুভব করবেন যখন প্রতিটি নতুন ফিচারের জন্য বহু ইন্টিগ্রেশন স্পর্শ করতে হয়, এবং ডিবাগ করা হয়ে যায় “এই মানটা কে লিখেছে?”—কোনো পরিষ্কার টাইমলাইন ছাড়া। একটি লগ সহ একটি শেয়ার্ড রেকর্ড থাকে যা আপনি পরীক্ষা ও পুনরায়-প্লে করতে পারেন, ফলে ছড়িয়ে থাকা ডাটাবেস স্টেট থেকে অনুমান করতে হয় না।

When does a log-based approach (Kafka-style) actually pay off?

যখন আপনাকে আডিট ট্রেইল ও রেপ্লে প্রয়োজন হয়: বাগ ঠিক করার জন্য ইতিহাস পুনরায় প্রসেস করা, পুরোনো ডেটা থেকে নতুন ফিচার ব্যাকফিল করা, বা “সেটার সময় আমরা কী জানতাম?” জাতীয় তদন্ত চালানো। এছাড়া যখন একই ইভেন্টের বহুমুখী কনজিউমার (billing, analytics, support, fraud) দরকার পড়ে এবং প্রোডিউসারকে বারবার বদলাতে না চাওয়া হয়।

Why does the “source of truth” argument get worse as systems grow?

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

What should an event look like if I want it to age well?

ইভেন্টগুলোকে অম্যুটেবল ফ্যাক্ট হিসেবে মডেল করুন (ভূতকালে বলা) যা ইতিমধ্যে ঘটে গেছে:\n\n- OrderPlaced, ProcessOrder নয়\n- PaymentAuthorized, ChargeCardNow নয়\n- UserEmailChanged, UpdateEmail নয়\n\nযদি পরে কিছু বদলে যায়, পুরনোটি এডিট করার বদলে একটি নতুন ইভেন্ট প্রকাশ করুন যা নতুন সত্য প্রকাশ করে।

How do I prevent duplicate events from causing real damage?

ধরুন ডুপ্লিকেট হতে পারে (at-least-once delivery সাধারণ)। প্রতিটি কনজিউমারকে রিট্রাই-সেফ করে তুলুন:\n\n- একটি স্থির ইভেন্ট ID ব্যবহার করুন এবং “ইতিমধ্যেই প্রক্রিয়াকৃত” মার্কার সংরক্ষণ করুন\n- যেখানে সম্ভব ইউনিক কনস্ট্রেইন্ট ব্যবহার করুন\n- একই ইভেন্ট দু'বার প্রয়োগ করে দ্বিগুণ পার্শ্বপ্রতিক্রিয়া (যেমন দ্বিগুণ চার্জ) না হয় তা ডিজাইন করুন\n\nডিফল্ট নিয়ম: সঠিকতা আগে, গতি পরে।

How should I evolve event schemas without breaking consumers?

অ্যাডিটিভ পরিবর্তনগুলোই ভালো: পুরনো ফিল্ড রাখুন, নতুন ফিল্ড যোগ করুন (ঐচ্ছিক), এবং এমনভাবে নাম বদলান/মুছুন না যা বিদ্যমান কনজিউমারকে ভেঙে দেবে। যদি ব্রেকিং পরিবর্তন অবধারিত হয়, ইভেন্ট (বা টপিক) ভার্সন করুন এবং কনজিউমারগুলো ইচ্ছাকৃতভাবে মাইগ্রেট করুন—সোজা JSON আপডেট নয়।

What’s a good first step if I’m switching from a queue mindset to a log mindset?

একটি পাতলা, end-to-end স্লাইস দিয়ে শুরু করুন:\n\n1. একটি ব্যবসায়িক ফ্লো বেছে নিন (উদাহরণ: OrderPlaced → email receipt).\n2. স্পষ্ট ইভেন্ট নাম ও প্রয়োজনীয় ফিল্ড নির্ধারণ করুন।\n3. অর্ডারিং কী বেছে নিন (orderId বা userId সাধারণ)।\n4. কনজিউমারকে idempotent করুন।\n5. টেস্ট করার জন্য রিটেনশন এত দীর্ঘ রাখুন যাতে রেপ্লে করা যায়।\n\nলুপটি কাজ করছে কিনা প্রমাণ করে তারপর বাকিটা বাড়ান।

Does an event log replace my database?

না। বর্তমান স্টেটের জন্য ডাটাবেস রাখুন এবং ট্রানজেকশনাল নিয়ম। ইভেন্ট লগ ইতিহাসের জন্য এবং ডেরাইভড ভিউ (analytics টেবিল, সার্চ ইন্ডেক্স, টাইমলাইন) পুনর্নির্মাণের জন্য। সহজভাবে: DB হলো ‘এখন কী সত্য’, লগ হলো পরিবর্তনের রেকর্ড।

How can Koder.ai help me prototype an event-streaming design safely?

Planning mode প্রকাশক/কনজিউমার ম্যাপ করতে, ইভেন্ট নাম নির্ধারণ করতে এবং idempotency ও retention ঠিক করতে কাজে আসে; তারপর আপনি একটি ছোট প্রোডিউসার-কনজিউমার স্লাইস তৈরি করে স্ন্যাপশট, রোলব্যাক দিয়ে পরীক্ষা করতে পারেন। স্থিতিশীল হলে সোর্স কোড এক্সপোর্ট করে ডিপ্লয় করুন।

সূচিপত্র
কেন দলগুলো ঐতিহ্যবাহী ইন্টিগ্রেশনে বারান্দায় আটকে পড়ে\n\nঅধিকাংশ প্রোডাক্ট সহজ পয়েন্ট-টু-পয়েন্ট ইন্টিগ্রেশন দিয়ে শুরু করে: সিস্টেম A সিস্টেম B-কে কল করে, বা একটি ছোট স্ক্রিপ্ট এক জায়গা থেকে ডেটা কপি করে। সেটা কাজ করে যতক্ষণ প্রোডাক্ট ছোট থাকে, দল আলাদা হয় না, এবং সংযোগের সংখ্যা বেশি নয়। কিন্তু প্রোডাক্ট বড় হলে, দলগুলো ভাগ হলে, সংযোগ গুণতে শুরু করলে সমস্যা দেখা দেয়। দ্রুত ছোট একটি ফিল্ড বা স্ট্যাটাস আপডেট বহু সার্ভিসে তরঙ্গের মত ছড়িয়ে যেতে পারে।\n\nগতিই সাধারণত প্রথম যে জিনিস ভেঙে পড়ে। একটি নতুন ফিচার যোগ করতে হলে বহু ইন্টিগ্রেশন আপডেট করতে হয়, কয়েকটি সার্ভিস রিডিপ্লয় করতে হয়, এবং আশা করতে হয় আগের আচরণের ওপর আর কেউ নির্ভর করে নি।\n\nতারপর ডিবাগ করা কষ্টদায়ক হয়ে ওঠে। UI-তে কিছু ভুল দেখলে মৌলিক প্রশ্নগুলো করা কঠিন: কী ঘটেছে, কী ক্রমে ঘটেছে, এবং কোন সিস্টেম আপনাকে যে মানটি দেখাচ্ছে তা লিখেছে?\n\nঅনেক সময় সমস্যার মুলটুকু হলো নিরীক্ষা ট্রেইল। যদি ডেটা সরাসরি এক ডাটাবেস থেকে আরেকটায় পাঠানো হয় (বা পথে ট্রান্সফর্ম হয়ে যায়), আপনি ইতিহাস হারান। আপনি হয়ত চূড়ান্ত স্টেট দেখবেন, কিন্তু সেই স্টেটে পৌঁছানোর জন্য কি ঘটেছে তার সিকোয়েন্স আপনি পাবেন না। ইনসিডেন্ট রিভিউ ও কাস্টমার সাপোর্ট দুটোই কষ্ট পায় কারণ আপনি অতীত আবার প্লে করে নিশ্চিত করতে পারেন না কী পরিবর্তিত হয়েছে এবং কেন।\n\nএখানেই "Who owns the truth" আর্কুমেন্টটা শুরু হয়। একটি টিম বলে, “বিলিং সার্ভিসই সোর্স অফ ট্রুথ।” অন্যটি বলে, “অর্ডার সার্ভিস।” বাস্তবে প্রতিটি সিস্টেমের আংশিক ভিউ থাকে, এবং পয়েন্ট-টু-পয়েন্ট ইন্টিগ্রেশনগুলো সেই অমতকে প্রতিদিনের ঘর্ষণে পরিণত করে।\n\nএকটি সাধারণ উদাহরণ: একটি অর্ডার তৈরি হয়, তারপর পেমেন্ট হয়, তারপর রিফান্ড হয়। যদি তিনটি সিস্টেম একে অপরকে সরাসরি আপডেট করে, রিট্রাই, টাইমআউট, বা ম্যানুয়াল ফিক্সের কারণে প্রতিটির কাছে ভিন্ন গল্প থাকা স্বাভাবিক।\n\nএটাই Kafka ইভেন্ট স্ট্রিমিংয়ের নীতিগত প্রশ্ন: আপনি কি শুধু কাজ এক জায়গা থেকে আরেকটা জায়গায় সরাতে চান (একটি কিউ), নাকি এমন একটি শেয়ার্ড, টেকসই রেকর্ড চান যা বহু সিস্টেম পড়তে, রিওয়াইন্ড করতে এবং বিশ্বাস করতে পারে (একটি লগ)? এর উত্তর আপনার সিস্টেম বানানো, ডিবাগ করা এবং বিকাশের পথ বদলে দেয়।\n\n## Jay Kreps, Kafka এবং লগের ধারণা\n\nJay Kreps Kafka গঠনে সাহায্য করেছেন এবং আরও গুরুত্বপূর্ণভাবে অনেক দলের ডেটা মুভমেন্ট সম্পর্কে চিন্তাধারা বদলে দিয়েছেন। দরকারী শিফটটা হলো মানসিকতা: ম্যাসেজগুলোকে একবারের ডেলিভারি হিসেবে দেখা বন্ধ করুন, এবং সিস্টেমের কার্যকলাপকে একটি রেকর্ড হিসেবে দেখুন।\n\nমূল ধারণাটা সহজ। গুরুত্বপূর্ণ পরিবর্তনগুলোকে অপরিবর্তনীয় ফ্যাক্টস হিসেবে স্ট্রিম আকারে মডেল করুন:\n\n- একটি অর্ডার তৈরি হল।\n- একটি পেমেন্ট অথরাইজড হলো।\n- একজন ব্যবহারকারী ইমেইল বদলালেন।\n\nপ্রতিটি ইভেন্ট এমন একটি ফ্যাক্ট যা পরে এডিট হওয়া উচিত নয়। যদি পরে কিছু বদলে যায়, আপনি একটি নতুন ইভেন্ট যোগ করেন যা নতুন সত্য বলে। সময়ের সাথে সেই ফ্যাক্টগুলো একটি লগ গঠন করে: আপনার সিস্টেমের একটি অ্যাপেন্ড-ওনলি ইতিহাস।\n\nএখানেই Kafka ইভেন্ট স্ট্রিমিং অনেক বেসিক মেসেজিং সেটআপ থেকে আলাদা। অনেক কিউ "পাঠাও, প্রসেস কর, মুছে ফেল"-ভিত্তিক। যখন কাজ শুধু হ্যান্ড-অফ, তখন তা ঠিক আছে। লগ ভিউ বলে, "ইতিহাস রাখুন যাতে বহু কনজিউমার তা এখনো এবং পরে ব্যবহার করতে পারে।"\n\nইতিহাস পুনরায় চালানো হল ব্যবহারিক সুপারপাওয়ার।\n\nযদি একটি রিপোর্ট ভুল হয়, আপনি একই ইভেন্ট ইতিহাসকে একটি ফিক্সড অ্যানালিটিক্স জবের মধ্য দিয়ে পুনরায় চালাতে পারেন এবং দেখতে পারেন কোথায় সংখ্যা বদলালো। যদি কোনো বাগ ভুল ইমেইল পাঠায়, আপনি ইভেন্টগুলো টেস্ট এনভায়রনমেন্টে রেপ্লে করে একই টাইমলাইন পুনরায় উৎপাদন করতে পারেন। যদি একটি নতুন ফিচার পুরনো ডেটা চান, আপনি একটি নতুন কনজিউমার বানিয়ে শুরু থেকেই পড়তে দিতে পারেন এবং নিজ গতিতে ক্যাচ-আপ করতে পারেন।\n\nএকটি কংক্রিট উদাহরণ: ধরুন আপনি পরে ফ্রড চেক যোগ করেন যখন ইতিমধ্যেই মাসব্যাপী পেমেন্ট প্রসেস করেছেন। পেমেন্ট ও অ্যাকাউন্ট ইভেন্টগুলোর একটি লগ থাকলে আপনি অতীতটি রেপ্লে করে বাস্তব সিকোয়েন্সের ওপর রুল ট্রেইন/ক্যালিব্রেট করতে পারেন, পুরোনো লেনদেনের জন্য রিস্ক স্কোর হিসাব করতে পারেন, এবং ডাটাবেস রিরাইট না করে "fraud_review_requested" ইভেন্ট ব্যাকফিল করতে পারেন।\n\nদেখুন এটা আপনাকে কী বাধ্য করে। লগ-বেসড পদ্ধতি আপনাকে ইভেন্টগুলোর স্পষ্ট নাম রাখতে, তাদের স্থিতিশীল রাখতে এবং একাধিক দল/সার্ভিস তাদের ওপর নির্ভর করবে এটা মেনে নিতে বাধ্য করে। এটি ব্যবহারিক প্রশ্নও জাগায়: কোনটি সোর্স অফ ট্রুথ? এই ইভেন্টের দীর্ঘমেয়াদী অর্থ কী? আমরা ভুল করলে কী করব?\n\nমূল্যটা ব্যক্তিগতত্বে নয়। এটি উপলব্ধি করা যে একটি শেয়ার্ড লগ আপনার সিস্টেমের মেমোরি হয়ে উঠতে পারে, এবং মেমোরিই এমন জিনিস যা সিস্টেমগুলোকে নতুন কনজিউমার যোগ করলেও ভেঙে ফেলতে দেয় না।\n\n## কিউ বনাম লগ: সবচেয়ে সরল মানসিক মডেল\n\nএকটি মেসেজ কিউ হলো আপনার সফটওয়্যারের জন্য একটি টু-ডু লাইন। প্রোডিউসার কাজ লাইনটিতে রাখে, কনজিউমার পরের আইটেম নেয়, কাজ করে, এবং আইটেমটাকে মুছে ফেলা হয়। সিস্টেমটি মূলত প্রতিটি টাস্ক যত দ্রুত সম্ভব হ্যান্ডেল করা নিয়ে।\n\nএকটি লগ ভিন্ন। এটি ঘটনাগুলোর একটি অর্ডার্ড রেকর্ড যা টেকসইভাবে সংরক্ষিত থাকে। কনজিউমার ইভেন্টগুলো "নেই করে" না; তারা নিজ গতিতে লগ পড়ে এবং পরে আবারও পড়তে পারে। Kafka ইভেন্ট স্ট্রিমিংয়ে সেই লগই মূল ধারণা।\n\nমনে রাখার সহজ উপায়:\n\n- Queue = করার কাজ। একজন ওয়ার্কার নিশ্চিত করলে তা অদৃশ হয়।\n- Log = কী ঘটেছে তার ইতিহাস। ইভেন্টগুলো একটি রিটেনশন পিরিয়ডের জন্য থাকে।\n\nরিটেনশন ডিজাইন বদলে দেয়। কিউতে যদি পরে কোনো নতুন ফিচার পুরোনো মেসেজের ওপর নির্ভর করে (অ্যানালিটিক্স, ফ্রড চেক, বাগের পরে রেপ্লে), আপনাকে আলাদা একটি ডাটাবেস যোগ করতে হতে পারে বা অতিরিক্ত কপি ধরতে হতে পারে। লগে রেপ্লে স্বাভাবিক: আপনি শুরু থেকে (অথবা একটি জানা চেকপয়েন্ট থেকে) পড়ে একটি ডেরাইভড ভিউ পুনর্নির্মাণ করতে পারেন।\n\nফ্যান-আউটও একটি বড় পার্থক্য। ধরা যাক চেকআউট সার্ভিস "OrderPlaced" ইমিট করে। কিউতে সাধারণত আপনি একটি ওয়ার্কার গ্রুপ বেছে নেন এটি প্রসেস করার জন্য, অথবা একাধিক কিউতে কাজ ডুপ্লিকেট করে ফেলেন। লগে billing, email, inventory, search indexing, এবং analytics একই ইভেন্ট স্ট্রিম স্বাধীনভাবে পড়তে পারে। প্রতিটি টিম নিজ গতিতে কাজ করতে পারে, এবং পরে একটি নতুন কনজিউমার যোগ করতে প্রোডিউসারকে বদলাতে হয় না।\n\nসুতরাং মানসিক মডেল সরল: যখন আপনি টাস্ক সরাতে চান কিউ ব্যবহার করুন; যখন আপনি এমন ইভেন্ট রেকর্ড করতে চান যা কোম্পানির অনেক অংশ পরে বা এখনও পড়তে চায়, লগ ব্যবহার করুন।\n\n## ইভেন্ট স্ট্রিমিং সিস্টেম ডিজাইনকে কীভাবে বদले\n\nইভেন্ট স্ট্রিমিং ডিফল্ট প্রশ্নটাকে উল্টো করে দেয়। "আমি এই মেসেজটা কাকে পাঠাব?" জিজ্ঞাসা করার বদলে আপনি শুরু করেন "এখন কী ঘটেছে?" দিয়ে। এটা ছোট মনে হলেও আপনার সিস্টেম মডেল করা বদলে দেয়।\n\nআপনি `OrderPlaced` বা `PaymentFailed`-এর মতো ফ্যাক্ট পাবলিশ করেন, এবং সিস্টেমের অন্যান্য অংশই সিদ্ধান্ত নেয় তারা কীভাবে, কখন ও কিভাবে প্রতিক্রিয়া দেখাবে।\n\nKafka ইভেন্ট স্ট্রিমিংয়ে প্রোডিউসারদের কাছে সরাসরি ইন্টিগ্রেশনগুলোর তালিকা থাকতে হয় না। একটি চেকআউট সার্ভিস একটি ইভেন্ট পাবলিশ করলে সেটি জানে না analytics, email, fraud checks, বা ভবিষ্যতের recommendation সার্ভিস এটা ব্যবহার করবে কি না। নতুন কনজিউমার পরে আসতে পারে, পুরনোগুলো পজ করা যায়, এবং প্রোডিউসারের আচরণ অপরিবর্তিত থেকে যায়।\n\nএটি কিভাবে ভুল থেকে পুনরুদ্ধার করা হয় তাও বদলে দেয়। কেবল মেসেজিং দুনিয়ায়, একবার কনজিউমার কিছু মিস করলে বা বাগ করলে ডেটা প্রায়ই "চলে যায়" যদি না আপনি কাস্টম ব্যাকআপ তৈরি করে রাখেন। লগ থাকলে আপনি কোড ঠিক করে ইতিহাস রেপ্লে করে সঠিক স্টেট পুনর্নির্মাণ করতে পারেন। বেশিরভাগ সময় সেটা ম্যানুয়াল ডাটাবেস এডিট বা এক-বারের স্ক্রিপ্টের চাইতে ভালো।\n\nপ্রায়োগিকভাবে এই শিফট কিছু নির্ভরযোগ্য উপায়ে দেখা যায়: আপনি ইভেন্টগুলোকে একটি স্থায়ী রেকর্ড হিসেবে বিবেচনা করেন, ফিচার যোগ করতে সাবস্ক্রাইব করেন बजाय প্রোডিউসার পরিবর্তনের, আপনি রিড-মডেল (সার্চ ইন্ডেক্স, ড্যাশবোর্ড) শূন্য থেকে পুনর্নির্মাণ করতে পারেন, এবং সার্ভিসগুলো জুড়ে কী ঘটেছে তার স্পষ্ট টাইমলাইন পান।\n\nঅবজারভেবিলিটি উন্নত হয় কারণ ইভেন্ট লগ একটি শেয়ার্ড রেফারেন্স হিসেবে কাজ করে। যখন কিছু ভুল হয়, আপনি একটি ব্যবসায়িক সিকোয়েন্স অনুধাবন করতে পারেন: order created, inventory reserved, payment retried, shipment scheduled। সেই টাইমলাইন সাধারণত ছড়িয়ে থাকা অ্যাপ্লিকেশন লগের চেয়ে বুঝতে সহজ কারণ এটা ব্যবসায়িক ফ্যাক্টের ওপর ফোকাস করে।\n\nএকটি কংক্রিট উদাহরণ: যদি দু'ঘন্টার জন্য একটি ডিসকাউন্ট বাগ অর্ডারগুলো ভুল মূল্য নির্ধারণ করে, আপনি একটি ফিক্স পাঠান এবং প্রভাবিত ইভেন্টগুলো রেপ্লে করে টোটাল পুনর্গণনা, ইনভয়েস আপডেট এবং অ্যানালিটিক্স রিফ্রেশ করতে পারেন। আপনি আউটকামগুলো পুনরায়derive করে ঠিক করছেন, কারো টেবিল ম্যানুয়ালি প্যাচ করে অনুমান করে ঠিক করছেন না।\n\n## কখন একটি সাধারণ কিউই যথেষ্ট\n\nএকটি সাধারণ কিউ ঠিক টুল যখন আপনি কাজ সরাতে চান, ইতিহাস তৈরি করতে চান না। লক্ষ্য হলো টাস্কটি ওয়ার্কারকে হস্তান্তর করা, চালানো, এবং তারপর ভুলে যাওয়া। যদি কেউ অতীত পুনরায় চালাতে না চায়, পুরোনো ইভেন্টগুলো পরীক্ষা করতে না চায়, বা ভবিষ্যতে নতুন কনজিউমার যোগ হবে না, একটি কিউ সরল রাখে।\n\nকিউ ব্যাকগ্রাউন্ড জবের জন্য উপযুক্ত: সাইনআপ ইমেইল পাঠানো, আপলোডের পর ছবি রিসাইজ করা, নাইটলি রিপোর্ট জেনারেট করা, বা ধীর থার্ড-পার্টি API কল করা। এই পরিস্থিতিগুলোতে মেসেজটি কেবল একটি কাজের টিকিট। যখন ওয়ার্কার কাজ শেষ করে, টিকিটের কাজও সম্পন্ন।\n\nএকটি কিউ সাধারণত মালিকানার সাদৃশ্য পূরণ করে: একটি কনজিউমার গ্রুপ টাস্কটির দায় নেয়, এবং অন্য সার্ভিসগুলো একই মেসেজ স্বাধীনভাবে পড়ার আশা করে না।\n\nএকটি কিউ সাধারণত যথেষ্ট যখন নিচের অধিকাংশ সত্য:\n\n- ডেটার মূল্য স্বল্পমেয়াদী।\n- এক দল বা এক সার্ভিস কাজটি end-to-end মালিকানায় রাখে।\n- রেপ্লে ও দীর্ঘ রিটেনশন আবশ্যক নয়।\n- ডিবাগিং ইতিহাস পুনরায় চালানোর উপর নির্ভর করে না।\n\nউদাহরণ: একজন ব্যবহারকারী ছবি আপলোড করে। অ্যাপ একটি "resize image" টাস্ক কিউতে লিখে। ওয়ার্কার A তা নেয়, থাম্বনেইল তৈরি করে, স্টোর করে, এবং টাস্কটি সম্পন্ন হিসেবে চিহ্নিত করে। যদি টাস্কটি দুইবার চলে, আউটপুট একই (idempotent), তাই at-least-once ডেলিভারি ঠিক আছে। আর কোনো সার্ভিস পরে সেই টাস্কটি স্বাধীনভাবে পড়তে চায় না।\n\nআপনার প্রয়োজন যদি ধীরে ধীরে শেয়ার্ড ফ্যাক্টস, রেপ্লে, অডিট, বা "গত সপ্তাহে সিস্টেম কী বিশ্বাস করেছিল?" এর দিকে সরে যায়, তখন Kafka ইভেন্ট স্ট্রিমিং ও লগ-বেসড পদ্ধতি ব্যবহার করে সুবিধা পাওয়া শুরু হবে।\n\n## কখন লগ-বেসড পদ্ধতি উপকারী\n\nএকটি লগ-বেসড সিস্টেম তখন উপকারী যখন ইভেন্টগুলো একবারের মেসেজ না থেকে শেয়ার্ড ইতিহাস হয়ে ওঠে। "পাঠাও এবং ভুলে যাও"-এর বদলে আপনি একটি অর্ডার্ড রেকর্ড রাখেন যা বহু টিম স্বাধীনভাবে এখন বা পরে পড়তে পারে।\n\nসবচেয়ে স্পষ্ট সংকেতটি হলো বহু কনজিউমার। একটি ইভেন্ট যেমন "OrderPlaced" billing, email, fraud checks, search indexing এবং analytics—সবকিছু খাওয়াতে পারে। লগে প্রতিটি কনজিউমার একই স্ট্রীম স্বাধীনভাবে পড়ে। আপনাকে কাস্টম ফ্যান-আউট পাইপলাইন বানাতে বা কে প্রথম মেসেজ পাবে তা সমন্বয় করতে হয় না।\n\nআরেকটি সুবিধা: আপনি প্রশ্নের উত্তর দিতে পারেন, "তখন আমরা কী জানতাম?" একজন কাস্টমার চার্জ নিয়ে বিরোধ করলে বা কোনো রিকমেন্ডেশন ভুল হলে, একটি অ্যাপেন্ড-ওনলি ইতিহাস আপনাকে আসল সময়ে যে ফ্যাক্টগুলো এসেছিল সেগুলো রেপ্লে করে দেখতে দেয়। এটি একটি সাধারন কিউ-তে পরে ঝুট করে লাগানো কঠিন।\n\nআপনি নতুন ফিচার যোগ করতে পারেন পুরনোগুলো রিরাইট না করে। যদি আপনি কয়েক মাস পরে একটি নতুন "shipping status" পেজ যোগ করতে চান, একটি নতুন সার্ভিস ইতিহাস থেকে সাবস্ক্রাইব করে ব্যাকফিল করে নিজের স্টেট তৈরি করতে পারে, বরং প্রতিটি upstream সিস্টেমকে এক্সপোর্ট দিতে বলার দরকার পড়ে না।\n\nলগ-বেসড পদ্ধতি প্রায়ই লাভজনক যখন নিচের কোনগুলোর প্রয়োজন দেখা দেয়:\n\n- একই ইভেন্টকে বহু সিস্টেম (analytics, search, billing, support) খাওয়াতে হবে।\n- রেপ্লে, অডিটিং, বা অতীত ফ্যাক্টের ওপর তদন্ত প্রয়োজন।\n- নতুন সার্ভিসগুলোকে ইতিহাস থেকে ব্যাকফিল করতে হবে কোনো এক-বারের জব ছাড়াই।\n\n- নির্দিষ্ট সত্তা অনুসারে অর্ডারিং গুরুত্বপূর্ণ (প্রতি অর্ডার, প্রতি ব্যবহারকারী)।\n- ইভেন্ট ফরম্যাট বিবর্তিত হবে এবং আপনাকে ভার্সনিং কন্ট্রোল করতে হবে।\n\nএকটি সাধারণ প্যাটার্ন: প্রথমে একটি প্রোডাক্ট অর্ডার ও ইমেইল নিয়ে শুরু করে। পরে ফাইন্যান্স রেভিনিউ রিপোর্ট চায়, প্রোডাক্ট ফানেল চায়, এবং অপস লাইভ ড্যাশবোর্ড চায়। যদি প্রতিটি নতুন প্রয়োজন আপনাকে নতুন পাইপলাইন কপি করতে বাধ্য করে, খরচ দ্রুত বেড়ে যায়। একটি শেয়ার্ড ইভেন্ট লগ টিমগুলোকে একই সোর্স অফ ট্রুথে কাজ করতে দেয়, এমনকি সিস্টেম বড় হলেও ও ইভেন্টের গঠন বদলেও।\n\n## কীভাবে সিদ্ধান্ত নেবেন, ধাপে ধাপে\n\nকিউ এবং লগ-বেসড পদ্ধতির মধ্যে নির্বাচন একটি প্রোডাক্ট সিদ্ধান্তের মত করা সহজ। আজকের জন্য কাজ করছে তা না দেখে, এক বছরের পরে কী থাকা উচিত সেই দিক থেকে শুরু করুন।\n\n### একটি ব্যবহারিক ৫-ধাপ সিদ্ধান্ত\n\n1) প্রকাশক এবং পাঠক ম্যাপ করুন। লিখে রাখুন কারা ইভেন্ট তৈরি করে এবং কারা আজ পড়ে, তারপর সম্ভাব্য ভবিষ্যৎ কনজিউমার যোগ করুন (analytics, search indexing, fraud checks, customer notifications)। যদি আপনি বহু টিম একই ইভেন্ট স্বাধীনভাবে পড়বে বলে মনে করেন, লগ যুক্তির পক্ষে যায়।\n\n2) জিজ্ঞাসা করুন আপনি ইতিহাস পুনরায় পড়তে চাইবেন কি না। কেন নির্দিষ্টভাবে: বাগের পরে রেপ্লে, ব্যাকফিল, বা যা ভিন্ন গতিতে পড়ে। কিউ একবার হ্যান্ড-অফের জন্য দুর্দান্ত। লগ তখন ভালো যখন আপনি এমন একটি রেকর্ড চান যা আপনি রেপ্লে করতে পারবেন।\n\n3) নির্ধারণ করুন "ডান হওয়া" মানে কী। কিছু ওয়ার্কফ্লোরে ডান হওয়া মানে "জবটি চালানো হলো" (ইমেইল পাঠানো, ছবি রিসাইজ)। অন্যগুলোর জন্য ডান হওয়া মানে "ইভেন্টটি একটি টেকসই ফ্যাক্ট" (অর্ডার প্লেসড, পেমেন্ট অথরাইজড)। টেকসই ফ্যাক্টস আপনাকে লগের দিকে ধাক্কা দেয়।\n\n4) ডেলিভারি প্রত্যাশা বেছে নিন এবং কিভাবে ডুপ্লিকেট হ্যান্ডেল করবেন তা সিদ্ধান্ত নিন। at-least-once ডেলিভারি সাধারণ, যার মানে ডুপ্লিকেট হতে পারে। যদি ডুপ্লিকেট ক্ষতিকর (যেমন দ্বিগুণ চার্জ), তাহলে idempotency পরিকল্পনা করুন: প্রক্রিয়াকৃত ইভেন্ট ID সংরক্ষণ, ইউনিক কনস্ট্রেইন্ট ব্যবহার, বা এমনভাবে আপডেট করুন যাতে বারবার প্রয়োগ করা নিরাপদ।\n\n5) একটি পাতলা স্লাইস দিয়ে শুরু করুন। একটি ইভেন্ট স্ট্রিম বেছে নিন যা সহজে বোঝা যায় এবং সেখান থেকে বাড়ান। যদি আপনি Kafka ইভেন্ট স্ট্রিমিং বেছে নেন, প্রথম টপিকটিকে ফোকাসেড রাখুন, ইভেন্টগুলোকে স্পষ্টভাবে নাম দিন, এবং অপ্রাসঙ্গিক ইভেন্ট টাইপ মিশাবেন না।\n\nএকটি কংক্রিট উদাহরণ: যদি "OrderPlaced" পরে শিপিং, ইনভয়সিং, সাপোর্ট, এবং অ্যানালিটিক্স খাওয়াবে, একটি লগ প্রতিটি টিমকে নিজ গতিতে পড়তে এবং ভুল হলে রেপ্লে করে ক্যাচ-আপ করতে দেয়। যদি আপনি শুধুমাত্র ব্যাকগ্রাউন্ড ওয়ার্কার দিয়ে রসিদ ইমেইল পাঠাবেন, সাধারণ কিউ সাধারণত যথেষ্ট।\n\n## উদাহরণ: একটি বাড়তে থাকা প্রোডাক্টে অর্ডার ইভেন্ট\n\nএকটি ছোট অনলাইন স্টোর কল্পনা করুন। প্রথমে শুধু অর্ডার নিতে, কার্ড চার্জ দিতে, এবং শিপিং রিকোয়েস্ট তৈরি করতে হবে। সবচেয়ে সহজ ভার্সন হলো চেকআউটের পর একটি ব্যাকগ্রাউন্ড জব: "process order"। এটি পেমেন্ট API-কে কল করে, অর্ডার রো আপডেট করে, তারপর শিপিং কল করে।\n\nএই কিউ স্টাইল তখন ভালো কাজ করে যখন একটি স্পষ্ট ওয়ার্কফ্লো থাকে, একটি কনজিউমারই থাকে (ওয়ার্কার), এবং রিট্রাই ও ডেড-লেটার বেশিরভাগ ব্যর্থতা কভার করে।\n\nস্টোর বড় হলে সমস্যাটা শুরু হয়। সাপোর্ট স্বয়ংক্রিয় "অর্ডার কোথায়?" আপডেট চায়। ফাইন্যান্স ডেইলি রেভিনিউ চান। প্রোডাক্ট টিম কাস্টমার ইমেইল চায়। শিপিংয়ের আগে ফ্রড চেক করা উচিত। একটি একক "process order" জব থাকলে আপনি বারংবার সেই ওয়ার্কারটি এডিট করতে থাকেন, শাখা বাড়ান, এবং কোর ফ্লোতে নতুন বাগের ঝুঁকি নেন।\n\nলগ-বেসড পদ্ধতিতে চেকআউট ছোট ফ্যাক্টগুলো ইভেন্ট হিসেবে প্রকাশ করে, এবং প্রতিটি টিম তা ব্যবহার করে। সাধারণ ইভেন্টগুলো হতে পারে:\n\n- `OrderPlaced`\n- `PaymentConfirmed`\n- `ItemShipped`\n- `RefundIssued`\n\nমূল বদলটা হলো মালিকানা। চেকআউট সার্ভিস `OrderPlaced` এর মালিক। পেমেন্ট সার্ভিস `PaymentConfirmed` এর মালিক। শিপিং `ItemShipped` এর মালিক। পরে নতুন কনজিউমার আসলে প্রোডিউসার বদলাতে হয় না: একটি ফ্রড সার্ভিস `OrderPlaced` ও `PaymentConfirmed` পড়ে রিস্ক স্কোর করে, একটি ইমেইল সার্ভিস রসিদ পাঠায়, অ্যানালিটিক্স ফানেল তৈরি করে, এবং সাপোর্ট টুল টাইমলাইন রাখে।\n\nএখানেই Kafka ইভেন্ট স্ট্রিমিং সুবিধা দেয়: লগ ইতিহাস রাখে, তাই নতুন কনজিউমার শুরু থেকেই বা একটি নির্দিষ্ট পয়েন্ট থেকে রিওয়াইন্ড করে নিজের অবস্থান তৈরি করতে পারে, প্রতিটি upstream টিমকে নতুন ওয়েবহুক যোগ করতে বলার বদলে।\n\nলগ আপনার ডাটাবেস বদলে না দেয়। আপনাকে এখনও বর্তমান স্টেটের জন্য একটি ডাটাবেস রাখতে হবে: সর্বশেষ অর্ডার স্ট্যাটাস, কাস্টমার রেকর্ড, ইনভেন্টরি কাউন্ট, এবং লেনদেনগত নিয়ম (যেমন "পেমেন্ট নিশ্চিত না হওয়া পর্যন্ত শিপ করবেন না")। লগকে মনে করুন পরিবর্তনের রেকর্ড হিসেবে এবং ডাটাবেসকে মনে করুন "এখন কী সত্য" জবাব দেয়ার জায়গা হিসেবে।\n\n## সাধারণ ভুল ও ফাঁদগুলো\n\nইভেন্ট স্ট্রিমিং সিস্টেমগুলোকে পরিষ্কার করে তুলতে পারে, কিন্তু কয়েকটি সাধারণ ভুল সুবিধাগুলো মুছে দিতে পারে। বেশিরভাগই আসে লগকে একটি রিমোট কন্ট্রোল হিসেবে ট্রিট করার কারণে, রেকর্ড হিসেবে নয়।\n\nএকটি সাধারণ ফাঁদ হলো ইভেন্টগুলোকে কমান্ড হিসেবে লেখা, যেমন "SendWelcomeEmail" বা "ChargeCardNow"। এতে কনজিউমারগুলো প্রযোজনার ইন্টেনশনের সাথে কঠিনভাবে যুক্ত হয়ে যায়। ইভেন্টগুলো ফ্যাক্ট হিসেবে ভাল কাজ করে: "UserSignedUp" বা "PaymentAuthorized"। ফ্যাক্টগুলো সময়ের সাথে ভালোভাবে স্থায়ী হয়ে যায়। নতুন টিমগুলো পরে সহজে ব্যবহার করতে পারে।\n\nডুপ্লিকেট ও রিট্রাই আরেকটি বড় সমস্যা। বাস্তব সিস্টেমে প্রোডিউসার রিট্রাই করে এবং কনজিউমার পুনরায় প্রসেস করে। আপনি যদি এটির জন্য পরিকল্পনা না করেন, দ্বিগুণ চার্জ, দ্বিগুণ ইমেইল, এবং রেগে যাওয়া সাপোর্ট টিকেট পাবেন। সমাধান জটিল নয়, কিন্তু এটি ইচ্ছাকৃত হতে হবে: idempotent হ্যান্ডলার, স্থির ইভেন্ট ID, এবং "ইতিমধ্যেই প্রয়োগ হয়েছে" সনাক্তকরণ ব্যবসায়িক নিয়ম।\n\nসাধারণ ফাঁদসমূহ:\n\n- কমান্ড-স্টাইল ইভেন্ট ব্যবহার করা যা সার্ভিসগুলোকে কী করতে হবে বলে—বজায়—রেকর্ড করার বদলে।\n- এমন কনজিউমার বানানো যা একই ইভেন্ট দুইবার দেখলে ভেঙে যায়।\n- খুব দ্রুত স্ট্রিম বিভক্ত করা, ফলে একটি ব্যবসায়িক ফ্লো খুব বেশি টপিকে ছড়িয়ে পড়ে।\n- স্কিমা নিয়ম উপেক্ষা করা যতক্ষণ না একটি ছোট পরিবর্তন পুরানো কনজিউমারকে ভেঙে দেয়।\n- স্ট্রিমিংকে ভালো ডাটাবেস ডিজাইনের বিকল্প ভাবা।\n\nস্কিমা ও ভার্সনিং বিশেষ মনোযোগ দাবি করে। আপনি JSON দিয়ে শুরু করলেও একটি পরিষ্কার কন্ট্রাক্ট দরকার: প্রয়োজনীয় ফিল্ড, ঐচ্ছিক ফিল্ড, এবং কীভাবে পরিবর্তনগুলো রোলআউট হবে। একটি ছোট পরিবর্তন যেমন ফিল্ড নাম পরিবর্তন অ্যানালিটিক্স, বিলিং, বা মোবাইল অ্যাপে চুপচাপ ভাঙতে পারে।\n\nআরেকটি ফাঁদ হল অতিরিক্ত বিভাজন। দলগুলো প্রায়ই প্রতিটি ফিচারের জন্য একটি নতুন স্ট্রিম তৈরি করে। এক মাস পরে কেউ উত্তর দিতে পারেনা "অর্ডারের বর্তমান অবস্থা কী?" কারণ কাহিনী অনেক স্থানে ছড়িয়ে আছে।\n\nইভেন্ট স্ট্রিমিং ভাল ডেটা মডেলের প্রয়োজনীয়তা শেষ করে না। আপনাকে এখনও এমন একটি ডাটাবেস দরকার যা বর্তমান সত্য উপস্থাপন করে। লগ ঐতিহাস নয়, পুরো অ্যাপ্লিকেশন নয়।\n\n## দ্রুত চেকলিস্ট এবং পরবর্তী ধাপ\n\nআপনি যদি কিউ আর Kafka ইভেন্ট স্ট্রিমিংয়ের মধ্যে আটকে থাকেন, কয়েকটি দ্রুত চেক শুরু করুন। এগুলো বলবে আপনি কি কেবল ওয়ার্কারদের মধ্যে হ্যান্ডঅফ চান, না কি এমন একটি লগ চান যা বছরগুলো ধরে পুনঃব্যবহৃত হবে।\n\n### দ্রুত চেকসমূহ\n\n- আপনি কি রেপ্লে প্রয়োজন (ব্যাকফিল, বাগ ফিক্স, বা নতুন ফিচার), এবং কতটা পেছন পর্যন্ত?\n- একই ইভেন্টটি একাধিক কনজিউমার প্রয়োজন হবে কি শীঘ্রই (analytics, search, ইমেইল, ফ্রড, বিলিং)?\n- আপনি কি এমন রিটেনশন চান যাতে টিমগুলো প্রযোজককে আবার বলার প্রয়োজন ছাড়াই ইতিহাস পুনরায় পড়তে পারে?\n- অর্ডারিং কত গুরুত্বপূর্ণ, এবং কোন স্তরে: প্রতি সত্তা (প্রতি অর্ডার, প্রতি ব্যবহারকারী) নাকি গ্লোবাল?\n- কনজিউমাররা কি idempotent হতে পারবে (একই ইভেন্ট পুনরায় প্রয়োগ করে দ্বিগুণ চার্জ/ইমেইল/আপডেট হবে না)?\n\nআপনি যদি "না" বলেন রেপ্লে, "একই কনজিউমার মাত্র", এবং "স্বল্পমেয়াদী মেসেজ"—তাহলে একটি বেসিক কিউ সাধারণত যথেষ্ট। যদি আপনি "হ্যাঁ" বলেন রেপ্লে, বহু কনজিউমার, বা দীর্ঘ রিটেনশন—তাহলে লগ-বেসড পদ্ধতি অধিক ফলপ্রসূ কারণ এটি এক স্ট্রিম অফ ফ্যাক্টকে শেয়ার্ড সোর্স অফ ট্রুথে পরিণত করে।\n\n### পরবর্তী ধাপ\n\nউত্তরগুলোকে একটি ছোট, টেস্টেবল প্ল্যানে পরিণত করুন।\n\n- 5-10টি মূল ইভেন্ট সাধারণ ভাষায় তালিকাভুক্ত করুন (উদাহরণ: OrderPlaced, PaymentAuthorized, OrderShipped) এবং লিখে রাখুন কে প্রকাশ করে এবং কে প্রতিটি খায়।\n- অর্ডারিং কী (প্রায়ই প্রতি সত্তা, যেমন orderId) নির্ধারণ করুন এবং কীভাবে "সঠিক অর্ডার" বোঝানো হবে তা ডকুমেন্ট করুন।\n- প্রতিটি কনজিউমারের জন্য একটি idempotency নিয়ম নির্ধারণ করুন (উদাহরণ: প্রতিটি অর্ডারের জন্য সর্বশেষ প্রক্রিয়াকৃত ইভেন্ট ID সংরক্ষণ)।\n- আপনার প্রয়োজন মেটানোর জন্য রিটেনশন টার্গেট বেছে নিন (কিউ-রকমের ওয়ার্কফ্লো হলে দিন, রেপ্লে গুরুত্বপূর্ণ হলে সপ্তাহ/মাস)।\n- পুরো সিস্টেম কমিট করার আগে একটি স্যান্ডবক্সে একটি end-to-end স্লাইস চালান।\n\nপ্রোটোটাইপ তাড়াতাড়ি করতে চাইলে আপনি Koder.ai planning mode-এ ইভেন্ট ফ্লো স্কেচ করতে পারেন এবং ডিজাইন ইটারেট করতে পারেন। কারণ Koder.ai সোর্স কোড এক্সপোর্ট, স্ন্যাপশট এবং রোলব্যাক সাপোর্ট করে, এটি একটি ছোট প্রোডিউসার-কনজিউমার স্লাইস পরীক্ষা করে ইভেন্ট শেপ অ্যাডজাস্ট করার নিরাপদ উপায়। একবার স্থিতিশীল হলে কোড এক্সপোর্ট করে যেকোন জায়গায় চালান।সাধারণ প্রশ্ন
শেয়ার