System Design শেখো
সব কেস স্টাডি

Distributed Message Queue (Kafka) ডিজাইন

12 মিনিটadvanced
এক নজরে
  • Kafka হলো একটি distributed, append-only commit log যেখানে message গুলো topic এবং partition-এ সাজানো থাকে।
  • প্রতিটি partition-এর leader/follower replication থাকে, আর ordering শুধু একটি partition-এর ভেতরেই নিশ্চিত হয়।
  • Consumer group, offset commit এবং retention মিলে at-least-once delivery দেয় বিশাল throughput-এ।

ধরো তোমাদের কোম্পানিতে একটা e-commerce platform আছে — order, payment, notification, analytics সব আলাদা service। এখন প্রশ্ন হলো, একটা order হলে এই সব service-কে কীভাবে জানাবে? সরাসরি একে অন্যকে কল করলে coupling বাড়ে, একটা service down হলে পুরো চেইন ভাঙে। এই জায়গায় আসে message queue — আর scale-এ সবচেয়ে জনপ্রিয় হলো Kafka। চলো এটা ধাপে ধাপে ডিজাইন করি।

১. সমস্যা বোঝা (Requirements)

আগে ঠিক করি আমরা কী বানাচ্ছি।

Functional requirements:

  • Producer message publish করবে একটা topic-এ।
  • Consumer সেই topic থেকে message subscribe করে পড়বে।
  • একই message একাধিক consumer group পড়তে পারবে (যেমন analytics আর notification আলাদা আলাদা পড়বে)।
  • Message কিছু সময় retain থাকবে, পড়া হয়ে গেলেও সঙ্গে সঙ্গে মুছবে না।
  • একটা logical key-এর সব message order বজায় রাখবে।

Non-functional requirements:

  • High throughput — সেকেন্ডে লক্ষ লক্ষ message।
  • Durability — broker crash করলেও message হারাবে না।
  • Horizontal scalability — node যোগ করলেই capacity বাড়বে।
  • Low latency — কয়েক millisecond-এর মধ্যে delivery।
সহজ উদাহরণ

Kafka-কে ভাবো একটা সংবাদপত্রের পত্রিকা হিসেবে। Producer হলো সাংবাদিক যারা খবর (message) লেখে, topic হলো একটা নির্দিষ্ট পত্রিকা (যেমন "খেলার পাতা"), আর consumer হলো পাঠক। মজার ব্যাপার — পত্রিকা পড়লেও সেটা মুছে যায় না, একই কপি অনেকে পড়তে পারে, আর প্রত্যেক পাঠক নিজের bookmark (offset) রাখে কোন পেজ পর্যন্ত পড়েছে।

২. স্কেল আন্দাজ (Estimation)

ধরি: 1 million message/second peak
গড় message size: 1 KB
=> ingest throughput = 1,000,000 * 1 KB = 1 GB/second

Retention: 7 দিন
দৈনিক data = 1 GB/s * 86,400 s = ~86 TB/day
7 দিনে = ~600 TB

Replication factor 3 ধরলে disk প্রয়োজন:
600 TB * 3 = ~1.8 PB

Partition planning:
একটি partition ~10 MB/s handle করলে,
1 GB/s ingest-এর জন্য দরকার ~100 partition (নিরাপত্তার জন্য 200+)

মূল শিক্ষা: এই scale একটা single machine-এ অসম্ভব। তাই data কে ভাগ করতেই হবে — সেটাই partition।

৩. API ডিজাইন

# Producer
produce(topic, key, value, headers) -> {partition, offset}
  - key থাকলে hash(key) % numPartitions দিয়ে partition নির্ধারণ
  - key না থাকলে round-robin / sticky partitioner

# Consumer
subscribe(topics[], groupId)
poll(timeoutMs) -> [records]   # batch of records
commitSync(offsets)            # offset persist করা
seek(topic, partition, offset) # নির্দিষ্ট offset-এ যাওয়া

# Admin
createTopic(name, numPartitions, replicationFactor)
describeTopic(name) -> partitions, leaders, ISR

লক্ষ্য করো — produce-এর response-এ partition আর offset ফেরত আসে। এই দুটো মিলেই একটা message-এর unique ঠিকানা।

৪. ডেটা মডেল

একটা topic হলো কয়েকটা partition-এর সমষ্টি। প্রতিটি partition একটা ordered, immutable, append-only log। নিচে মূল entity:

Entityমূল fieldবর্ণনা
Topicname, numPartitions, replicationFactorlogical channel
PartitionpartitionId, leaderBroker, replicas[], ISR[]parallelism + ordering unit
Recordoffset, key, value, timestamp, headersএকটি message
ConsumerGroupOffsetgroupId, topic, partition, offsetকোন group কতদূর পড়েছে

Storage choice: Kafka নিজে disk-এ segment file হিসেবে log রাখে (sequential write)। কেন disk? কারণ sequential disk write আসলে random memory access-এর চেয়েও fast হতে পারে, আর OS page cache পড়ার সময় কাজে লাগে। Offset তাই কোনো DB নয় — এটা log-এর ভেতর position।

মনে রাখার মতো: Kafka message কে database row হিসেবে নয়, log entry হিসেবে treat করে। তাই random update নেই, শুধু append আছে।

৫. হাই-লেভেল ডিজাইন

মূল components:

  • Producer client — partition নির্বাচন, batching, compression করে broker-এ পাঠায়।
  • Broker — partition leader/follower host করে, disk-এ log লেখে, consumer-কে serve করে।
  • Controller / Metadata layer — কোন partition-এর leader কে, কে cluster-এ আছে — এসব track করে (পুরোনো Kafka-তে ZooKeeper, নতুন version-এ KRaft)।
  • Consumer group coordinator — group-এর consumer গুলোর মধ্যে partition assign (rebalance) করে।

