# Kafka Fetch and HTTP Polling

***

❓Trong xây dựng mô hình realtime chatting, dùng Kafka lưu messages với websocket là giao thức truyền event thì có tối ưu hơn việc sử dụng thuần Kafka không.

Trước khi đi sâu vào so sánh, hãy cùng tìm hiểu cách mỗi phương pháp hoạt động. Cụ thể là giữa **HTTP Polling** và **Kafka Consumer Fetch (Optimized Pull).**

## **HTTP Polling (Traditional Pull)** <a href="#heading-http-polling-traditional-pull" id="heading-http-polling-traditional-pull"></a>

**Cách hoạt động:**

* **Client liên tục gửi request hỏi server** theo chu kỳ (ví dụ: mỗi 1 giây) dù server có dữ liệu mới hay không.
* **Server luôn phải trả lời** ngay lập tức (có thể trả về `204 No Content` nếu không có dữ liệu).
* **Ưu điểm**: Đơn giản, dễ triển khai.
* **Nhược điểm**:
  * Lãng phí tài nguyên (nhiều request rỗng).
  * **Độ trễ cao** (nếu dữ liệu mới xuất hiện ngay sau khi polling, client phải đợi đến chu kỳ tiếp theo).

## **Kafka Consumer Fetch (Optimized Pull)** <a href="#heading-kafka-consumer-fetch-optimized-pull" id="heading-kafka-consumer-fetch-optimized-pull"></a>

**Cách hoạt động:**

* **Consumer gửi fetch request đến Kafka broker**, nhưng broker có thể **không trả lời ngay lập tức**.
* **Broker giữ kết nối mở** (long-polling) đến khi:
  * Có đủ dữ liệu theo cấu hình (ví dụ: `fetch.min.bytes=1`).
  * Hết thời gian chờ (`fetch.max.wait.ms=500`).
* **Ưu điểm**:
  * Giảm request rỗng: Broker chỉ trả về dữ liệu khi có message mới hoặc hết timeout.
  * Giảm độ trễ: Nếu message xuất hiện ngay sau fetch request, broker trả về ngay.
* **Nhược điểm**:
  * Consumer vẫn phải chủ động gửi request (không phải push thực sự).

## So sánh số Request rỗng <a href="#heading-so-sanh-so-request-rong" id="heading-so-sanh-so-request-rong"></a>

***Giả sử:***

* Thời gian quan sát: 10 phút = 600 giây
* Không có tin nhắn nào trong suốt 10 phút

***HTTP Polling (1 giây/lần)***

* Mỗi giây gửi 1 request → tổng số request:

600s1s/request=600

***Kafka Fetch (timeout 1000ms = 1 giây)***

* Mỗi request chờ tối đa ***1000ms*****&#x20;(1 giây)**.
* Nếu không có dữ liệu, broker sẽ đóng request sau ***1000ms*** → Consumer phải gửi lại request mới ngay lập tức.
* Số request trong 600 giây:

600s1s/request=600

→ Thoạt nhìn, số request **là như sau**. Tuy nhiên ta cần xem xét cơ chế tối ưu của Kafka.

## **Kafka Fetch tối ưu hơn nhờ cơ chế "long-polling"** <a href="#heading-kafka-fetch-toi-uu-hon-nho-co-che-long-polling" id="heading-kafka-fetch-toi-uu-hon-nho-co-che-long-polling"></a>

### **Điểm khác biệt chính:** <a href="#heading-diem-khac-biet-chinh" id="heading-diem-khac-biet-chinh"></a>

* **HTTP Polling**:
  * Mỗi request độc lập, server **luôn trả lời ngay** (kể cả rỗng).
  * Tốn tài nguyên cho **cả request và response**.
* **Kafka Fetch**:
  * Broker **giữ kết nối mở** đến khi có dữ liệu hoặc hết timeout (500ms).
  * Nếu không có dữ liệu, broker chỉ gửi **1 response rỗng sau 500ms**.
  * Consumer không cần gửi request mới liên tục (vì 1 request có thể chờ đến 500ms).

### Sự tối ưu của Kafka Fetch: <a href="#heading-su-toi-uu-cua-kafka-fetch" id="heading-su-toi-uu-cua-kafka-fetch"></a>

* **1 request Kafka sẽ mở kết nối tồn tại trong 1 giây** (không phải gửi mới mỗi 1 giây). Do đó nếu message tới trong đoạn thời gian đó thì sẽ được gửi ngay lập tức tới client chứ không cần phải đợi tới chu kì sau như HTTP Polling. Điều này giúp giảm độ trễ message tới client.
* Mỗi request trong Kafka tiêu tốn ít tài nguyên hơn so với HTTP Polling, vì không cần thiết lập lại kết nối hay gửi các header lặp lại. Nhờ sử dụng kết nối TCP liên tục, mỗi request cũng nhẹ hơn.
* Ngoài `fetch.max.wait.ms`, ta còn có thể thiết lập `fetch.min.bytes` để chỉ định lượng dữ liệu tối thiểu mà consumer muốn nhận trước khi Kafka gửi phản hồi. Điều này giúp giảm số lần request nếu lượng dữ liệu nhỏ, tối ưu hiệu suất truyền tải.

### Ví dụ <a href="#heading-vi-du" id="heading-vi-du"></a>

**HTTP Polling (1s):**

* Tin nhắn đến tại thời điểm `t = 1000.5ms`.
* Client chỉ nhận được ở request tiếp theo (`t = 2000ms`) → **độ trễ 999.5ms**.

**Kafka Fetch (1s):**

* Tin nhắn đến tại `t = 1000.5ms`.
* Request hiện tại đang chờ (timeout tại `t = 2000ms`) → nhận ngay ở `t = 1000.5ms`.
* **Độ trễ ≈ 0ms**.

→ Kafka giảm độ trễ **từ 999.5ms xuống \~0ms** trong trường hợp này.

## **Kết luận** <a href="#heading-ket-luan" id="heading-ket-luan"></a>

Kafka **“không hoàn toàn im lặng”** khi không có message, nhưng cơ chế **long-polling** giúp:

* Giảm số lần trả về response rỗng thực tế. Nếu có message trong khoảng thời gian chờ thì sẽ không trả về response rỗng.
* Giảm độ trễ khi message mới xuất hiện. Do thiết lập kết nối duy trì trong 1 khoảng thời gian và sẽ đẩy message tới client ngay nếu có.
* Tiết kiệm tài nguyên mạng so với HTTP Polling truyền thống nhờ sử dụng kết nối TCP.
