System Design শেখো
শেখো / আর্কিটেকচারাল প্যাটার্ন

Event-Driven Architecture

11 মিনিট Module 3 · Patterns
এক নজরে
  • Event-Driven Architecture-এ সিস্টেমের অংশগুলো সরাসরি একে অপরকে না ডেকে event ছেড়ে দেয় ও পড়ে নেয়।
  • Producer event তৈরি করে, broker/event bus সেটা বিলি করে, আর consumer সেটা শুনে কাজ করে — pub/sub মডেল।
  • এটা দারুণ decoupling ও scalability দেয়, কিন্তু eventual consistency ও debugging-এর জটিলতা আনে।

সমস্যাটা কী?

একটা e-commerce অর্ডারের কথা ভাবো। কেউ অর্ডার করল। এখন একসাথে অনেক কিছু ঘটতে হবে: payment কাটতে হবে, inventory কমাতে হবে, ক্রেতাকে confirmation email পাঠাতে হবে, courier-কে জানাতে হবে, loyalty point যোগ করতে হবে।

যদি Order service সরাসরি এই ৫টা সেবাকে একে একে ডাকে, তাহলে সমস্যা: Order service-কে সবার ঠিকানা জানতে হবে, যেকোনো একটা slow হলে পুরো অর্ডার আটকে যাবে, আর নতুন কোনো কাজ যোগ করতে চাইলে (যেমন "fraud check") Order service-এর কোড আবার বদলাতে হবে। সবাই সবার সাথে শক্তভাবে জড়িয়ে যায় — একে বলে tight coupling।

Event-Driven Architecture এই জট খুলে দেয়।

মূল ধারণা

Event-Driven Architecture (EDA) এমন একটা ডিজাইন যেখানে সিস্টেমের অংশগুলো সরাসরি একে অপরকে না ডেকে "ঘটনা" (event) প্রকাশ করে ও সেগুলোর জবাবে react করে। একটা Event হলো "কিছু একটা ঘটেছে"-র একটা অপরিবর্তনীয় রেকর্ড, যেমন OrderPlaced

মূল ভাবনা: Order service শুধু চিৎকার করে বলবে "একটা অর্ডার হয়েছে!" — কে শুনবে, কে কী করবে, তা নিয়ে সে মাথা ঘামায় না। যাদের দরকার তারা শুনে নেবে।

দুটো ভূমিকা: Producer/Consumer — Producer (বা publisher) event তৈরি করে, Consumer (বা subscriber) সেটা পড়ে কাজ করে। মাঝখানে দাঁড়িয়ে event বিলি করে একটা Event Broker (যেমন Kafka, RabbitMQ)।

কীভাবে কাজ করে

Pub/Sub মডেল

সবচেয়ে প্রচলিত প্যাটার্ন হলো Pub/Sub (publish-subscribe):

  1. Producer একটা event publish করে broker-এর একটা "topic"-এ।
  2. যারা ওই topic-এ subscribe করেছে, broker সবাইকে সেই event পৌঁছে দেয়।
  3. প্রতিটি consumer স্বাধীনভাবে নিজের কাজ করে।

Producer জানেই না কে শুনছে — এটাই এর সৌন্দর্য।

Choreography বনাম Orchestration

দিকChoreographyOrchestration
নিয়ন্ত্রণবিকেন্দ্রীভূত, কেন্দ্র নেইএকটা কেন্দ্রীয় coordinator
সেবা কীভাবে জানেevent দেখে নিজে react করেcoordinator নির্দেশ দেয়
Couplingসবচেয়ে কমএকটু বেশি
Flow বোঝাকঠিন (ছড়ানো)সহজ (এক জায়গায় দেখা যায়)

Choreography-তে প্রতিটি সেবা event শুনে নিজে সিদ্ধান্ত নেয়। Orchestration-এ একজন "কন্ডাক্টর" সবাইকে বলে দেয় কখন কী করতে হবে।

Eventual Consistency

Event async-ভাবে ছড়ায়, তাই সব জায়গায় data এক হতে একটু সময় লাগে। একে বলে Eventual Consistency — মুহূর্তের জন্য inventory আর order count আলাদা থাকতে পারে, কিন্তু কিছুক্ষণ পরে মিলে যায়।

ধাপOrder DBInventory DB
t=0 অর্ডার হলো১টি অর্ডারএখনো পুরনো stock
t=200ms event পৌঁছাল১টি অর্ডারstock কমল
সহজ উদাহরণ

