"Đặt nhiều partition cho chắc" là lời khuyên phổ biến và tốn kém. Bài này đo cả hai vế: partition mua được gì, và tốn gì.

Thông lượng theo số partition, khả năng đọc song song, và cái giá phải trả

Phía ghi gần như không quan tâm

500.000 tin × 300 byte, một broker, thay đổi số partition:

Partition Thông lượng
1 802.568 tin/giây
2 932.835
4 967.117
8 907.441
16 931.098
32 905.797
64 833.333
128 941.619

Một partition đã đạt 83% mức đỉnh. Từ 4 trở lên, chênh lệch chỉ là nhiễu — 64 partition còn thấp hơn 4 partition.

Điều này ngược với hình dung thường gặp rằng partition là "làn đường" và thêm làn thì thông xe hơn. Với một broker, nút thắt là đĩa và mạng của chính máy đó, không phải số làn.

Vậy partition dùng để làm gì?

Phía đọc — nhưng cũng bão hoà

Đọc 2 triệu tin từ topic 8 partition, thay đổi số consumer trong nhóm:

Consumer Thông lượng Hệ số
1 1.863.933 tin/giây 1,00×
2 2.353.449 1,26×
4 3.164.007 1,70×
8 3.099.374 1,66×

Bốn consumer cho 1,70 lần, không phải 4 lần. Tám consumer không thêm gì.

Lại là nút thắt máy: một broker phục vụ tất cả, và nó chỉ đọc được chừng đó từ bộ đệm trang.

Trên cụm thật, partition trải trên nhiều broker và mỗi broker phục vụ phần của nó — đó mới là chỗ khả năng mở rộng đến từ. Con số ở đây đo trần của một máy, không đo trần của Kafka.

Nhưng luật cứng vẫn giữ nguyên và đó mới là điều đáng nhớ: số partition là trần tuyệt đối của số consumer hoạt động trong một nhóm. Topic 4 partition thì consumer thứ 5 ngồi không, dù cụm có bao nhiêu broker.

Cái giá

Bộ nhớ broker Khởi động lại
~5 partition 290 MB 2,0 giây
414 partition 682 MB 3 giây
2.414 partition 973 MB 9 giây

Tạo một topic 2.000 partition rỗng hoàn toàn:

  • 24 MB đĩa (12 KB mỗi partition — tệp chỉ mục thưa)
  • 2.590 tệp đang mở trên tiến trình broker
  • Bộ nhớ từ 290 MB lên 973 MB — gấp 3,4 lần, chỉ vì có thêm partition rỗng

Mỗi partition là một thư mục, ít nhất ba tệp mở, một mục trong siêu dữ liệu cụm, và một dòng trong mọi báo cáo trạng thái. Broker giữ chỉ mục của partition đang mở trong bộ nhớ, và đó là phần lớn con số 973 MB.

Việc tạo và xoá thì nhanh: tạo 2.000 partition mất chưa tới 2 giây, gọi lệnh xoá trả về sau 862 ms. Nhưng xoá là bất đồng bộ — thư mục được đánh dấu rồi mới dọn sau file.delete.delay.ms (mặc định 60 giây). Ngay sau lệnh xoá, ls vẫn thấy đủ 2.414 thư mục. Đừng dựa vào việc đếm thư mục để xác nhận đã xoá xong.

Ba hệ quả khác của partition thừa

Bầu lại leader lâu hơn. Khi một broker chết, controller phải bầu leader mới cho từng partition nó giữ. Vài nghìn partition thì việc đó tính bằng giây; vài chục nghìn thì tính bằng phút, và trong khoảng đó những partition chưa bầu xong đều không phục vụ được.

Cân bằng lại nhóm nặng hơn. Danh sách partition phải truyền qua lại giữa mọi thành viên trong mỗi lần cân bằng.

Nén và dọn hết hạn chạy trên nhiều tệp hơn. Nhiều partition rỗng vẫn tốn công quét định kỳ.

Không giảm được

--alter --partitions chỉ đi lên. Kafka không có cách giảm số partition — vì giảm nghĩa là phải quyết định dữ liệu trong partition bị bỏ đi đâu, và không có câu trả lời đúng.

Muốn giảm thì phải tạo topic mới và chép dữ liệu sang, rồi đổi mọi producer và consumer. Đó là một dự án, không phải một lệnh.

Và tăng cũng không miễn phí: nó làm hỏng phân bố khoá của dữ liệu cũ, vì hash(key) % n đổi khi n đổi. Phần sau đo con số cụ thể.

Cách chọn

Công thức thực dụng:

số partition = số consumer cao nhất bạn nghĩ sẽ cần  ×  2

Nhân đôi để có chỗ tăng consumer mà không phải sửa topic. Không nhân 10.

Vài điểm neo từ phép đo trên:

  • Dưới 10 consumer: 8–16 partition. Thừa đủ.
  • Vài chục consumer: 32–64 partition.
  • Trên 100 partition cho một topic: cần lý do cụ thể, thường là một nhóm consumer thật sự lớn.
  • Tổng partition trên một broker: vài nghìn thì bình thường, và con số 973 MB ở trên cho thấy vì sao vài chục nghìn thì không.

Và nếu bạn dùng khoá để giữ thứ tự, còn một ràng buộc nữa quan trọng hơn tất cả những cái trên: số khoá phân biệt phải lớn hơn số partition rất nhiều, nếu không partition sẽ rỗng bất kể bạn đặt bao nhiêu. Phần 3 đã đo, và phần sau đo tiếp.

Thử ba mươi giây

Đếm partition trên broker của bạn và đối chiếu với bộ nhớ:

kafka-topics.sh --bootstrap-server kf:9092 --describe \
  | grep -c "^	Topic:"

docker stats --no-stream kf

Rồi xem có bao nhiêu partition thật sự đang được đọc:

kafka-consumer-groups.sh --bootstrap-server kf:9092 --all-groups --describe 2>/dev/null \
  | awk 'NR>1 && $2!="" {print $2"-"$3}' | sort -u | wc -l

Chênh lệch giữa hai con số là số partition bạn đang trả tiền mà không dùng.

Phần sau đo khoá và thứ tự: cái gì Kafka bảo đảm, cái gì không, và 45% khoá đổi chỗ khi bạn tăng partition.