Bài viết mới nhất

Tổng 2300 bài
Lập trình 22/09/2026 6 phút

Cardinality explosion: một label user_id làm nổ metric store 2000 lần — nguyên nhân số 1 sập Prometheus

Label làm metric mạnh lên (cắt lát theo method, status), nhưng đặt sai một label là tự tay cho nổ. Bài này đo thật với client_golang: cùng một counter, label an toàn {method, status} sinh 10 chuỗi thời gian; thêm một label user_id thành 20.000 chuỗi — nổ đúng 2000 lần. Vì cardinality là TÍCH số giá trị mọi label, không phải tổng; và user_id/request_id/URL trong thực tế là vô hạn, chuỗi tăng không ngừng tới khi Prometheus ngốn hết RAM và sập.

Lập trình 22/09/2026 6 phút

Sampling: head sampling 1% bỏ sót 99% lỗi, error-biased giữ 4% mà bắt 100% lỗi

Trace và log mỗi request thì đúng nhất, nhưng hàng triệu request/ngày là khối dữ liệu không kham nổi. Sampling giảm khối lượng — nhưng sampling ngẫu nhiên (head) bỏ mù đúng thứ cần thấy: lỗi hiếm. Bài này đo thật trên 100.000 trace: head sampling 1% chỉ bắt 14/1029 lỗi (bỏ sót 99%); error-biased sampling giữ tổng cộng chỉ 4% mà bắt trọn 1029/1029 lỗi. Cùng bàn cái giá của tail sampling và vì sao metric không sample.

Lập trình 22/09/2026 7 phút

Tổng kết Observability: ghép metric, trace, log thành một bức tranh — và checklist thực chiến

Mười một phần qua ta dựng từng mảnh observability bằng demo đo thật. Bài cuối ghép chúng lại: một request duy nhất phát cả ba tín hiệu — metric, trace, log — chia sẻ cùng một trace_id, và chính trace_id đó là sợi chỉ nối metric báo động với log và trace để điều tra. Kèm bảng tổng hợp mọi con số đo thật xuyên suốt loạt bài và một checklist gắn observability vào service của bạn.

Lập trình 22/09/2026 6 phút

Consumer lag: con số nói cho bạn biết hệ thống Kafka sắp sập trước khi nó sập

Nếu chỉ được theo dõi một chỉ số của Kafka, hãy chọn consumer lag — khoảng cách giữa chỗ producer đã ghi và chỗ consumer đã xử lý. Bài này đo thật trong lab: lag phình từ 700 lên 1200 khi producer ghi nhanh hơn consumer, rồi co về 0 khi consumer đuổi kịp. Hiểu công thức LAG = LOG-END − CURRENT, phân biệt offset lag với time lag, và biết dấu hiệu nguy hiểm thật: lag tăng đều không ngừng.

Lập trình 22/09/2026 6 phút

MVCC và VACUUM: vì sao UPDATE làm bảng phình 9 lần dù số dòng không đổi

PostgreSQL không sửa dòng tại chỗ — mỗi UPDATE tạo một phiên bản mới và để lại 'xác chết' (dead tuple). Bài này đo thật: một bảng 100.000 dòng sau 8 lần UPDATE toàn bộ phình từ 3.5MB lên 31MB với 799.810 dead tuple, dù vẫn đúng 100.000 dòng sống. VACUUM dọn dead tuple (dead về 0) nhưng không trả đĩa; chỉ VACUUM FULL trả bảng về 3.5MB — nhưng khoá cả đọc. Hiểu MVCC để không bị bloat bất ngờ.

Lập trình 22/09/2026 8 phút

Phân trang offset và keyset: đo thật trên 400.000 dòng, trang sâu chậm 90 lần và trùng dữ liệu khi có bài mới

Mở đầu sê-ri thiết kế API bằng thứ gần như API nào cũng có: phân trang. Mình dựng HTTP server Go với hai cách — `?page=N` dùng OFFSET và `?after=<id>` dùng keyset — trên bảng reviews 400.000 dòng và đo qua HTTP. Ở trang 1–100 hai cách bằng nhau; tới trang 19.999 offset mất 13,62 ms còn keyset vẫn 0,15 ms. EXPLAIN lộ lý do: offset đọc 200.000 dòng index để trả 20. Duyệt hết bảng: 28,5 giây so với 0,96 giây. Và khi có 5 review mới chèn vào giữa hai lần lật trang, offset trả 5 dòng trùng, keyset không trùng dòng nào.