Tác giả: Danica Fine & Nikoleta Verbeck | Ngày đăng: 03/11/2022
Link bài viết gốc | Link series tiếng Việt
Khi gặp sự cố với Apache Kafka® - ví dụ như số lượng kết nối tới các broker tăng đột biến hoặc việc gom nhóm bản ghi (record batching) hoạt động không bình thường - các bạn sẽ rất dễ coi các vấn đề này như những vấn đề cần được giải quyết riêng lẻ. Tuy nhiên, bạn sẽ sớm nhận ra, phần lớn các vấn đề này thực chất chỉ là triệu chứng của một vấn đề lớn hơn. Thay vì chỉ xử lý từng triệu chứng riêng lẻ, chẳng phải sẽ tốt hơn nếu ta đi đến tận gốc vấn đề bằng một chẩn đoán chuẩn chỉ?
Nếu bạn đang muốn nâng cao kỹ năng debug Kafka của mình và hiểu sâu hơn về các vấn đề phổ biến cũng như các “bệnh lý” tiềm ẩn đằng sau từng triệu chứng, thì loạt bài viết này là dành cho bạn.
Các triệu chứng có trong loạt bài viết
Trong loạt bài viết này, chúng ta sẽ cùng tìm hiểu một số triệu chứng phổ biến bạn có thể gặp phải khi sử dụng Kafka, bao gồm:
- Giảm thông lượng gửi message (bài viết này)
- Tăng request rate, thời gian response và/hoặc tăng tải trên broker
- Tăng thời gian tái cân bằng (rebalance) consumer
- Tăng số lượng kết nối
Những vấn đề này khá phổ biến, đến mức đôi khi bạn sẽ không để ý tới chúng nếu chúng chưa gây ảnh hưởng nghiêm trọng tới hoạt động thông thường. Hãy cùng khám phá từng triệu chứng cụ thể, tìm hiểu xem chúng là gì và tác động của chúng, cũng như đặt ra những câu hỏi giúp bạn xác định gốc rễ vấn đề.
Nội dung bài viết này: Giảm thông lượng gửi message (Reduced Message Throughput)
Một trong những điểm mạnh lớn nhất của Kafka là khả năng duy trì thông lượng dữ liệu cao. Và thông lượng cao bắt đầu từ các producer. Trước khi gửi message tới các broker, các bản ghi (record) cùng topic-partition được gom lại thành một batch – tập hợp dữ liệu nén. Những batch này sau đó được tiếp tục gom nhóm và gửi đi đến broker.
Việc gom nhóm (batching) là điều rất tốt, và ta nên làm như vậy. Nhưng làm sao biết khi nào batching hoạt động hiệu quả và khi nào thì không?
Các chỉ số về Producer nên biết
“Bạn không thể quản lý điều gì mà bạn không thể đo lường.” — Câu nói quen thuộc nhưng rất đúng.
May mắn thay, Kafka cung cấp khá nhiều chỉ số qua các số liệu JMX. Khi này, trở ngại lớn nhất đối với nhiều người là việc biết được số liệu nào của producer thực sự cần chú ý. Dưới đây là một số chỉ số đáng chú ý:
-
batch-size-avg
kafka.producer:type=producer-metrics,client-id=([-.w]+),name=batch-size-avg
:
Mô tả kích thước trung bình của các batch tính theo byte được gửi cho mỗi topic-partition, trên mỗi request. Giá trị này nên gần – nhưng đừng quá gần – vớibatch.size
(kích thước batch tối đa của mỗi producer), nó cho thấy rằng producer đang lấp đầy các batch hoàn toàn trước khi đạt đến ngưỡng thời gian được xác định bởilinger.ms
. Nếu giá trị này liên tục thấp hơnbatch.size
, có thể producer đang chờ quá lâu để batch đầy. -
records-per-request-avg
kafka.producer:type=producer-metrics,client-id=([-.w]+),name=records-per-request-avg
:
Mô tả số lượng record trung bình trên mỗi request. Nếu bạn muốn tận dụng tính năng batching, hãy theo dõi chỉ số này để đảm bảo mỗi batch chứa nhiều hơn một record. Ví dụ, nếu các record của bạn quá lớn, bạn sẽ thấy giá trị này thường xuyên bằng 1; bạn cần xem xét sử dụng nén (compression) hoặc tăngbatch.size
. -
record-size-avg
kafka.producer:type=producer-metrics,client-id=([-.w]+),name=record-size-avg
:
Mô tả kích thước trung bình tính theo byte của mỗi record. Nếu giá trị này gần hoặc lớn hơnbatch-size-avg
, điều đó có nghĩa là producer không thực hiện batching, vì bản thân mỗi record đã chiếm toàn bộ batch. -
record-queue-time-avg
kafka.producer:type=producer-metrics,client-id=([-.w]+),name=record-queue-time-avg
:
Thời gian trung bình các batch nằm trong send buffer trước khi được gửi. Dùng kết hợp vớibatch-size-avg
để xác định liệu các batch đang bị ràng buộc bởilinger.ms
haybatch.size
. (Nếu bạn muốn thực hành tinh chỉnh các tham số này, hãy tham khảo video thực hành producer trong Khóa học Kafka Internals.) -
request-latency-avg
kafka.producer:type=producer-metrics,client-id=([-.w]+),name=request-latency-avg
:
Thời gian từ khi producer gửi request đến khi nhận response từ broker. Không có phân tích chi tiết theo từng broker cho số liệu này, nên cần kết hợp chỉ số này với thông tin topic-partition để tính toán hiệu năng. Dùng kết hợp vớimax.request.size
có thể giúp bạn hiểu được hiệu suất của batching. Từ đó cân bằng giữa hiệu năng batch, độ trễ xử lý record và chi phí tổng thể khi tối ưu hóa batch. -
requests-in-flight
kafka.producer:type=producer-metrics,client-id=([-.w]+),name=requests-in-flight
:
Số lượng request đang chờ phản hồi từ broker. Giá trị thấp là dấu hiệu tốt: ít request đang bị “treo” (tồn đọng), hệ thống phản hồi nhanh.
Giờ bạn đã hiểu rõ những chỉ số quan trọng của producer, bạn có thể bắt đầu quan sát chúng một cách đúng đắn. Nếu bạn thấy các batch hoạt động kém hiệu quả (ví dụ: mỗi batch chỉ chứa một vài record hoặc batch quá lớn), có thể là do nhiều nguyên nhân. Bước đầu tiên và đơn giản nhất: hãy kiểm tra lại và hiểu rõ các cấu hình của producer
Cấu hình batching
Việc batching được điều khiển bởi các cấu hình sau:
-
batch.size
Kích thước tối đa của một batch - producer cố gắng gom các record lại (mặc định: 16.384 byte ~ 16KB). Giá trịbatch.size
càng lớn, khả năng batching càng tối ưu (gom được nhiều bản ghi hơn trước khi gửi). Nếu một record lớn hơnbatch.size
, nó sẽ không được batch. May mắn là, nếu bạn theo dõi chỉ số (metric)records-per-request-avg
, bạn sẽ phát hiện vấn đề này. -
linger.ms
Thời gian tối đa mà producer sẽ chờ để thêm record vào batch trước khi gửi đi (mặc định: 0ms). Tănglinger.ms
có thể giúp batching hiệu quả hơn, nhưng nếu số lượng record ít,linger.ms
quá lâu sẽ gây trễ không cần thiết. Mặc địnhlinger.ms=0
(tức là gửi ngay khi có record). -
buffer.memory
Thường bị bỏ qua, nhưng rất quan trọng khi điều chỉnhbatch.size
. Là dung lượng bộ nhớ tạm mà producer cấp phát để chứa batch. Bộ nhớ này sẽ được chia thành các phần nhỏ có kích thướcbằng batch.size
. Như bạn đoán, điều này có nghĩa là số lượng batch tối đa có thể tồn tại cùng lúc được kiểm soát bởi cấu hình này. Cần lưu ý rằng batch sẽ không giải phóng phân đoạn (segment) của nó khỏi bộ nhớ cho đến khi các record bên trong được xử lý xong, dù thành công hay không. Bạn có thể dùng metric:kafka.producer:type=producer-metrics,client-id=([-.\w]+),name=buffer-available-bytes
để giám sát dung lượng buffer còn lại và nhận biết khi nào sắp chạm ngưỡng.
Hiểu và điều chỉnh hợp lý các cấu hình này sẽ giúp tối ưu hiệu quả batching. Ngoài ra, còn nhiều tham số bổ sung khác bạn có thể tinh chỉnh để tối ưu hóa batching toàn diện hơn.
Tiếp tục chẩn đoán
Nếu sau khi đã kiểm tra cấu hình liên quan đến batching mà vẫn không phát hiện bất thường, bước tiếp theo hợp lý để debug tình trạng giảm thông lượng (message throughput) là tự đặt thêm một vài câu hỏi sau:
Ngoài việc phát hiện hiện tượng giảm batching...
-
... bạn đã kiểm tra số lượng partition của topic chưa?
Có thể một số topic của bạn có quá nhiều partition. Thực tế, việc tăng partition thường được dùng để phân tán dữ liệu rộng hơn trên disk và tăng khả năng xử lý song song (parallelization) ở phía consumer. Nhưng trên phía producer, điều này có thể gây hại. Vì Kafka batch theo topic-partition, nên nếu topic có quá nhiều partition, các batch sẽ trở nên rời rạc (sparse). Điều này khiến producer phải chờ lâu hơn để gom đủ record. -
... bạn có thấy tần suất request cao bất thường không?
Nếu Kafka chạy trên cloud, hãy kiểm tra cấu hình khối lượng công việc (workloads) của KafkaProducer xem đã được cấu hình phù hợp chưa. Khi triển khai cloud, thường ban đầu sẽ chọn cấu hình nhỏ. Nhưng khi nhu cầu tăng lên theo thời gian, việc scale workload lại thường bị bỏ sót. Như đã nói trước đó, việc mở rộng theo chiều ngang (horizontal scaling) có thể làm batching kém hiệu quả do phân tán record. Mở rộng theo chiều dọc (vertical scaling) sẽ giúp hạn chế sự phân tán của các record giữa các service instance, từ đó cải thiện hiệu suất batching. -
... bạn có thấy số lượng kết nối tăng cao không?
Dấu hiệu này có thể cho thấy bạn đang tạo nhiều KafkaProducer instance trong cùng một service hoặc process. Điều này thường xảy ra khi bạn vừa chuyển (migrate) từ một công nghệ messaging khác (và cố gắng giảm thiểu thay đổi code) hoặc có thể bạn chưa hiểu rõ KafkaProducer là thread-safe, nên tạo nhiều instance thay vì dùng chung. Dù thế nào đi nữa, đã đến lúc kiểm tra code client của bạn.
Kết luận
Trong hành trình tối ưu hóa thông lượng, batching là yếu tố then chốt. Như bạn thấy, nếu gặp phải tình trạng giảm thông lượng (message throughput), rất có thể liên quan tới cấu hình batching — nhưng không loại trừ khả năng đây chỉ là triệu chứng của một vấn đề lớn hơn.
Lần tới khi Kafka của bạn “trục trặc”, đừng vội sửa. Hãy dành thời gian để chẩn đoán và phân tích kỹ càng. Trước khi thay đổi bất kỳ điều gì trong ứng dụng hoặc cấu hình, điều quan trọng là bạn cần hiểu rõ nguyên nhân gốc rễ gây ra vấn đề. Với các công cụ và câu hỏi đã được trang bị ở đây, bạn sẽ sẵn sàng để chẩn đoán, gỡ lỗi và tối ưu hiệu suất Kafka một cách thông minh.