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

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 সোর্স কোড এক্সপোর্ট, স্ন্যাপশট এবং রোলব্যাক সাপোর্ট করে, এটি একটি ছোট প্রোডিউসার-কনজিউমার স্লাইস পরীক্ষা করে ইভেন্ট শেপ অ্যাডজাস্ট করার নিরাপদ উপায়। একবার স্থিতিশীল হলে কোড এক্সপোর্ট করে যেকোন জায়গায় চালান।একটি কিউ হচ্ছে সেই কাজের টিকিটগুলোর জন্য উপযুক্ত যা আপনি সম্পন্ন করে ভুলে যেতে চান (ইমেইল পাঠানো, ছবি রিসাইজ করা, কোনো ব্যাচ জব চালানো)। একটি লগ হলো সেই তথ্যের জন্য উপযুক্ত যা আপনি রেকর্ড হিসেবে রাখতে চান এবং যেকোনো সময় বহু সিস্টেম পড়তে ও পুনরায় প্লে করতে পারে (OrderPlaced, PaymentAuthorized, RefundIssued)।
আপনি সেটি অনুভব করবেন যখন প্রতিটি নতুন ফিচারের জন্য বহু ইন্টিগ্রেশন স্পর্শ করতে হয়, এবং ডিবাগ করা হয়ে যায় “এই মানটা কে লিখেছে?”—কোনো পরিষ্কার টাইমলাইন ছাড়া। একটি লগ সহ একটি শেয়ার্ড রেকর্ড থাকে যা আপনি পরীক্ষা ও পুনরায়-প্লে করতে পারেন, ফলে ছড়িয়ে থাকা ডাটাবেস স্টেট থেকে অনুমান করতে হয় না।
যখন আপনাকে আডিট ট্রেইল ও রেপ্লে প্রয়োজন হয়: বাগ ঠিক করার জন্য ইতিহাস পুনরায় প্রসেস করা, পুরোনো ডেটা থেকে নতুন ফিচার ব্যাকফিল করা, বা “সেটার সময় আমরা কী জানতাম?” জাতীয় তদন্ত চালানো। এছাড়া যখন একই ইভেন্টের বহুমুখী কনজিউমার (billing, analytics, support, fraud) দরকার পড়ে এবং প্রোডিউসারকে বারবার বদলাতে না চাওয়া হয়।
কারণ সিস্টেম বড় হতে থাকে এবং রিট্রাই, টাইমআউট, আংশিক আউটেজ ও ম্যানুয়াল ফিক্স হয়ে থাকে। যদি প্রতিটি সেবা সরাসরি অন্যকে আপডেট করে, তারা একে অপরের থেকে আলাদা কাহিনী পেতে পারে। একটি অ্যাপেন্ড-ওনলি ইভেন্ট ইতিহাস আপনাকে এক অর্ডার্ড সিকোয়েন্স দেয় যার ওপর থেকে তর্ক করা যায়, এমনকি কিছু কনজিউমার ডাউন ছিলেও পরে আপডেট নিতে পারে।
ইভেন্টগুলোকে অম্যুটেবল ফ্যাক্ট হিসেবে মডেল করুন (ভূতকালে বলা) যা ইতিমধ্যে ঘটে গেছে:\n\n- OrderPlaced, ProcessOrder নয়\n- PaymentAuthorized, ChargeCardNow নয়\n- UserEmailChanged, UpdateEmail নয়\n\nযদি পরে কিছু বদলে যায়, পুরনোটি এডিট করার বদলে একটি নতুন ইভেন্ট প্রকাশ করুন যা নতুন সত্য প্রকাশ করে।
ধরুন ডুপ্লিকেট হতে পারে (at-least-once delivery সাধারণ)। প্রতিটি কনজিউমারকে রিট্রাই-সেফ করে তুলুন:\n\n- একটি স্থির ইভেন্ট ID ব্যবহার করুন এবং “ইতিমধ্যেই প্রক্রিয়াকৃত” মার্কার সংরক্ষণ করুন\n- যেখানে সম্ভব ইউনিক কনস্ট্রেইন্ট ব্যবহার করুন\n- একই ইভেন্ট দু'বার প্রয়োগ করে দ্বিগুণ পার্শ্বপ্রতিক্রিয়া (যেমন দ্বিগুণ চার্জ) না হয় তা ডিজাইন করুন\n\nডিফল্ট নিয়ম: সঠিকতা আগে, গতি পরে।
অ্যাডিটিভ পরিবর্তনগুলোই ভালো: পুরনো ফিল্ড রাখুন, নতুন ফিল্ড যোগ করুন (ঐচ্ছিক), এবং এমনভাবে নাম বদলান/মুছুন না যা বিদ্যমান কনজিউমারকে ভেঙে দেবে। যদি ব্রেকিং পরিবর্তন অবধারিত হয়, ইভেন্ট (বা টপিক) ভার্সন করুন এবং কনজিউমারগুলো ইচ্ছাকৃতভাবে মাইগ্রেট করুন—সোজা JSON আপডেট নয়।
একটি পাতলা, end-to-end স্লাইস দিয়ে শুরু করুন:\n\n1. একটি ব্যবসায়িক ফ্লো বেছে নিন (উদাহরণ: OrderPlaced → email receipt).\n2. স্পষ্ট ইভেন্ট নাম ও প্রয়োজনীয় ফিল্ড নির্ধারণ করুন।\n3. অর্ডারিং কী বেছে নিন (orderId বা userId সাধারণ)।\n4. কনজিউমারকে idempotent করুন।\n5. টেস্ট করার জন্য রিটেনশন এত দীর্ঘ রাখুন যাতে রেপ্লে করা যায়।\n\nলুপটি কাজ করছে কিনা প্রমাণ করে তারপর বাকিটা বাড়ান।
না। বর্তমান স্টেটের জন্য ডাটাবেস রাখুন এবং ট্রানজেকশনাল নিয়ম। ইভেন্ট লগ ইতিহাসের জন্য এবং ডেরাইভড ভিউ (analytics টেবিল, সার্চ ইন্ডেক্স, টাইমলাইন) পুনর্নির্মাণের জন্য। সহজভাবে: DB হলো ‘এখন কী সত্য’, লগ হলো পরিবর্তনের রেকর্ড।
Planning mode প্রকাশক/কনজিউমার ম্যাপ করতে, ইভেন্ট নাম নির্ধারণ করতে এবং idempotency ও retention ঠিক করতে কাজে আসে; তারপর আপনি একটি ছোট প্রোডিউসার-কনজিউমার স্লাইস তৈরি করে স্ন্যাপশট, রোলব্যাক দিয়ে পরীক্ষা করতে পারেন। স্থিতিশীল হলে সোর্স কোড এক্সপোর্ট করে ডিপ্লয় করুন।