← Về danh sách bài họcBài 15/20
📑 Bài 15: Topics, Partitions & Replication
🎯 Sau bài học này, bạn sẽ:
- Thiết kế partition strategy phù hợp
- Hiểu message ordering guarantee
- Cấu hình replication factor và ISR
- Quản lý topic configurations
1. Partition Deep Dive
Topic "orders" với 4 partitions:
Partition 0: [offset:0] [offset:1] [offset:2] [offset:3] → newest
Partition 1: [offset:0] [offset:1] → newest
Partition 2: [offset:0] [offset:1] [offset:2] → newest
Partition 3: [offset:0] → newest
Message distribution (dựa vào key hash):
key: "user-1" → hash("user-1") % 4 = Partition 2
key: "user-2" → hash("user-2") % 4 = Partition 0
key: null → Round-robin (lần lượt P0, P1, P2, P3)
⚠️ Ordering Guarantee:
• Kafka chỉ đảm bảo thứ tự trong cùng 1 partition
• Messages cùng key → cùng partition → đúng thứ tự
• Messages khác key → có thể khác partition → không đảm bảo thứ tự
• Kafka chỉ đảm bảo thứ tự trong cùng 1 partition
• Messages cùng key → cùng partition → đúng thứ tự
• Messages khác key → có thể khác partition → không đảm bảo thứ tự
2. Partition Key Strategy
| Use Case | Partition Key | Lý Do |
|---|---|---|
| Order processing | orderId |
Events cùng order phải theo thứ tự |
| User activity | userId |
Activities cùng user phải theo thứ tự |
| IoT sensors | sensorId |
Data cùng sensor liên tục |
| Logs (high throughput) | null |
Round-robin, phân bổ đều |
// Custom partitioner
const { Partitioners } = require('kafkajs');
const producer = kafka.producer({
createPartitioner: Partitioners.DefaultPartitioner
});
// Hoặc custom logic
const customPartitioner = () => {
return ({ topic, partitionMetadata, message }) => {
// VIP users → partition 0 (xử lý ưu tiên)
const user = JSON.parse(message.value.toString());
if (user.isVIP) return 0;
// Others: distribute đều
const numPartitions = partitionMetadata.length;
const key = message.key?.toString() || '';
return Math.abs(hashCode(key)) % numPartitions;
};
};
3. Replication
Topic "orders" - Replication Factor = 3
Broker 1 Broker 2 Broker 3
┌────────────┐ ┌────────────┐ ┌────────────┐
│ P0 (Leader)│ │ P0 (ISR) │ │ P0 (ISR) │
│ P1 (ISR) │ │ P1 (Leader)│ │ P1 (ISR) │
│ P2 (ISR) │ │ P2 (ISR) │ │ P2 (Leader)│
└────────────┘ └────────────┘ └────────────┘
ISR = In-Sync Replica (đã sync đủ data)
Nếu Broker 1 chết → P0 Leader chuyển sang Broker 2 hoặc 3
# Tạo topic với replication
docker exec kafka kafka-topics --create \
--topic orders \
--partitions 6 \
--replication-factor 3 \
--bootstrap-server localhost:9092
# Cấu hình topic
docker exec kafka kafka-configs --alter \
--entity-type topics \
--entity-name orders \
--add-config retention.ms=604800000,min.insync.replicas=2 \
--bootstrap-server localhost:9092
💡 min.insync.replicas:
Kết hợp với
Kết hợp với
acks=-1, producer chỉ thành công khi tối thiểu N replicas đã nhận message. Ví
dụ: RF=3, min.insync.replicas=2 → chịu được 1 broker chết.
4. Số Partitions Nên Chọn?
📌 Hướng dẫn chọn partition count:
• Throughput target: partitions ≥ target throughput / throughput per partition
• Consumer parallelism: partitions ≥ max consumers bạn muốn
• Rule of thumb: Bắt đầu với 6-12 partitions cho hầu hết use cases
• Có thể tăng partitions, nhưng KHÔNG thể giảm (phải tạo topic mới)
• Throughput target: partitions ≥ target throughput / throughput per partition
• Consumer parallelism: partitions ≥ max consumers bạn muốn
• Rule of thumb: Bắt đầu với 6-12 partitions cho hầu hết use cases
• Có thể tăng partitions, nhưng KHÔNG thể giảm (phải tạo topic mới)
📝 Tóm Tắt
- Partition key: quyết định message đến partition nào, ảnh hưởng ordering
- Ordering: chỉ đảm bảo trong cùng partition
- Replication: RF ≥ 3 cho production, min.insync.replicas = RF - 1
- Partition count: 6-12 là điểm bắt đầu tốt, chỉ tăng không giảm được