Có rất nhiều thông số cấu hình mặc định có sẵn trong Apache Kafka, hầu hết những giá trị này có thể tùy chỉnh được – giúp tinh chỉnh sản phẩm nhằm đáp ứng những yêu cầu phù hợp cho hệ thống (độ trễ, thoughtput, performance,… ). Những giá trị mặc định này trải dài trên nhiều thành phần khác nhau như: broker, producer và consumer.
Thường thì Kafka cung cấp càng nhiều thông số cấu hình, sẽ giúp chúng ta tùy chỉnh hệ thống một cách toàn diện hơn, nhưng một số thông số cấu hình trong đó có thể trở nên tương đối nguy hiểm nếu chúng được sử dụng sai cách. Vì chúng có thể có những tác dụng phụ không mong muốn, hay được tối ưu hóa cho một số mục đích nào đó mà không dành cho bạn.
Trong bài viết này, mình sẽ giải thích một số thông số cấu hình quan trọng ở phía broker, giải thích những giá trị này có tác dụng gì, tại sao những giá trị mặc định này có thể gây ra các vấn đề nghiêm trọng cho hệ thống của bạn.
Những giá trị mặc định bạn nên thay đổi
1. auto.create.topics.enable
Mặc định giá trị này được thiết lập “true“. Bạn sẽ muốn thay đổi giá trị này thành false. Vì các ứng dụng thường sẽ phải chịu trách nhiệm cho việc tạo ra các topics của chúng.
Nếu bạn để giá trị này là true, một số thông số cấu hình khác sẽ được kích hoạt để đáp ứng cấu hình này cho topic.
- log.retention.hours: mặc định, logs sẽ được giữ lại 7 ngày. Hãy xem xét cẩn thận xem giá trị này đã đủ tốt chưa. Bất kỳ dữ liệu nào được lưu trữ quá 7 ngày sẽ không được giữ lại nữa.
- min.insync.replicas: mặc định giá trị này là 1. Như theo documentation Kafka có đề cập đến, giá trị cấu hình này điển hình sẽ là replication-factor trừ đi 1, nghĩa là nếu replication-factor bạn thiết lập giá trị là 3, khi đó min.insync.replicas nên là 2. Vấn đề khi bạn sử dụng giá trị mặc định là 1, nghĩa là bạn sẽ đặt mình vào trạng thái nguy hiểm – trong đó cluster chấp nhận các message khi mà bạn chỉ có 1 bản copy. Mặt khác, gía trị này bằng với replication-factor nghĩa là bạn sẽ bị mất đi 1 node broker tạm thời mà không nhận thêm được message nào nữa cho đến khi missing partition được rebalanced lại để trở thành healthy node.
- default.replication.factor: mặc định giá trị này là 1. Giá trị mặc định như vậy hơi bị dở, vì nó thực sự chỉ tạo ra 1 bản copy của một topic một cách tự động. Nếu disk lưu trữ partition của topic này chết, khi đó dữ liệu sẽ hoàn toàn bị mất. Thậm chí nếu như bạn có backup, consumer sẽ vẫn gặp trục trặc khi rebalance tới broker khác mà có bản copy của partition, dẫn đến việc consumer lấy message sẽ bị ngắt đoạn. Mình đề xuất giá trị này nên được thiết lập là 3.
- num.partitions: mặc định là 1. Giá trị mặc định này cũng không tốt. Nếu một topic chỉ có một partition, nó có thể được sử dụng chỉ bởi một instance của một ứng dụng tại một thời điểm cụ thể, dẫn đến việc cản trở quá trình nhận dữ liệu song song khi sử dụng Kafka. Mặc dù Kafka cluster có giới hạn về số lượng chúng có thể xử lý, giá trị tối thiểu 3 partition mỗi topic thường sẽ an toàn và hợp lý hơn.
2. offsets.retention.minutes
Mặc định là 1400 phút (24 giờ). Giá trị mặc định này khá là nguy hiểm. Một số ứng dụng có thể rơi vào trạng thái nghỉ vào khoảng thời gian cuối tuần, nghĩa là chúng không đẩy message nào tới Kafka trong khoảng thời gian đó.
Buổi sáng ngày hôm sau, nếu chúng khởi động lại trước khi consume từ Kafka, instance mới không thể tìm thấy bất kỳ committed offsets nào cho consumer group, vì chúng đã bị hết hạn.
Do đó, cấu hình auto.offset.reset trong consumer khởi động, gửi ứng dụng tới các message cũ nhất, mới nhất hoặc không thành công. Trong bất kỳ trường hợp nào đi nữa, điều này cũng không nên.
Đề xuất là nên tăng giá trị này lên khoảng 7 ngày để giữ offset thêm an toàn.
Những giá trị mặc định bạn nên để lại
1. auto.leader.rebalance.enable
Mặc định là “true”. Trừ khi bạn biết mình đang làm gì, thường thì chắc chắn bạn sẽ không muốn phải rebalance partition một cách thủ công đâu. Hãy để Kafka làm việc đó cho bạn.
2. delete.topic.enable
Mặc định là “true”. Nếu bạn thấy mình đang thiết lập Kafka trong một môi trường được kiểm soát chặt chẽ, bạn có thể sẽ không được xóa bất cứ thứ gì. Mặc khác, cho phép xóa topic giúp đảm bảo bạn có thể thoát khỏi mớ dữ liệu này một cách nhanh chóng và dễ dàng.
Đặc biệt hữu ích trong các cluster đang phát triển. Không nên thiết lập giá trị này thành false, vì nó giống như bạn sẽ tự bắn vào chân mình vậy.
3. log.flush.scheduler.interval.ms
Mặc định là “never” (được biểu thị dưới dạng số ms). Kafka rất hiệu quả vì nó cho phép truyền dữ liệu zero-copy từ producer cho đến consumer.
Mặc dù đó là cơ chế tuyệt vời để di chuyển dữ liệu một cách nhanh chóng, khi nói về khía cạnh độ bền – nó có thể trở thành một mối lo ngại. Để giải thích vấn đề này, Kafka đề xuất việc sử dụng replication qua nhiều node để đảm bảo thông tin không bị mất mát, thay vì xóa đi các message khỏi disk khi chúng đến. Kết quả là sự thiếu chắc chắn về thời điểm các message thực sự được ghi vào disk.
Bạn có thể ép Kafka flush tới disk bằng cách sử dụng thuộc tính này và các thuộc tính cấu hình khác. Tuy nhiên, rất có thể bạn sẽ làm giảm hiệu năng Kafka trong quá trình xử lý. Do đó, đề xuất là nên giữ mặc định giá trị này.
4. offsets.commit.required.acks
Mặc định là “-1”, nghĩa là các message không được công nhận bởi leader cho đến khi giá trị min.in.sync.replicas của topic chấp nhận.
Đây là giá trị an toàn, thuộc về khía cạnh độ bền cho Kafka. Bạn nên cân nhắc các cấu hình cụ thể ở cấp độ topic, tùy thuộc vào tính chất của thông tin được lưu trữ.
5. offsets.topic.num.partitions
Mặc định là “50”. Kafka tự động tạo ra topic __consumer_offsets với số partition là 50. Vì đây có thể là topic hoạt động nhiều nhất trong cluster của bạn, nên để con số partition này đủ cao để giữ cho tải được trải đều trên càng nhiều node broker càng tốt.
__consumer_offsets không thể thay đổi trong suốt vòng đời của cluster, thậm chí nếu như bạn không có kế hoạch sử dụng 50 broker node, vẫn an toàn hơn khi duy trì con số này.
6. offsets.topic.replication.factor
Mặc định là 3. Tương tự như giá trị trước đó, nhưng là để cấu hình số lượng bản copy __consumer_offsets mà bạn muốn. 3 bản copy là đủ an toàn rồi và có lẽ chỉ nên được thay đổi khi bạn muốn tăng thêm số lượng.
Có nhiều bản copy topic sẽ làm cho cluster của bạn trở nên an toàn và bền vững hơn trong trường hợp broker bị lỗi vì sẽ có nhiều follower hơn trong trạng thái sẵn sàng để trở thành leader.
7. unclean.leader.election.enable
Mặc định là “false”. Được sử dụng thành “true” khi bạn muốn tối ưu hóa về mặt tính khả dụng cho hệ thống. Trong trường hợp leader chết mà không có follower nào được cập nhật, cluster tiếp tục hoạt động nếu giá trị này được set thành “true”. Nhưng có vấn đề nghiêm trọng là dữ liệu sẽ bị mất.
Tuy nhiên, sau khi Aphyr đưa ra kịch bản mất mát dữ liệu này, Kafka đã giới thiệu giá trị cấu hình này và thậm chí thay đổi hẳn thành “false” để ngăn chặn mất mát dữ liệu. Với giá trị mặc định này, cluster sẽ ngừng hoạt động cho đến khi follower được cập nhật dữ liệu đầy đủ, giúp ngăn chặn mất mát dữ liệu.
8. delete.retention.ms
Mặc định là 86400000 (1 ngày): Là khoảng thời gian để hoãn lại việc xóa các điểm đánh dấu tombstone khi topic sử dụng log compacted. Thiết lập này sẽ cho phép consumer một khoảng thời gian để đọc offset nếu bắt đầu từ offset 0 để đảm bảo consumer có được bản snapshot của giai đoạn cuối cùng.
Kết luận
Có rất nhiều thông số cấu hình đóng vai trò thiết yếu trong broker, và mình thậm chí còn không hề đề cập đến bất kỳ thông số cấu hình nào phía client (consumer và producer). Khi thiết lập triển khai cluster, bạn nên quan tâm đến các thông số cấu hình mặc định để giúp tối ưu hóa hệ thống sao cho phù hợp với như cầu của mình.
Xem thêm: