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

Eviction: đo thật một job quét xoá sạch key nóng dưới LRU, còn LFU giữ 199/200

Khi Redis chạm maxmemory, key bị đá ra trước cả khi TTL hết — và chính sách chọn key để đá quyết định cache còn dùng được hay không. Bài này đo thật trên Redis 7: làm nóng 200 key, cho một job quét tuần tự đi qua toàn bộ 2.000 key đúng một lượt, rồi đếm xem key nóng còn lại bao nhiêu. allkeys-lru giữ 18/200, allkeys-random giữ 11/200, allkeys-lfu giữ 199/200. Và đo luôn noeviction: 1.392/1.400 lệnh ghi bị từ chối với lỗi OOM command not allowed, tức bước điền cache của cache-aside hỏng hoàn toàn trong khi đọc vẫn chạy.

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

Hot key: đo thật một key hút 20,8% lưu lượng và dồn 4,44× tải lên đúng một shard

Hit ratio 100%, mọi biểu đồ xanh, mà một node Redis nóng rực còn các node khác ngồi chơi. Bài này đo thật trên 1 triệu request phân bố Zipf qua 10.000 key, dùng chính thuật toán CRC16 của Redis Cluster: key nóng nhất chiếm 20,81% toàn bộ lưu lượng, top 10 key chiếm 51,46%, và shard nặng nhất trong 16 shard gánh 4,44 lần mức trung bình. Thêm shard không chữa được vì một key luôn thuộc đúng một slot. Tách key nóng thành 16 bản sao kéo độ lệch xuống 2,44× và tách 100 key nóng nhất xuống 1,63×.

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

Cache phân tầng: đo thật L1 trong tiến trình cắt 97,6% lưu lượng Redis và nhanh hơn 800 lần

Mười phần trước đều coi Redis là tầng cache duy nhất. Bài này thêm một tầng L1 ngay trong bộ nhớ tiến trình và đo trên 300.000 request Zipf qua 10.000 key: L1 với TTL 1 giây kéo lưu lượng tới Redis từ 300.000 xuống 7.438 — cắt 97,6% — và độ trễ mỗi request từ 39,2µs xuống 2,95µs. Đo riêng từng tầng còn lộ ra chuyện bất ngờ: Redis 36,9µs chỉ nhanh hơn PostgreSQL 1,26 lần cho query điểm có index, còn L1 thì nhanh hơn Redis 800 lần. Cái giá đo được: mỗi instance giữ bản riêng và trả dữ liệu cũ đúng bằng TTL của L1.

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

Nén response API: đo thật gzip và brotli — JSON 21 KB còn 2,2 KB trong 125 µs, brotli-11 tốn 16,85 ms cho thêm 2%, và thân 11 byte nén xong thành 35 byte

Đo nén trên JSON thật từ PostgreSQL, từ 308 byte tới 2,09 MB: gzip-6 đưa 21,2 KB xuống 2,2 KB (10,6%) với 125 µs nén và 26 µs giải. Mức nén gần như không quan trọng với JSON — gzip-1 và gzip-9 chênh 0,3 điểm phần trăm — nhưng brotli-11 tốn 16,85 ms, gấp 135 lần brotli-4, để mua thêm 1 điểm. Hai trường hợp nén làm hại: thân dưới 100 byte phình thêm 24 byte, và JSON chứa ảnh base64 chỉ còn 75% nhưng tốn CPU gấp 17 lần. Kèm thương lượng Accept-Encoding qua HTTP thật, header Vary bắt buộc, và điểm hoà vốn theo băng thông tính từ số đo.

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

Chi phí TLS trên 10.000 kết nối đo thật: thêm 24,5 KB RAM mỗi kết nối idle, một lõi làm 4.350 bắt tay ECDSA mỗi giây nhưng chỉ 1.060 với RSA-2048, session ticket cắt 9% CPU với ECDSA và 80% với RSA, và Kyber768 chiếm 35% chi phí bắt tay

Server Go nhận 10.000 kết nối idle: plaintext 42 MB RSS, TLS 1.3 với ECDSA P-256 288 MB, tức thêm 24,5 KB mỗi kết nối, phần lớn là bộ đệm record chứ không phải heap. Server một lõi: TCP connect trần 27.114 lần mỗi giây và 21 µs CPU; bắt tay TLS ECDSA 4.350 mỗi giây và 212 µs; RSA-2048 1.060 mỗi giây và 941 µs vì chữ ký RSA chiếm 78%. Session ticket đưa cả hai về 192 µs: cắt 9% với ECDSA, 80% với RSA. Tắt Kyber768 hybrid: 6.575 mỗi giây và 139 µs, Kyber tốn 73 µs mỗi bắt tay. Với 16 worker một lõi bão hoà ở 5.328 mỗi giây; 4 lõi chỉ đạt 6.055 vì client thành nút thắt.

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

cgroups v2 giới hạn CPU đo thật: --cpus=0.5 đặt cpu.max 50000/100000 chứ không giấu bớt lõi, một khối việc 6 giây phình thành 77 giây ở --cpus=0.2, nproc vẫn báo đủ 10 lõi host, cpu.stat cho thấy luồng bị ghìm 50 trên 51 chu kỳ

cgroups giới hạn cái container dùng, khác namespace cô lập cái nó thấy. --cpus=X đặt cpu.max = quota/period: --cpus=0.5 là 50 ms chạy mỗi 100 ms rồi bị ghìm. Nhưng nproc vẫn báo đủ 10 lõi host, nên Go đặt GOMAXPROCS=10 và Java tính pool theo 10 lõi. Một luồng busy 5 giây ở --cpus=0.5 chỉ chạy 2,55 giây, bị ghìm 50 trên 51 chu kỳ, chờ 2,5 giây dù host rảnh, đọc qua cpu.stat. Cùng khối việc 6 giây chạy như nhau ở 1, 2 hay unlimited CPU nhưng thành 12 giây ở 0.5 và 77 giây ở 0.2. Một request 1 giây CPU biến thành 12 giây.