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

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

Kiểm thử tích hợp với PostgreSQL thật, đo thật: rollback mỗi test 2,9 ms, cơ sở dữ liệu mới mỗi test 20,5 ms, container mới 0,8 giây — và sáu lỗi ứng dụng mà SQLite trong bộ nhớ cho qua cả sáu, PostgreSQL từ chối cả sáu

Năm cách cô lập test tích hợp trên cùng một khối việc, đo bằng go test -count=30: pool không dọn 3,4 ms, transaction rồi rollback 2,9 ms, truncate 5,7 ms, schema mỗi test 9,1 ms, cơ sở dữ liệu mỗi test 20,5 ms; container postgres:16 mới sẵn sàng sau 0,8 giây. Rollback rẻ nhất nhưng vỡ khi mã dưới test tự mở kết nối và commit: nó không thấy dữ liệu mồi chưa commit, test đỏ oan. Rồi sáu lỗi ứng dụng chạy cùng mã test trên SQLite trong bộ nhớ và PostgreSQL thật: varchar quá dài, integer tràn, khoá ngoại, LIKE hoa thường, so sánh kiểu, GROUP BY. SQLite cho qua 6/6, PostgreSQL bắt 6/6.

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

Mạng không đáng tin: đo thật bằng tc netem giữa hai container — mất gói 30% vẫn 137/200 thành công nhưng p99 lên 420 ms, và 10 đơn hàng được tạo mà client tưởng là lỗi

Mở đầu sê-ri hệ thống phân tán bằng cách làm hỏng mạng có chủ đích: tc netem trên một container Go gọi sang container khác. Trễ 50 ms thành 107 ms mỗi request vì bắt tay TCP; mất gói 5% làm p99 nhảy từ 0,3 lên 209 ms vì TCP truyền lại theo bậc 200/400/800 ms; mất 30% vẫn 137/200 thành công nhưng tối đa 829 ms. Phép đo quan trọng nhất: dưới mất gói 30%, client thấy 125 thành công và 75 lỗi, server đếm 135 đơn đã tạo — 10 request client tưởng lỗi nhưng server đã làm. Tải 1 MB ở mất gói 15% không lỗi lần nào, chỉ chậm gấp 160 lần. Phân vùng 3 giây được phát hiện sau đúng một timeout.

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

Cache invalidation: đo thật đảo thứ tự hai dòng code làm tỉ lệ đọc sai nhảy từ 7,26% lên 66,82%

Cache-aside chỉ dựa vào TTL thì dữ liệu cũ tới cả phút. Xoá cache khi ghi là cách chữa — nhưng xoá vào lúc nào thì quan trọng hơn người ta tưởng. Đo thật trên Go + Redis + PostgreSQL với TTL 300s để mọi tính mới phải đến từ invalidation: ghi DB rồi xoá cache cho 7,26% lượt đọc sai và cache luôn khớp lại sau đó; đảo lại thành xoá cache rồi ghi DB cho 66,82% và cache KẸT ở giá trị sai cho tới khi TTL hết. Hai con số đó còn là hai loại lỗi khác hẳn nhau.

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

Bộ nhớ và big key trong Redis: một key 34 MB có thể làm nghẽn cả server, và vì sao đừng bao giờ KEYS *

Redis chạy một luồng — nên một lệnh O(n) trên key khổng lồ chặn mọi client khác. Bài này đo thật trong redis-lab: một hash 500.000 field chiếm 34,5 MB; HGETALL trên nó mất 224ms (so với 1ms cho hash nhỏ) và suốt thời gian đó cả server khựng; và KEYS * quét toàn bộ keyspace O(n) chặn server, trong khi SCAN duyệt từng lô không block. Hiểu để một key hay một lệnh không kéo sập Redis.

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

Hit ratio: đo thật vì sao cửa sổ 44,8% mà tích luỹ vẫn báo 95,8%, và vì sao 98% tệ hơn 90%

Hit ratio là con số đầu tiên ai cũng đo, và là con số dễ hiểu sai nhất. Đo thật trên Go + Redis + PostgreSQL: cho một bot quét id lạ trong 3 giây, hit ratio cửa sổ 1 giây rơi xuống 44,82% ngay lập tức trong khi hit ratio tích luỹ chỉ chạm đáy 90,21% — cảnh báo đặt ở ngưỡng 90% không hề kêu. Và đo hai dịch vụ: A hit 98,01% đặt lên database 375 truy vấn mỗi giây, B hit 90,20% chỉ 80 — hit ratio là tỉ lệ, còn database chịu con số tuyệt đối.

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

Persistence trong Redis: RDB và AOF — Redis có mất dữ liệu khi chết không, và đánh đổi độ bền vs hiệu năng

Redis sống trong RAM, nên câu hỏi sống còn: tắt đi có mất dữ liệu không? Redis có hai cơ chế ghi xuống đĩa với hai triết lý khác nhau. Bài này đo thật trong redis-lab: RDB snapshot (BGSAVE tạo dump.rdb nhỏ gọn, nhưng mất dữ liệu giữa hai lần chụp); AOF ghi mọi lệnh với appendfsync everysec (bền hơn, mất tối đa 1 giây, file lớn hơn). Cùng 1000 key, RDB 16.881 byte vs AOF 21.161 byte. Chọn đúng theo vai trò cache hay store.