# Cửa sổ thời gian, event time và dữ liệu đến trễ trong stream

> Dòng dữ liệu vô hạn không thể cộng tổng một lần. Xem demo cửa sổ cố định, trượt và phiên, rồi hiểu event time, watermark và cách tránh xử lý trùng.

Canonical URL: https://learn.chabulab.com/vi/system-design/cua-so-thoi-gian-va-du-lieu-den-tre. Kiểm tra thông tin: 2026-11-03.

- Muốn có một con số từ dòng vô hạn thì phải cắt nó thành các cửa sổ thời gian.
- Tính theo event time, tức lúc sự kiện thật sự xảy ra, chứ không theo lúc hệ thống nhận được.
- Watermark quyết định chờ dữ liệu trễ bao lâu. Exactly-once cần checkpoint và ghi idempotent.

Cộng tổng một file rất dễ vì file có điểm cuối. Dòng sự kiện thì không, nên stream cần những khái niệm mà batch không phải lo.

## Vì sao stream cần cửa sổ?

Dòng vô hạn không có lúc nào "cộng xong". Ta cắt nó thành các cửa sổ thời gian rồi tính trong từng cửa sổ.

Các chấm dưới đây là sự kiện đến theo thời gian. Thanh bên dưới là cửa sổ, con số là số sự kiện trong cửa sổ khi nó đóng lại. Đổi loại cửa sổ để thấy cùng một dòng dữ liệu cho ra kết quả khác nhau.

*Cùng 26 sự kiện, đếm theo ba loại cửa sổ.*

## Nên dùng loại cửa sổ nào?

| Loại | Hoạt động | Hợp với |
| --- | --- | --- |
| Cố định (tumbling) | Nối đuôi nhau, không chồng lên nhau | Số liệu định kỳ, ví dụ số đơn mỗi phút |
| Trượt (sliding) | Chồng lên nhau theo bước trượt | Số liệu mượt, ví dụ trung bình trượt |
| Phiên (session) | Đóng khi im lặng đủ lâu | Một lượt truy cập của người dùng |

## Event time khác processing time thế nào?

**Event time** là lúc sự kiện thật sự xảy ra. **Processing time** là lúc hệ thống nhận được nó. Mạng chậm làm hai mốc lệch nhau, nên tính toán đúng phải dựa vào event time. Nếu tính theo processing time, cùng dữ liệu đó chạy lại sẽ cho kết quả khác.

## Watermark là gì?

Watermark là mốc thời gian mà hệ thống tin rằng các sự kiện cũ hơn đã đến đủ. Khi watermark đi qua cuối một cửa sổ, cửa sổ đóng và kết quả được phát ra.

Sự kiện đến sau mốc này là **dữ liệu trễ**, cần quy tắc riêng: bỏ qua, ghi ra chỗ khác để xem lại, hoặc cập nhật lại kết quả. Đây là một đánh đổi: chờ lâu thì đủ dữ liệu hơn nhưng kết quả ra chậm hơn.

## Trạng thái được giữ thế nào khi máy sập?

Bộ đếm, tổng tiền và phiên đăng nhập là trạng thái. Stream processor lưu chúng định kỳ bằng **checkpoint**. Khi máy sập, nó khôi phục từ checkpoint gần nhất rồi đọc lại sự kiện từ vị trí tương ứng trong log.

## At-least-once và exactly-once khác gì?

| Đảm bảo | Ý nghĩa | Hệ quả |
| --- | --- | --- |
| At-most-once | Gửi tối đa một lần | Có thể mất dữ liệu |
| At-least-once | Gửi đến khi chắc chắn nhận | Không mất, nhưng có thể trùng |
| Exactly-once | Kết quả như thể xử lý đúng một lần | Cần checkpoint và ghi idempotent |

Cách làm phổ biến: chấp nhận giao nhận at-least-once và làm cho bước ghi **idempotent**, ví dụ ghi theo khoá để xử lý lại không nhân đôi kết quả.

## Sai lầm hay gặp

- **Tính theo processing time cho tiện.** Kết quả đổi theo tốc độ mạng và không tái lập được khi chạy lại.
- **Đặt watermark quá chặt.** Dữ liệu trễ bị bỏ nhiều. Đặt quá rộng thì kết quả ra chậm. Hãy đo độ trễ thực tế rồi mới chọn.
- **Tin rằng hàng đợi đảm bảo không trùng.** Hầu hết chỉ đảm bảo at-least-once, nên bước ghi vẫn phải idempotent.
- **Không có đường xử lý dữ liệu trễ.** Ít nhất hãy đếm và ghi lại chúng để biết mình đang mất bao nhiêu.

## Kiểm tra lại

1. Vì sao stream cần cửa sổ thời gian khi muốn tính tổng?
   Xem đáp án: Vì dòng vô hạn không có điểm cuối để cộng một lần, nên phải cắt thành các đoạn. Muốn có một con số thì phải có biên. Cửa sổ chính là cách đặt biên cho dòng không có điểm cuối.
2. Cửa sổ trượt dài 10 giây, bước trượt 5 giây. Một sự kiện thuộc mấy cửa sổ?
   Xem đáp án: 2 cửa sổ. Mỗi cửa sổ chồng lên cửa sổ kế tiếp một nửa chiều dài, nên mỗi sự kiện rơi vào hai cửa sổ.
3. Một đơn hàng tạo lúc 10:03:12 nhưng hệ thống nhận lúc 10:03:40 do mạng chậm. Báo cáo theo phút nên xếp nó vào đâu?
   Xem đáp án: Theo event time, phút 10:03. Event time phản ánh lúc việc thật sự xảy ra, nên kết quả không đổi theo tốc độ mạng.

## Nguồn

- [Apache Flink: thời gian và watermark](https://nightlies.apache.org/flink/flink-docs-stable/docs/concepts/time/)
- [Apache Flink: cửa sổ](https://nightlies.apache.org/flink/flink-docs-stable/docs/dev/datastream/operators/windows/)
