System DesignMastery
--Distributed Systems — ডিস্ট্রিবিউটেড সিস্টেম

Message Queues & Event Streaming

Duration৬০-৯০ মিনিট
LevelIntermediate
FocusAsync Systems
001Core Concept

Message Queue কী?

ধরুন আপনি Swiggy তে খাবার order দিলে। তৎক্ষণাৎ screen এ আসে "Order Confirmed!" — আপনি phone রেখে দিলে। কিন্তু পেছনে কী হচ্ছে? Restaurant কে notification গেলো, delivery partner assign হলো, payment process হলো, invoice তৈরি হলো। এই সব কাজ আপনার জন্য wait করছে না।

এটাই Async Messaging। Sync মানে — আপনি কাজ দিলে, সে শেষ করলেন, তারপর next step। Async মানে — আপনি কাজ দিলে, সে নিজের সময়ে করবেন, আপনি এগিয়ে যান।

SYNC ❌ ব্লকিং

Order দিন → Email পাঠাও (wait) → SMS পাঠাও (wait) → Inventory update (wait) → Response। সব শেষ না হওয়া পর্যন্ত user আটকে।

ASYNC ✅ নন-ব্লকিং

Order দিন → Queue তে message রাখুন → "Order Confirmed!" return। Background এ Email, SMS, Inventory সব parallel হয়।

DEFINITION — Message Queue কী?

  • Message Queue হলো একটা middleware — দুটো service এর মাঝখানে buffer হিসেবে কাজ করে।
  • Producer — message পাঠায় (যে কাজ দেয়)।
  • Queue — message গুলো সংরক্ষণ করে (buffer/storage)।
  • Consumer — queue থেকে message নেয় এবং নিজের গতিতে process করে।
  • Decoupled — Producer আর Consumer একে অপরকে চেনে না, সরাসরি কথা বলে না।
002Why Async?

কেন Async Messaging দরকার?

1. DECOUPLING

Service B down হলেও Service A চলতে পারে। Message queue তে জমা থাকবেন, B উঠলে process করবেন। Services একে অপরের উপর directly depend করে না।

2. TRAFFIC SPIKE BUFFER

হঠাৎ ১০,০০০ order আসলে queue buffer হিসেবে কাজ করে। Consumer নিজের গতিতে process করে। System overload হয় না।

3. RETRY LOGIC

Consumer fail করলেন message queue তে থাকে। Retry করা যায় — data loss নেই। Email service crash হলেও email টা পরে পাঠানো সম্ভব।

4. MICROSERVICES

Microservices architecture এ services loosely coupled থাকে। Queue হলো তাদের communication bridge — directly call না করে message দিয়ে কথা বলে।

Real Example — E-Commerce Order Flow

User checkout করলো → Payment Service payment নিলো → Queue তে order_placed event publish করলো।

Queue থেকে parallel এ চারটা service কাজ শুরু করলো:

  • 📧 Email Service — confirmation email পাঠালো
  • 📱 SMS Service — OTP/update পাঠালো
  • 📦 Inventory Service — stock কমালো
  • 📊 Analytics Service — event log করলো

User কে শুধু Payment Service এর response দরকার। বাকি সব async — user দেখে না, জানে না, অপেক্ষা করে না।

003MQ Patterns

Message Queue Patterns

Pattern 1 — Point-to-Point (Queue Model)

একটা message শুধু একজন consumer পায়। Task queue এর মতো — কেউ একজন কাজটা নিয়ে করে।

Producer─────────►Queue─────────►Consumer A(শুধু একজন পাবেন)
Consumer B, C — পাবেন না

উদাহরণ: Image resize task queue — ১টা worker একটা image নেয়, process করে, next।

Pattern 2 — Publish-Subscribe (Topic / Fan-out)

একটা message সব subscribers পায়। এটা broadcast — একজন বলে, সবাই শোনে।

Producer──►Topic: order_placed
├──►Email Service
├──►SMS Service
└──►Analytics Service

