Tác giả: Danica Fine & Nikoleta Verbeck | Ngày đăng: 01/12/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
- 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 (bài viết này)
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: Tăng số lượng kết nối (Increased connections)
Nếu bạn đã từng sử dụng Kafka, hẳn bạn đã nghe nói nhiều về "kết nối" (connection) — chủ đề này thường được nhắc đến nhất khi nói về client. Tất nhiên, producer và consumer sẽ kết nối đến cluster để thực hiện công việc của mình, nhưng không chỉ có vậy. Gần như mọi tương tác trong Kafka đều diễn ra qua kết nối, vì vậy chúng có vai trò cực kỳ quan trọng.
Tuy nhiên, quá nhiều kết nối lại là một vấn đề. Quá nhiều kết nối trong cluster có thể gây quá tải cho broker, từ đó ảnh hưởng đến việc xử lý các request.
Các loại kết nối trong cluster
Trước khi đi sâu vào các sự cố do số kết nối tăng cao, bạn cần hiểu những loại kết nối nào được thiết lập trong cluster và chúng được tạo vào lúc nào.
Kết nối của producer và consumer
Mỗi khi một producer hoặc consumer muốn ghi hoặc đọc dữ liệu từ Kafka cluster, chúng sẽ thiết lập và duy trì kết nối đến các broker. Với consumer, nếu thuộc consumer group, nó còn phải duy trì kết nối, gửi heartbeat, và cung cấp thông tin thành viên cho ConsumerGroupCoordinator (chạy bên trong một broker).
Các kết nối được tạo ra khi chúng ta ghi dữ liệu vào Kafka (produce) và đọc dữ liệu từ Kafka (consume). Nhưng có bao nhiêu kết nối sẽ được tạo? Câu trả lời phụ thuộc vào: số lượng topic, partition, broker và một chút yếu tố ngẫu nhiên.
Đối với cả consumer và producer, số lượng kết nối từ một client bị giới hạn bởi số lượng topic-partition mà client đó tương tác. Producer có khả năng ghi dữ liệu vào mọi partition trong một topic, vì vậy có thể một producer phải duy trì kết nối mở đến mọi broker, tùy thuộc vào broker nào giữ bản sao chính (lead replica) của mỗi topic-partition. Mặt khác, consumer có thể tối ưu hơn trong việc kết nối với broker. Consumer hoạt động trong một consumer group và do đó chỉ đọc dữ liệu từ một số lượng topic-partition nhất định. Cũng cần lưu ý rằng khi một consumer hoặc producer khởi động lần đầu tiên, nó sẽ kết nối đến một trong các bootstrap server để nhận metadata cần thiết.
Ví dụ, giả sử một producer ghi dữ liệu vào một topic có 3 partition và hoạt động trong một cluster có 5 broker. Producer không nhất thiết phải duy trì kết nối mở với các broker không chứa partition của topic đó. Vì vậy, chúng ta chỉ cần 3 kết nối cho producer này.
Tuy nhiên, thực tế producer này có thể duy trì 4 kết nối mở, tùy thuộc vào broker mà producer kết nối khi khởi động. Lưu ý rằng kết nối thứ 4 này chỉ được sử dụng để lấy metadata ban đầu và có thể không được duy trì lâu như các kết nối khác. Điều này bị ảnh hưởng bởi metadata.max.age.ms
(mặc định 5 phút), kiểm soát khoảng thời gian làm mới metadata, và connections.max.idle.ms
(mặc định 9 phút), cho phép các kết nối không hoạt động được dọn dẹp và đóng lại.
Kết nối giữa các broker
Các broker cũng kết nối với nhau, nhưng điều này phụ thuộc vào cài đặt cụ thể của cluster. Ví dụ khi sử dụng in-sync replicas, broker chứa bản sao (follower) sẽ kết nối đến broker chứa bản gốc (leader) để định kỳ fetch dữ liệu và đồng bộ.
Kết nối bổ sung
Chưa hết! Tùy vào loại ứng dụng bạn xây dựng, còn có thể có các kết nối bổ sung khác được thiết lập trong cluster. Ví dụ: AdminClient sẽ tạo kết nối riêng biệt cho mỗi topic mà nó cố gắng tạo.
Một số số liệu cần theo dõi
Không phải lúc nào vấn đề cũng nằm ở số liệu, nhưng ... cũng hiếm khi không liên quan đến số liệu. Khi nói đến số lượng kết nối đến cluster của bạn tại một thời điểm bất kỳ, có một vài số liệu về broker và client mà bạn nên ghi nhớ.
-
connection-count
kafka.server:type=socket-server-metrics,listener={listener_name},networkProcessor={#},name=connection-count
kafka.producer:type=producer-metrics,client-id=([-.w]+),name=connection-count
kafka.consumer:type=consumer-metrics,client-id=([-.w]+),name=connection-count
Tổng số kết nối đang hoạt động với broker tại một thời điểm nhất định. Kafka có thể xử lý hàng nghìn kết nối đồng thời, nhưng bạn vẫn nên theo dõi xu hướng số lượng kết nối. Bất kỳ đột biến bất thường nào đều có thể là dấu hiệu cần lưu ý. Chỉ số này được cung cấp cả từ phía producer và consumer, giúp bạn dễ dàng xác định vấn đề ở phía client nào.
-
connection-creation-rate
kafka.server:type=socket-server-metrics,listener={listener_name},networkProcessor={#},name=connection-creation-rate
kafka.producer:type=producer-metrics,client-id=([-.w]+),name=connection-creation-rate
kafka.consumer:type=consumer-metrics,client-id=([-.w]+),name=connection-creation-rate
Số lượng kết nối mới được tạo mỗi giây. Số liệu này có ở cấp độ broker, producer và consumer đi đôi với connection-count, cho thấy số lượng kết nối mới được tạo ra mỗi giây. Đây là một số liệu tốt để đặt cảnh báo nhằm phát hiện cơn bão kết nối (connection storm) ngay khi nó xảy ra và cũng để xác định loại client nào (producer hay consumer) có thể đang gây ra vấn đề.
-
AcceptorBlockedPercent
kafka.network:type=Acceptor,name=AcceptorBlockedPercent,listener={listener_name}
Tỷ lệ phần trăm request mà listener bị chặn không nhận được. Tại Confluent, chỉ số này đóng vai trò quan trọng trong việc phát hiện các đợt bùng nổ kết nối (connection storm) khi sử dụng Confluent Cloud. Bạn có thể sử dụng chỉ số này phối hợp với bất kỳ listener nào, ví dụ như replication listener hoặc listener bên ngoài khác. Ví dụ, đối với replication listener, giá trị này sẽ giúp bạn xác định các nút thắt, điểm nghẽn (bottlenecks) đang xảy ra trong quá trình replication. Lý tưởng nhất, giá trị này sẽ là 0; bất kỳ giá trị dương nào đều cho thấy các kết nối đang bị giới hạn (throttled).
Tiếp tục chẩn đoán
Bên cạnh việc quan sát số lượng kết nối tăng lên ...
-
... bạn có thấy mức tiêu thụ bộ nhớ tăng cao?
Hãy kiểm tra xem bạn có vô tình tạo một consumer cho mỗi thread trong cùng một service instance hay không. Xem lại phần xử lý vấn đề thời gian rebalance tăng để hiểu rõ hơn. Nếu bạn đang chuyển sang mô hình consumer đa luồng, tránh tạo một consumer cho mỗi luồng, vì điều này có thể làm tăng số kết nối và mức tiêu thụ bộ nhớ không cần thiết. -
... bạn có thấy consumer group tăng kích thước và mất nhiều thời gian rebalance?
Hãy kiểm tra xem workload của KafkaConsumer chạy trên cloud để xem liệu chúng có bị định cỡ quá nhỏ hay không. Vấn đề này đã được đề cập nhiều lần trong series này; nó đặc biệt quan trọng trong thế giới sử dụng các dịch vụ Kafka chạy trên cloud. Nếu bạn đang sử dụng Kafka chạy trên cloud, một trong những điều đầu tiên bạn nên kiểm tra khi gặp bất kỳ vấn đề nào là liệu workload cloud-based của bạn có được định cỡ phù hợp hay không. Điều này có thể giúp bạn tiết kiệm rất nhiều thời gian! -
... bạn có thấy tần suất request tăng đột biến?
Điều này có thể cho thấy bạn đang sử dụng nhiều instance KafkaProducer trong một service hoặc process. Có thể bạn vừa chuyển 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õ về cơ chế an toàn luồng (thread safety) của KafkaProducer. Dù thế nào đi nữa, đã đến lúc kiểm tra code client của bạn.
Kết luận
Bản chất của các kết nối broker là khá phức tạp và khó theo dõi, nhưng điều đó không có nghĩa là bạn không thể kiểm soát được Kafka cluster của mình! Với sự hiểu biết về các loại kết nối đang diễn ra trong cluster và các chỉ số cần theo dõi, bạn đã có đủ công cụ để gỡ rối và chẩn đoán các vấn đề liên quan đến kết nối một cách tự tin hơn.