Kafka là một từ ngữ khá thông dụng trong hầu hết các nghành nghề thuộc lĩnh vực công nghiệp ngày nay. Hầu như mọi công ty hàng đầu trên thế giới đều đang sử dụng kafka trong nền tảng cơ sở hạ tầng của mình. Nhưng câu hỏi đặt ra nó là gì và sức ảnh hưởng của nó ra sao?
Kafka là gì?
Kafka là nền tảng streaming phân tán, có thể mở rộng và là sản phẩm mã nguồn mở. Dự án Kafka ban đầu được phát triển bởi Linkedin sau đó trở thành dự án Apache mã nguồn mở vào năm 2011. Kafka được viết bằng ngôn ngữ Scala và Java. Nó được viết ra nhằm mục đích cung cấp một nền tảng mà có độ trễ thấp và thông lượng cao cho việc xử lý các nguồn cấp dữ liệu theo thời gian thực.
Kafka hoạt động như thế nào?
Kafka được xây dựng dựa trên mô hình publish/subcribe, tương tự như bất kỳ hệ thống message nào khác. Các ứng dụng (đóng vai trò là producer) gửi các messages (records) tới một node kafka (broker) và nói rằng những messages này sẽ được xử lý bởi các ứng dụng khác gọi là consumers. Các messages được gửi tới kafka node sẽ được lưu trữ trong một nơi gọi là topic và sau đó consumer có thể subcribe tới topic đó và lắng nghe những messages này. Messages có thể là bất cứ thông tin gì như giá trị cảm biến, hành động người dùng,…
Topic có thể được xem như là tên của một danh mục mà các messages sẽ được lưu trữ và được đẩy vào.
Partition
Topics trong kafka có thể có kích cỡ rất lớn, như vậy không nên lưu trữ tất cả dữ liệu của một topic trên một node, dữ liệu cần đươc phân chia ra thành nhiều partition sẽ giúp bảo toàn dữ liệu cũng như xử lý dữ liệu dễ dàng hơn. Partitions cho phép chúng ta thực hiện subcribe song song tới một topic cụ thể bằng cách phân chia dữ liệu trong một topic cụ thể ra cho nhiều broker khác nhau (kafka node), mỗi partition có thể được đặt trên một máy riêng biệt – cho phép nhiều consumer đọc dữ liệu từ một topic diễn ra một cách song song.
Để tăng tính khả dụng (availability) của partition, mỗi partition cũng có giá trị replicas của riêng nó. Để dễ hiểu hơn về kafka, mình sẽ trình bày bằng ví dụ với 3 node/broker.
Bây giờ, một topic sẽ được chia ra thành 3 partitions và mỗi broker sẽ có một bản copy của partition. Trong số những bản copy partition này, sẽ có một bản copy được bầu chọn làm leader, trong khi những bản copy khác chỉ thực hiện đồng bộ dữ liệu với partition leader.
Tất cả các hành động ghi và đọc tới một topic sẽ đều phải đi qua partition leader tương ứng và leader sẽ phối hợp để cập nhật dữ liệu mới tới các replica parition khác. Nếu leader bị hỏng, một trong các replica partition sẽ đảm nhận vai trò là một leader mới.
Để một producer/consumer ghi/đọc message từ một partition, chắc chắn chúng cần phải biết leader là ai phải không? Thông tin này cần phải có sẵn ở một vị trí nào đó.
Kafka lưu trữ những thông tin như vậy là metadata trong một dịch vụ gọi là Zookeeper.
Cấu trúc dữ liệu log trong Kafka
Chìa khóa chính dẫn tới khả năng mở rộng và hiệu suất của kafka chính là log. Thường thì các developer khi mới tiếp cận kafka cảm thấy khá rối khi lần đầu tiên nghe đến “log“, bởi vì chúng ta thường hiểu “log” chính là thuật nghữ được sử dụng trong log ứng dụng. Tuy nhiên, những gì mình đang nói ở đây, là cấu trúc dữ liệu log. Log là một cấu trúc dữ liệu có thứ tự nhất quán mà chỉ hỗ trợ dạng nối thêm (append). Bạn không thể chỉnh sửa hay xóa các records từ nó. Nó được đọc từ trái sang phải và được đảm bảo thứ tự các item.
Một nguồn dữ liệu sẽ ghi message vào log và một hoặc nhiều consumer khác sẽ đọc message từ log tại thời điểm họ lựa chọn.
Mỗi entry trong log được định danh bởi một con số gọi là offset, hay nói một cách dễ hiểu hơn, offset giống như chỉ số tuần tự trong một array vậy.
Vì chuỗi/offset chỉ có thể được duy trì trên từng node/broker cụ thể và không thể được duy trì đối với toàn bộ cluster, do đó Kafka chỉ đảm bảo sắp xếp thứ tự dữ liệu cho mỗi partition.
Parsistence data trong Kafa
Kafka lưu trữ tất cả message vào disk (không hề lưu trên RAM) và được sắp xếp có thứ tự trong cấu trúc log cho phép kafka tận dụng tối đa khả năng đọc và ghi lên disk một cách tuần tự.
Nó là một cách lựa chọn khá phổ biến để lưu trữ dữ liệu trên disk mà vẫn có thể sử dụng tối đa hóa hiệu năng, có một số lý do chính dưới đây:
- Kafka có một giao thức mà nhóm các message lại với nhau. Điều này cho phép các request network nhóm các message lại với nhau, giúp giảm thiểu chi phí sử dụng tài nguyên mạng, server, gom các message lại thành một cục và consumer sẽ tìm nạp một khối message cùng một lúc – do đó sẽ giảm tải disk cho hệ điều hành.
- Kafka phụ thuộc khá nhiều vào pagecache của hệ điều hành cho việc lưu trữ dữ liệu, sử dụng RAM trên máy một cách hiệu quả.
- Kafka lưu trữ các messages dưới định dạng nhị phân xuyên suốt quá trình (producer > broker > consumer), làm cho nó có thể tận dụng tối ưu hóa khả năng zero-copy. Nghĩa là khi hệ điều hành copy dữ liệu từ pagecache trực tiếp sang socket, hoàn toàn bỏ qua ứng dụng trung gian là kafka.
- Đọc/ghi dữ liệu tuyến tính trên disk nhanh. Vấn đề làm cho disk chậm hiện nay thường là do quá trình tìm kiếm trên disk nhiều lần. Kafka đọc và ghi trên disk tuyến tính, do đó nó có thể tận dụng tối đa hóa hiệu suất trên disk.
Consumer và Consumer Group
Consumer đọc các messages từ bất kỳ partition nào, cho phép bạn mở rộng lượng message được sử dụng tương tự như cách các producer cung cấp message.
Consumer cũng được tổ chức thành các consumer groups cho một topic cụ thể – mỗi consumer bên trong group đọc message từ một partition duy nhất, để tránh việc có 2 consumer cùng xử lý đọc cùng một message 2 lần và toàn bộ group xử lý tất cả các message từ toàn bộ topic.
- Nếu bạn có số consumer > số partition, khi đó một số consumer sẽ ở chế độ rảnh rỗi bởi vì chúng không có partition nào để xử lý.
- Nếu bạn có số partition > số consumer, khi đó consumer sẽ nhận các message từ nhiều partition.
- Nếu bạn có số consumer = số partition, mỗi consumer sẽ đọc message theo thứ tự từ 1 partition.
Để dễ hiểu hơn, các bạn xem qua hình ảnh dưới đây
Trong bức ảnh ở trên, Server 1 giữ partition 0 và 3 và server 2 giữ các partition 1 và 2. Chúng ta có 2 consumer groups là A và B. Group A có 2 consumer và group B có 4 consumer. Consumer group A có 2 consumer, vậy nên mỗi consumer sẽ đọc message từ 2 partition.Trong consumer group B, số lượng consumer bằng số partition nên mỗi consumer sẽ đọc message từ 1 partition.
Kafka tuân theo các quy tắc được cung cấp bởi broker và consumer. Nghĩa là kafka không theo dõi các record được đọc bởi consumer và do đó không biết gì về hành vi của consumer. Việc giữ lại các messages trong một khoảng thời gian được cấu hình trước và nó tùy thuộc vào consumer, để điều chỉnh thời gian sao cho phù hợp. Bản thân consumer sẽ thăm dò xem Kafa có message nào mới hay không và cho Kafka biết những record nào chúng muốn đọc. Điều này cho phép chúng tăng/giảm offset mà consumer muốn, do đó nó có thể đọc lại các message đã được đọc rồi và tái xử lý các sự kiện trong trường hợp gặp sự cố.
Ví dụ: nếu Kafka được cấu hình để giữ các messages tồn tại trong một ngày và consumer bị down lâu hơn 1 ngày, khi đó consumer sẽ mất message. Tuy nhiên, nếu consumer chỉ bị down trong khoảng 1 giờ đồng hồ, khi đó nó hoàn toàn có thể bắt đầu đọc lại message từ offset mới nhất.
Vai trò của Zookeeper
Zookeeper đóng vai trò là nơi lưu trữ dữ liệu phân tán dạng key-value. Nó được tối ưu hóa cho tác vụ đọc nhanh nhưng ghi chậm. Kafka sử dụng Zookeeper để thực hiện việc bầu chọn leader của Kafka broker và topic partition. Zookeeper cũng được thiết kế cho khả năng chịu lỗi cao, do đó Kafka phụ thuộc khá nhiều vào Zookeeper.
Nó cũng được sử dụng để lưu trữ tất cả metadata như là:
- Offset cho mỗi partition của consumer group
- ACL (Access control list) – được sử dụng cho việc giới hạn truy cập/ủy quyền
- Quota của consumer/producer – số lượng message tối đa mỗi giây
- Partition Leader và trạng thái của chúng
Producer và consumer không tương tác trực tiếp với Zookeeper để biết leader của partition hay những metadata khác, thay vào đó chúng sẽ truy vấn metadata tới Kafka broker – sau đó Kafka tương tác với Zookeeper và gửi phản hồi metadata về lại cho chúng.
Kết luận
Kafka đang nhanh chóng trở thành trụ cột của đường ống dữ liệu đối với bất kỳ tổ chức nào. Kafka cho phép bạn có một lượng lớn các messages đi qua một phương tiện tập trung và lưu trữ chúng mà không cần phải lo lắng gì về những vấn đề như hiệu suất hay mất mát dữ liệu. Kafka có thể là thành phần trung tâm trong mô hình kiến trúc hướng sự kiện (event-driven) và cho phép bạn phân tách giữa ứng dụng này với ứng dụng khác.
Các câu hỏi thường gặp về Apache Kafka
Kafka Kafka là nền tảng streaming phân tán, có thể mở rộng và là sản phẩm mã nguồn mở.
Nó có thể thực hiện 3 khả năng chính như sau:
1. Cơ chế publish/subcribe tương tự như các hệ thống message queue doanh nghiệp khác.
2. Cơ chế lưu trữ stream các bản ghi trên nhiều node broker khác nhau, giúp khắc phục lỗi xảy ra.
3. Xử lý stream các bản ghi ngay khi nó vừa đến.
Nó có 4 thành phần khác nhau như sau:
1. Kakfa Broker
2. Zookeeper
3. Producer
4. Consumer
1. Sử dụng để theo dõi lưu lượng truy cập, giám sát web server.
2. Xử lý sự kiện