উদাহরণ: Kafka topic — সব Consumer Group independently same message পড়তে পারে।

004Kafka Deep Dive

Apache Kafka — Event Streaming Platform

LinkedIn এ তৈরি, এখন Uber, Netflix, Airbnb সহ হাজারো company ব্যবহার করে। প্রতিদিন trillions of events process করে। Kafka শুধু message queue না — এটা distributed event streaming platform।

Kafka Key Terms — জানতেই হবে

  • Topic— message এর category। যেমন "order_placed", "user_signup"।
  • Partition — Topic কে parallel শাখায় ভাগ করে। বেশি partition = বেশি throughput।
  • Offset — Partition এর প্রতিটা message এর unique index। Consumer এখানে থেকে পড়ে।
  • Producer — Topic এ message লেখে।
  • Consumer Group — একদল consumer মিলে একটা topic process করে। প্রতিটা partition একজন consumer এ যায়।
  • Broker — Kafka server। Cluster এ অনেক broker থাকে।
  • Replication Factor — প্রতিটা partition কতটা broker এ copy থাকবেন (fault tolerance)।

Kafka Architecture

PRODUCERS
Order Service
Payment Service
User Service
──►
KAFKA BROKER
Topic: order_placed [P0][P1][P2]
Topic: payment_done [P0][P1]
──►
CONSUMER GROUPS
Email Group [C1][C2]
Analytics Group [C1][C2][C3]

Kafka's Unique Power — এটাই পার্থক্য

  • Message Replay — পুরনো message আবার পড়া যায়। Consumer নতুন আসলেও পুরো history process করতে পারে।
  • Multiple Consumer Groups — একই topic থেকে Email service আর Analytics service independently পড়তে পারে — একজন আরেকজনকে affect করে না।
  • Durable Storage — Message disk এ থাকে, days/weeks পর্যন্ত। Consumer down থাকলেও data নষ্ট হয় না।
005RabbitMQ

RabbitMQ — Traditional Message Broker

AMQP protocol ব্যবহার করে। Complex routing, explicit acknowledgment, Dead Letter Queue — এগুলো RabbitMQ এর specialty। Push-based model — broker consumer কে message push করে।

RabbitMQ Key Concepts

  • Exchange — Message কোন queue তে যাবেন তা decide করে। Types: Direct, Topic, Fanout, Headers।
  • Queue — Message store করে। Consumer এখান থেকে নেয়।
  • Binding — Exchange আর Queue এর মধ্যে connection rule।
  • ACK (Acknowledgment) — Consumer message সফলভাবে process করলেন broker কে জানায় → broker message delete করে।
  • NACK + DLQ (Dead Letter Queue) — Consumer fail করলেন NACK পাঠায় → বারবার fail হলে message Dead Letter Queue তে যায়।
FeatureKafkaRabbitMQ
ModelEvent Log (Pull-based)Message Queue (Push-based)
Message RetentionDays/weeks — replay সম্ভবACK এর পর delete
ThroughputMillions/secThousands/sec
Message Replayহ্যাঁ ✓না ✗
Complex RoutingTopic/Partition basedExchange types (flexible)
ACK/NACK + DLQOffset commitExplicit ACK/NACK + DLQ
Best ForReal-time streaming, analyticsTask queues, job processing
006Code Examples

Code Examples — হাতে-কলমে দেখুন

Kafka — Python Producer & Consumer

kafka_example.py
from kafka import KafkaProducer, KafkaConsumer
import json

# ── PRODUCER: Order Service ──────────────────────────────────────────────
producer = KafkaProducer(
    bootstrap_servers='localhost:9092',
    value_serializer=lambda v: json.dumps(v).encode('utf-8')
)

def place_order(order_id, user_id, items):
    event = {
        "order_id": order_id,
        "user_id": user_id,
        "items": items,
        "status": "placed"
    }
    # topic: "order_placed" এ message publish করুন
    producer.send('order_placed', value=event)
    producer.flush()
    print(f"✅ Order {order_id} event published to Kafka")

