Nội dung bài viết
Video học lập trình mỗi ngày
Bài viết được đưa vào: Trên con đường kỹ sư phần mềm
Phần 1: Chúng ta làm quen được không Kafka
Tôi nhận thấy có nhiều anh em chúng ta đang đặt câu hỏi "Đây là intern ư? Không thể nào.." Đúng vậy, chính xác là không thể nào đúng không, nhưng có đấy, ngay từ bây giờ hay chính thời điểm này bạn đã vượt qua intern. Xin chúc mừng.
Hãy nhìn lại chặng đường của một Intern đánh bại Senior, nếu bạn muốn hãy mượn đôi giày của anh ấy... Nào đi thôi...
Cơn mưa ngang qua...
Ngoài trời đang mưa rả rích, tiếng mưa rơi lộp độp trên của kính của văn phòng của một công ty lớn trong ngành sản xuất phần mềm. Trong phòng phỏng vấn, Senior - một kỹ sư dày dạn kinh nghiệm
đang trao đổi với Intern - một ứng viên trẻ tiềm năng.
Kafka - Buổi phỏng vấn lần 2
Senior:
Chào em, cảm ơn em đã đến buổi phỏng vấn ngày hôm nay, mặc dù trời mưa gió thế này. Chúng ta sẽ nói chuyện một chút về Kafka nhé.
Câu hỏi đầu tiên, khá cơ bản: Làm thế nào để tăng tốc độ xử lý tin nhắn trong hàng đợi Kafka?
Intern
: (hơi rụt rè) Dạ, em chào anh. Em nghĩ cách đơn giản nhất là chia topic thành nhiều phân vùng (partition)
và sử dụng nhóm người tiêu dùng (Consumer Group)
để xử lý topic ạ. Như vậy, nhiều consumer có thể xử lý song song, giúp tăng tốc độ xử lý.
Senior
: Đúng rồi. Đó là cách cơ bản. Vậy nếu anh thêm một điều kiện: Các yêu cầu thao tác trên cùng một đối tượng phải được xử lý theo thứ tự nghiêm ngặt thì sao?
Ví dụ, trong một ứng dụng thương mại điện tử như shopdev or vetautet.com, các thao tác trên cùng một đơn hàng như "tạo đơn", "thanh toán", "hủy đơn" cần phải xử lý đúng theo thứ tự đó. Nếu "hủy đơn" được xử lý trước "tạo đơn" thì sẽ gây ra lỗi. Em sẽ làm thế nào?
Intern
: (suy nghĩ) Dạ, trong trường hợp đó, sau khi chia topic thành các phân vùng, mình cần tùy chỉnh chiến lược phân phối của nhà sản xuất (Producer) ạ. Producer cần đảm bảo các yêu cầu thao tác trên cùng một đối tượng, ví dụ như cùng một đơn hàng, đều được phân phối đến cùng một phân vùng.
Như vậy, mỗi consumer sẽ xử lý dữ liệu trong phân vùng của mình theo thứ tự và đảm bảo tính nhất quán. Ví dụ, ta có thể dùng ID đơn hàng làm key để phân phối, các thao tác trên cùng đơn hàng có cùng ID sẽ vào cùng 1 partition
Senior
: (gật gù) Tốt, em hiểu vấn đề đấy. Bây giờ, giả sử tình huống phức tạp hơn một chút, với các điều kiện sau:
Thứ nhất
, consumer xử lý rất chậm, mất tới 100ms để xử lý một tin nhắn. Như vậy, ngay cả khi topic được chia thành 100 phân vùng, giả sử mỗi giây có 1000 tin nhắn đến, thì mỗi partition cần xử lý 10 tin nhắn/s, tương đương 1000ms, vậy là vẫn không đủ nhanh.
Thứ hai
, số lượng yêu cầu thao tác cho mỗi đối tượng có sự chênh lệch lớn. Ví dụ, có những bài viết trên mạng xã hội có rất nhiều lượt bình luận, trong khi những bài khác lại rất ít. Điều này dẫn đến tình trạng một số phân vùng của topic chứa bình luận sẽ có rất nhiều tin nhắn, trong khi một số phân vùng khác lại gần như trống.
Thứ ba
, các yêu cầu thao tác này rất quan trọng, cần đảm bảo mỗi yêu cầu đều được xử lý tin cậy và đảm bảo tính nhất quán cuối cùng của giao dịch.
Cuối cùng
, đây là một hệ thống cũ, đã hoạt động hàng chục năm, nghiệp vụ rất phức tạp. Bên dự án không cho phép thay đổi lớn liên quan đến logic nghiệp vụ và kiến trúc tổng thể.
Với tất cả các điều kiện ràng buộc đó, yêu cầu đặt ra là phải cải thiện đáng kể hiệu suất xử lý. Nếu là em, em sẽ giải quyết vấn đề này như thế nào?
Nếu là em, em sẽ giải quyết vấn đề này như thế nào?
Intern
: (căng thẳng, nhìn ra ngoài cửa sổ nơi cơn mưa vẫn đang rơi nặng hạt) Dạ, đây là một bài toán khá hóc búa. Em cần thêm thời gian để suy nghĩ... Với những ràng buộc như vậy, việc tối ưu hóa chỉ riêng Kafka có lẽ là không đủ. Em nghĩ có thể cần phải xem xét đến việc xử lý bất đồng bộ hoặc thêm các lớp caching phù hợp...
Senior
: (mỉm cười) Đừng quá lo lắng, đây là một vấn đề phức tạp cần nhiều kinh nghiệm để giải quyết. Anh chỉ muốn xem cách em tiếp cận và phân tích vấn đề. Câu trả lời của em cho thấy em nắm được các khái niệm cơ bản về Kafka. Về bài toán này, anh đã từng gặp phải trong một dự án thực tế cho một diễn đàn tương tác...
Senior
: Trước đây, tôi từng tham gia vào dự án cải thiện hiệu năng cho một hệ thống diễn đàn. Hệ thống này gặp phải vấn đề tương tự như những gì chúng ta vừa thảo luận. Yêu cầu đặt ra là các thao tác bình luận cho mỗi bài viết phải tuân theo một trình tự nhất định.
Ví dụ: Có các thao tác như xóa bình luận, trích dẫn bình luận, trả lời bình luận. Nếu thứ tự xử lý các thao tác này không chính xác, ví dụ, trả lời bình luận trước khi bình luận đó được tạo, thì sẽ gây ra lỗi logic.
Các bình luận này được đưa vào Kafka, sau đó một dịch vụ sẽ consume và xử lý. Tuy nhiên, dịch vụ này xử lý rất chậm, dẫn đến tình trạng tồn đọng tin nhắn. Và tôi cũng có cách xử lý cho TEAM của mình. Em có muốn nghe không?
... Phần 3 sẽ có trong thực hành... Nên như vậy và như vậy...