Flow (একটা message-এর জীবন):

  1. Producer key দিয়ে hash করে partition বের করে।
  2. সেই partition-এর leader broker-এ message পাঠায়।
  3. Leader নিজের log-এ append করে, তারপর follower-রা replicate করে।
  4. যথেষ্ট replica (acks অনুযায়ী) লিখলে producer-কে ack দেয়।
  5. Consumer group-এর একটা consumer সেই partition assign পায়, poll() করে batch নেয়।
  6. প্রক্রিয়া শেষে consumer offset commit করে — পরের poll এর পর থেকে শুরু হবে।

৬. গভীরে (Deep Dive)

ক. Partition ও Ordering

Partition হলো Kafka-র parallelism-এর একক। একটা topic-এ যত partition, তত বেশি consumer parallel-এ পড়তে পারে। কিন্তু trade-off: ordering শুধু একটা partition-এর ভেতরেই গ্যারান্টিড। তাই যে message গুলোর order জরুরি (যেমন এক user-এর সব event), সেগুলোকে একই key দিয়ে পাঠাতে হবে যাতে একই partition-এ যায়।

hash("user_42") % 100 = 37  -> সবসময় partition 37
=> user_42-এর সব event order বজায় থাকবে

খ. Replication (Leader/Follower per partition)

প্রতিটি partition-এর একটা leader আর কয়েকটা follower থাকে আলাদা broker-এ। সব read/write leader দিয়ে যায়; follower শুধু leader থেকে copy করে। যে follower গুলো leader-এর কাছাকাছি sync থাকে তাদের বলে ISR (In-Sync Replicas)

  • Leader crash করলে controller ISR থেকে নতুন leader নির্বাচন করে।
  • acks=all দিলে producer তখনই ack পায় যখন সব ISR লিখে ফেলে — সবচেয়ে durable কিন্তু একটু slow।
  • acks=1 দিলে শুধু leader লিখলেই ack — fast কিন্তু leader crash হলে data loss সম্ভব।
সাবধান

acks=1 ব্যবহার করলে leader ack দেওয়ার পর কিন্তু follower replicate করার আগেই leader crash করলে সেই message হারিয়ে যাবে। Durability জরুরি হলে acks=all আর min.insync.replicas=2 সেট করো।

গ. Offset ও Delivery Guarantee

Consumer প্রতিটি partition-এ নিজের offset রাখে — কতদূর পড়েছে। এই offset একটা special internal topic (__consumer_offsets)-এ commit হয়।

  • যদি আগে process, পরে commit করো → at-least-once (process-এর পর crash হলে redelivery, কিন্তু hারায় না)। এটাই default এবং সবচেয়ে ব্যবহৃত।
  • যদি আগে commit, পরে process করো → at-most-once (process-এর আগে crash হলে message হারাতে পারে)।
  • Exactly-once দরকার হলে Kafka-র idempotent producer + transactions ব্যবহার করতে হয়, যা read-process-write cycle কে atomic করে।

যেহেতু at-least-once-এ duplicate আসতে পারে, consumer-কে idempotent বানানো ভালো — যেমন message-এর (partition, offset) বা business key দেখে duplicate skip করা।

৭. বটলনেক ও স্কেলিং

  • Hot partition: কোনো একটা key যদি অসম্ভব জনপ্রিয় হয় (যেমন এক বিশাল seller-এর সব order), সেই partition overloaded হবে। সমাধান — key-তে suffix যোগ করে spread করা, অথবা partition সংখ্যা সঠিকভাবে পরিকল্পনা করা।
  • Consumer lag: Producer-এর গতি consumer-এর চেয়ে বেশি হলে lag বাড়ে। Monitor করো consumer lag metric, দরকারে group-এ consumer যোগ করো (তবে partition সংখ্যার বেশি consumer যোগ করে লাভ নেই — extra consumer idle থাকবে)।
  • Rebalance storm: Consumer যোগ/বাদ হলে rebalance হয়, এ সময় consumption থামে। Cooperative/sticky rebalancing দিয়ে এর প্রভাব কমানো যায়।
  • Disk I/O: Retention বেশি হলে disk দ্রুত ভরে। Time-based বা size-based retention আর compression (snappy/zstd) দিয়ে নিয়ন্ত্রণ করো।
  • Partition বাড়ানো: পরে partition বাড়ানো যায় কিন্তু এতে key-to-partition mapping বদলে যায়, ফলে ordering গ্যারান্টি ভাঙতে পারে। তাই শুরুতেই উদার partition planning ভালো।

৮. সারসংক্ষেপ

Kafka মূলত একটা distributed append-only log। Topic কে partition-এ ভাগ করে throughput পাওয়া যায়, প্রতিটি partition-এর leader/follower replication দিয়ে durability পাওয়া যায়, আর offset-based consumption দিয়ে একই data বহু consumer group স্বাধীনভাবে পড়তে পারে। মূল trade-off গুলো মনে রাখো — ordering বনাম parallelism (partition), latency বনাম durability (acks), আর simplicity বনাম exactly-once (transactions)।

টিপস

Interview-এ Kafka design করলে প্রথমেই partition আর key-এর সম্পর্ক স্পষ্ট করো — এটাই ordering, parallelism আর hot-spot সব সমস্যার কেন্দ্রবিন্দু। তারপর acks দিয়ে durability trade-off, আর offset commit দিয়ে delivery semantics বুঝিয়ে দিলে interviewer খুশি।

মিনি কুইজ

1. Kafka-তে message ordering কোন স্কোপে গ্যারান্টিড?

2. একটি consumer group-এ একই partition একসাথে কয়টি consumer পড়তে পারে?

3. Default-ভাবে Kafka কোন delivery guarantee দেয়?