place_order("ORD-001", "USR-42", [{"item": "Biryani", "qty": 2}])


# ── CONSUMER: Email Service ───────────────────────────────────────────────
consumer = KafkaConsumer(
    'order_placed',
    bootstrap_servers='localhost:9092',
    group_id='email-service-group',       # Consumer Group ID
    auto_offset_reset='earliest',
    value_deserializer=lambda m: json.loads(m.decode('utf-8'))
)

print("📧 Email Service listening for order events...")
for message in consumer:
    order = message.value
    print(f"Sending confirmation email for order: {order['order_id']}")
    # send_email(order['user_id'], order['order_id'])
    # offset automatically commit হয় — message processed হলে

RabbitMQ — Node.js Publisher & Worker

rabbitmq_worker.js
const amqp = require('amqplib');

// ── PUBLISHER ────────────────────────────────────────────────────────────
async function publishImageTask(imageUrl) {
  const connection = await amqp.connect('amqp://localhost');
  const channel = await connection.createChannel();

  const queue = 'image_resize';
  await channel.assertQueue(queue, { durable: true }); // queue crash এ survive করে

  const task = JSON.stringify({ imageUrl, width: 800, height: 600 });
  channel.sendToQueue(queue, Buffer.from(task), { persistent: true });

  console.log("📤 Task queued:", imageUrl);
  await channel.close();
  await connection.close();
}

publishImageTask('https://cdn.example.com/photo-001.jpg');


// ── WORKER (Consumer) ─────────────────────────────────────────────────────
async function startWorker() {
  const connection = await amqp.connect('amqp://localhost');
  const channel = await connection.createChannel();

  const queue = 'image_resize';
  await channel.assertQueue(queue, { durable: true });
  channel.prefetch(1); // একটা message process শেষ না হলে পরেরটা নেবে না

  console.log("🔧 Worker listening for image tasks...");

  channel.consume(queue, async (msg) => {
    const task = JSON.parse(msg.content.toString());

    try {
      console.log(`Processing: ${task.imageUrl}`);
      await resizeImage(task.imageUrl, task.width, task.height); // actual work
      channel.ack(msg);          // ✅ সফল → broker কে জানাও, message delete হবে
      console.log("✅ Image processed successfully");
    } catch (error) {
      console.error("❌ Failed:", error.message);
      channel.nack(msg, false, false); // ❌ fail → requeue: false → DLQ তে যাবেন
    }
  });
}

startWorker();

Dead Letter Queue Setup

dlq_setup.js
const amqp = require('amqplib');

async function setupDLQ() {
  const connection = await amqp.connect('amqp://localhost');
  const channel = await connection.createChannel();

  // 1. Dead Letter Exchange তৈরি করুন
  await channel.assertExchange('dlx_exchange', 'direct', { durable: true });

  // 2. Dead Letter Queue তৈরি করুন
  await channel.assertQueue('dead_letter_queue', { durable: true });
  await channel.bindQueue('dead_letter_queue', 'dlx_exchange', 'failed');

  // 3. Main queue — DLX config সহ
  await channel.assertQueue('image_resize', {
    durable: true,
    arguments: {
      'x-dead-letter-exchange': 'dlx_exchange',  // fail হলে এখানে যাবেন
      'x-dead-letter-routing-key': 'failed',
      'x-message-ttl': 30000,                    // 30 sec এর মধ্যে process না হলে DLQ
    }
  });

  console.log("✅ DLQ setup complete");
  // এখন যেকোনো nack(msg, false, false) → dlx_exchange → dead_letter_queue
  await connection.close();
}

setupDLQ();
007Full Comparison

Kafka vs RabbitMQ vs AWS SQS — কোনটা কখন?

