Distributed Consensus & Coordination
Distributed Consensus কেন শিখতে হবে?
৩টা server আছে — Server A, B, C। সবাই একই data রাখে। কিন্তু হঠাৎ network problem — A এবং B একটা value দেখছে, C আরেকটা। এখন কোনটা সত্য? কে decide করবেন?
এই সমস্যার নাম Distributed Consensus Problem। Multiple nodes কীভাবে একটা single agreed value তে পৌঁছাবে — এটাই consensus। Kubernetes, etcd, Kafka, CockroachDB — সব জায়গায় এটা ব্যবহার হয়।
DEFINITION
Distributed Consensus হলো একটা process যেখানে একটা distributed system এর সব nodes একটা single value বা decision এ agree করে — এমনকি যখন কিছু nodes fail করে বা network partition হয়।
সমস্যাটা কী?
ধরুন আপনি একটা bank এ কাজ করুন। Account balance হলো ১০,০০০ টাকা। ৩টা server এই data replicate করে রাখে। এখন একসাথে দুটো transaction আসলো:
❌ Without Consensus
TX1: Debit ৫,০০০ → Server A
TX2: Debit ৮,০০০ → Server B
উভয় approve হলো! Balance হলো -৩,০০০! 💸
✅ With Consensus
TX1 এবং TX2 একটা order এ agree করতে হবে। একটা process হবে, তারপর অন্যটা। Overdraft impossible।
Byzantine Generals Problem
Distributed Consensus এর classic problem। কয়েকজন general একটা city attack করবেন — সবাইকে একসাথে attack বা retreat করতে হবে। কিন্তু messenger unreliable, কিছু general traitor হতে পারে। কীভাবে সবাই agree করবেন?
THE TWO KEY CHALLENGES
2. Consistency: সব nodes একই data দেখবেন একই সময়ে।
CAP Theorem মনে আছে? Distributed system এ Consistency এবং Availability দুটো একসাথে fully পানয়া যায় না। Consensus algorithms এই trade-off manage করে।
QUORUM: Majority Wins
QUORUM FORMULA
Quorum = (N / 2) + 1
৩ nodes → need 2/3 to agree
৫ nodes → need 3/5 to agree
TOLERABLE FAILURES
Formula: N = 2f + 1
f = tolerable failures
৩ nodes → ১টা fail করলেনও চলবে
Raft — Understandable Consensus
Paxos (পুরনো algorithm) বোঝা খুব কঠিন ছিল। ২০১৪ সালে Stanford এর Diego Ongaro এবং John Ousterhout Raft design করলেনন — same guarantees, কিন্তু অনেক বেশি understandable।
Raft এর তিনটা Core Concept
👑 Leader Election
Cluster এ একটাই Leader থাকে। Leader সব writes handle করে। Leader fail করলেন নতুন election হয়।
📋 Log Replication
Leader সব entries তার log এ লেখে। তারপর Followers কে replicate করে। Majority acknowledge করলেনই committed।
🔒 Safety
Committed entries কখনো lost হয় না। New leader এর কাছে সব committed entries থাকবেনই। Strong guarantee।
⏰ Term
Raft logical time "Term" ব্যবহার করে। প্রতিটা election নতুন term শুরু করে। Stale leader detect করতে term ব্যবহার হয়।
Leader Election Process
FOLLOWER
Heartbeat timeout expired → election শুরু করে
CANDIDATE
নিজেকে vote দেয় এবং অন্য nodes এর কাছে vote request পাঠায়
MAJORITY VOTE
2/3 nodes "YES" বললে quorum reached — decision confirmed
LEADER 👑
Heartbeat পাঠায় followers কে। সব writes handle করে।
HEARTBEAT MECHANISM
Apache ZooKeeper — Coordination Service
ZooKeeper হলো Apache এর একটা distributed coordination service। এটা নিজে Zab (ZooKeeper Atomic Broadcast) protocol ব্যবহার করে — Raft এর মতোই একটা consensus algorithm।
ZooKeeper কী কী করে?
🔐 Distributed Locking
Multiple servers এর মধ্যে lock coordinate করুন। একটাই server কোনো resource access করবেন।
📋 Configuration Management
সব services এর config ZooKeeper এ রাখুন। Config change হলে সব services automatically update পাবেন।
🏃 Leader Election
Kafka, HBase তাদের leader election ZooKeeper দিয়ে করে (পুরনো version)।
📡 Service Registry
Services তাদের health status ZooKeeper এ register করে। Service down হলে automatically remove।
ZOOKEEPER VS ETCD VS CONSUL
etcd: Kubernetes এর brain। Raft ব্যবহার করে। Simple key-value store। Modern choice।
Consul: Service discovery + health checking + KV store। HashiCorp এর product।
| Feature | ZooKeeper | etcd | Consul |
|---|---|---|---|
| Algorithm | Zab (Paxos-like) | Raft | Raft |
| Language | Java | Go | Go |
| Use in | Kafka (old), HBase | Kubernetes | HashiCorp stack |
| Complexity | High | Low | Medium |
| Watch/Events | Yes | Yes | Yes |
| Production 2024 | Legacy | Preferred | Preferred |
Practical Code
Python: Raft Concept Simulation
import random
import time
from enum import Enum
class NodeState(Enum):
FOLLOWER = "follower"
CANDIDATE = "candidate"
LEADER = "leader"
class RaftNode:
def __init__(self, node_id, cluster_size):
self.node_id = node_id
self.state = NodeState.FOLLOWER
self.current_term = 0
self.voted_for = None
self.log = [] # List of (term, value) tuples
self.commit_index = -1
self.cluster_size = cluster_size
self.votes_received = 0
def start_election(self):
"""Follower timeout হলে election শুরু করে"""
self.state = NodeState.CANDIDATE
self.current_term += 1
self.voted_for = self.node_id # নিজেকে vote
self.votes_received = 1
print(f"Node {self.node_id}: Starting election for term {self.current_term}")
def receive_vote(self, from_node, term, vote_granted):
if term == self.current_term and self.state == NodeState.CANDIDATE:
if vote_granted:
self.votes_received += 1
quorum = (self.cluster_size // 2) + 1
if self.votes_received >= quorum:
self.become_leader()
def become_leader(self):
self.state = NodeState.LEADER
print(f"✅ Node {self.node_id}: Became LEADER for term {self.current_term}")
print(f" Votes: {self.votes_received}/{self.cluster_size}")
def append_entry(self, value):
"""Leader শুধু এটা call করতে পারে"""
if self.state != NodeState.LEADER:
raise Exception("Only leader can append entries")
self.log.append((self.current_term, value))
print(f"Leader Node {self.node_id}: Appended '{value}' to log")
# Simulation
nodes = [RaftNode(i, 5) for i in range(5)]
# Node 2 starts election
nodes[2].start_election()
# 3 nodes vote yes (quorum = 3/5)
nodes[2].receive_vote(0, 1, True)
nodes[2].receive_vote(1, 1, True)
nodes[2].receive_vote(3, 1, True) # This triggers becoming leader
# Leader now writes
nodes[2].append_entry("balance=10000")
nodes[2].append_entry("transfer=5000")Node.js: etcd দিয়ে Distributed Lock
// npm install etcd3
const { Etcd3 } = require('etcd3');
const client = new Etcd3({ hosts: 'localhost:2379' });
async function processOrderWithLock(orderId) {
// Distributed lock — শুধু একটা server এই order process করবেন
const lock = client.lock(`order/${orderId}`);
try {
await lock.acquire();
console.log(`🔒 Lock acquired for order ${orderId}`);
// Critical section — duplicate processing impossible
const existing = await client.get(`processed/${orderId}`);
if (existing) {
console.log(`⚠️ Order ${orderId} already processed!`);
return;
}
// Process the order
console.log(`✅ Processing order ${orderId}...`);
await new Promise(resolve => setTimeout(resolve, 1000));
// Mark as processed
await client.put(`processed/${orderId}`).value('true');
console.log(`🎉 Order ${orderId} processed successfully!`);
} finally {
await lock.release();
console.log(`🔓 Lock released for order ${orderId}`);
}
}
// Multiple services try to process same order simultaneously
// Only ONE will succeed due to distributed lock
Promise.all([
processOrderWithLock('order-123'),
processOrderWithLock('order-123'), // Duplicate — will be blocked
processOrderWithLock('order-123'), // Duplicate — will be blocked
]);Real World Use Cases
☸️ Kubernetes (etcd)
Kubernetes এর সব cluster state etcd তে থাকে। Raft দিয়ে 3-5 etcd nodes consensus maintain করে। etcd down হলে K8s cluster কাজ করে না।
📨 Apache Kafka
KRaft mode এ Kafka নিজেই Raft ব্যবহার করে। আগে ZooKeeper লাগতো। Kafka 3.3+ এ ZooKeeper deprecated।
🗄️ CockroachDB
Distributed SQL database। প্রতিটা range এর জন্য Raft group। Globally distributed consistency। Google Spanner এর open source alternative।
🔐 HashiCorp Vault
Secrets management। Raft storage backend। HA mode এ একটা Vault cluster এর সব nodes consensus maintain করে।
Common Interview Questions
🎯 Q1: Raft এবং Paxos এর পার্থক্য কী?
🎯 Q2: Quorum কী? ৩ nodes এ কতটা fail করলেন চলবে?
🎯 Q3: Split Brain কী?
INTERVIEW এ এটা বলুন
SUMMARY — আজকে যা শিখলাম
| Concept | এক লাইনে |
|---|---|
| Consensus | Distributed nodes এর agreement on single value |
| Raft | Understandable consensus — Leader, Log, Safety |
| Quorum | Majority (N/2 + 1) agree করলেনই committed |
| Leader Election | Timeout → Candidate → Vote → Leader |
| etcd | Kubernetes এর brain, Raft-based KV store |
| ZooKeeper | Legacy coordination service, Kafka এ ছিল |
| Split Brain | Quorum দিয়ে prevent করা হয় |