বিয়ের অনুষ্ঠানের কথা ভাবো। বরের গাড়ি গেটে পৌঁছাল — এটা একটা event। এখন কেউ আলাদা করে ফটোগ্রাফার, বাবুর্চি, গায়ককে একে একে ফোন করে না। বরং একজন "বর এসে গেছে!" বলে ঘোষণা দেয় (publish), আর যার যার কাজ সে শুরু করে দেয় — ফটোগ্রাফার ছবি তোলে, বাবুর্চি খাবার সাজায়, গায়ক গান ধরে (subscribers react)। ঘোষণাকারী জানেই না কে কী করছে। এটাই choreography। আর যদি একজন "অনুষ্ঠান পরিচালক" মাইকে এক এক করে নির্দেশ দেন, সেটা orchestration।

সুবিধা ও অসুবিধা

সুবিধা:

  • Loose coupling: producer ও consumer একে অপরকে চেনে না, তাই স্বাধীনভাবে বদলানো যায়।
  • সহজে সম্প্রসারণ: নতুন consumer যোগ করতে শুধু subscribe করলেই হয়, পুরনো কোড ছুঁতে হয় না।
  • Scalability ও resilience: broker buffer হিসেবে কাজ করে; এক consumer ডাউন থাকলেও event জমা থাকে।
  • Responsiveness: producer উত্তরের জন্য অপেক্ষা না করে এগিয়ে যায়।

অসুবিধা:

  • Eventual consistency: তাৎক্ষণিক সঠিক data দরকার এমন জায়গায় কঠিন।
  • Debugging কঠিন: একটা request-এর পথ অনেক সেবায় ছড়িয়ে পড়ে; tracing দরকার।
  • Event এর নকল/ক্রম: একই event দুবার আসতে পারে; idempotency নিশ্চিত করতে হয়।
  • Broker একটা গুরুত্বপূর্ণ অংশ: এটা ডাউন হলে বড় ক্ষতি — high availability দরকার।

কখন ব্যবহার করবে / করবে না

ব্যবহার করবে যখন: একটা ঘটনার জবাবে অনেকগুলো স্বাধীন কাজ করতে হয়, সেবাগুলোকে আলাদা করে scale করতে হয়, কিংবা real-time data stream (যেমন user activity tracking) সামলাতে হয়।

এড়িয়ে যাবে যখন: সরল request/response-ই যথেষ্ট, কিংবা তীব্রভাবে strong consistency দরকার (যেমন ব্যাংকের ব্যালেন্স তাৎক্ষণিক মেলা)।

সাবধান

সবচেয়ে কমন বাগ: consumer ধরে নেয় প্রতিটি event ঠিক একবারই আসবে। বাস্তবে broker প্রায়ই "at-least-once" delivery দেয় — মানে একই event দুবার আসতে পারে। তাই প্রতিটি consumer-কে idempotent বানাও — একই event দুবার এলেও যেন ফল একই থাকে (যেমন একই অর্ডারে দুবার payment না কাটে)। এটা না করলে duplicate charge-এর মতো ভয়ংকর বাগ হবে।

বাস্তব উদাহরণ

Uber এর পুরো সিস্টেম event-driven। তুমি যখন একটা রাইড চাও, একটা RideRequested event তৈরি হয়। এই একটা event-এর জবাবে: ম্যাচিং সেবা কাছের ড্রাইভার খোঁজে, pricing সেবা surge দাম হিসাব করে, ETA সেবা সময় হিসাব করে, notification সেবা ড্রাইভারকে জানায় — সবাই একসাথে, স্বাধীনভাবে। তারা Apache Kafka-তে দিনে কোটি কোটি event প্রসেস করে।

এতে নতুন কোনো ফিচার (যেমন "fraud detection") যোগ করতে চাইলে তারা শুধু একটা নতুন consumer বানিয়ে ওই event-এ subscribe করে — মূল রাইড flow-এর কোডে হাত দিতে হয় না।

টিপস

ইন্টারভিউতে EDA নিয়ে আলোচনায় "consistency" শব্দটা নিজে থেকে তোলো। বলো: "এখানে আমরা strong consistency ছেড়ে eventual consistency নিচ্ছি — বিনিময়ে পাচ্ছি scalability ও decoupling।" এই সচেতন trade-off দেখাতে পারলে তুমি কেবল প্যাটার্ন মুখস্থ করোনি, এর দাম বোঝো — সেটাই প্রমাণ হয়।

মিনি কুইজ

1. Event-Driven Architecture-এ producer-এর কাজ কী?

2. Choreography ও orchestration-এর মূল পার্থক্য কী?

3. Eventual consistency মানে কী?