ToolBest ForThroughputComplexityManaged?
Apache KafkaReal-time analytics, event streamingMillions/secHighSelf-hosted / Confluent Cloud
RabbitMQTask queues, complex routingThousands/secMediumSelf-hosted
AWS SQSSimple task queue, decouplingHighLowFully managed ✓
AWS SNSPub/Sub fan-out notificationsHighLowFully managed ✓
Redis StreamsLightweight streaming, low latencyHighLowSelf-hosted

Quick Decision Guide

  • Kafka বেছে নাও যখন — real-time analytics, event replay দরকার, millions of events/sec, multiple teams same data consume করবেন।
  • RabbitMQ বেছে নাও যখন — complex routing logic, task queue, ACK/retry behavior দরকার, throughput কম কিন্তু reliability বেশি।
  • AWS SQS বেছে নাও যখন — AWS already ব্যবহার করছো, simple decoupling দরকার, infrastructure manage করতে চাও না।
  • Redis Streams বেছে নাও যখন — already Redis আছে, lightweight streaming, low latency দরকার।
008Interview Prep

Interview Prep — এই প্রশ্নগুলো আসবেনই

Q1: Kafka At-Least-Once vs Exactly-Once Delivery কী?

  • At-Least-Once — Message কমপক্ষে একবার deliver হবে। Consumer crash করে re-process করলেন duplicate হতে পারে। Default behavior।
  • At-Most-Once — Message হয়তো পাবেন, হয়তো পাবেন না। Data loss সম্ভব।
  • Exactly-Once — Message exactly একবার deliver হবে। Idempotent producer + transactional consumer দিয়ে achieve করা যায়। Performance overhead আছে।
  • Interview answer: "Production এ আমি at-least-once ব্যবহার করি এবং consumer কে idempotent বানাই — duplicate message আসলেও same result হয়।"

Q2: Kafka Partition কীভাবে Throughput বাড়ায়?

  • একটা Topic কে N টা Partition এ ভাগ করলেন N টা Consumer Group member parallel এ পড়তে পারে।
  • Partition = Parallelism unit। 10 partition → 10 consumer same topic এ parallel কাজ করতে পারে।
  • Key-based partitioning — same order_id এর সব event একই partition এ → ordering guarantee।
  • Rule: Consumer Group এ Consumer সংখ্যা ≤ Partition সংখ্যা। বেশি consumer থাকলে idle থাকবেন।

Q3: Message Queue vs Direct API Call — কখন কোনটা?

Direct API Call ব্যবহার করুন যখন:
  • — Immediate response দরকার (payment confirmation)
  • — Strong consistency দরকার
  • — Simple request-response pattern
Message Queue ব্যবহার করুন যখন:
  • — Result immediately দরকার নেই (email, notification)
  • — Service গুলো independent থাকুক
  • — Traffic spike handle করতে হবে
  • — Retry/fault tolerance দরকার

Q4: Dead Letter Queue কী কাজ করে?

  • যে message বারবার process করতে গিয়ে fail হয় — সেটা main queue থেকে সরিয়ে Dead Letter Queue (DLQ) তে রাখা হয়।
  • DLQ তে message থাকলে engineer manually investigate করতে পারে — কেন fail হলো।
  • "Poison message" problem সলভ করে — একটা bad message পুরো queue আটকে না রাখে।
  • Real use case: Invalid payment data → 3 বার retry → DLQ → Alert → Manual fix → Reprocess।
009Lesson Summary

SUMMARY — আজকে যা শিখলাম

Conceptএক লাইনে
Message QueueServices এর মাঝখানে async buffer — decoupling এর হাতিয়ার
Point-to-Pointএকটা message শুধু একজন consumer পায় — task queue
Pub/Subএকটা message সব subscribers পায় — broadcast / fan-out
KafkaEvent streaming, replay সম্ভব, millions/sec, multiple Consumer Groups
RabbitMQTraditional broker, complex routing, ACK/NACK, DLQ support
Dead Letter QueueRepeatedly fail message আলাদা রাখে — investigate করা যায়
Consumer GroupMultiple consumers coordinate করে একটা topic parallel process করে
010Knowledge Check
011Assignments
012Practical Lab