Danh sách bài viết

Bài 110: Anti-patterns Scaling & Incident: BGSAVE Killed bởi OOM

Bài cuối Module 9 tổng hợp 15 anti-pattern phổ biến khi deploy và scale Redis — từ cấu hình Sentinel sai quorum, Cluster thiếu replica, đến dùng KEYS trong production. Mỗi anti-pattern có mô tả hậu quả cụ thể và fix ngắn gọn. Nửa sau là phân tích incident thực tế: BGSAVE bị OOM Killer trên e-commerce 5M user trong peak sale — timeline 15 phút, root cause, cascade failure, và các thay đổi permanent sau đó. Kết thúc bằng tổng kết Module 9 và checklist production deployment.

01/06/2026
0 lượt xem
1

Mục Tiêu Bài Học

  • Nhận biết 15 anti-pattern scaling Redis phổ biến và hiểu hậu quả cụ thể của từng cái.
  • Phân tích incident BGSAVE OOM Killed theo timeline: từ fork đến cascade failure.
  • Hiểu tại sao maxmemory > 70% RAM kết hợp với COW tạo thành rủi ro OOM có thể tính toán được.
  • Nắm các bước fix permanent và lessons để không lặp lại trong production.
  • Dùng checklist deployment cuối Module 9 làm tài liệu tham chiếu khi chuẩn bị release.
2

Anti-patterns: HA & Topology

AP-1 — 2 Sentinels (even quorum)

Vấn đề: Sentinel cần quorum để bầu chọn master mới. Với 2 Sentinel, nếu 1 Sentinel mất kết nối (network partition, crash, maintenance), quorum không đủ — failover không xảy ra dù master thực sự đã chết. Tệ hơn: cả hai Sentinel đều "thấy" master là chính nên không ai hành động, dẫn đến split-brain tiềm tàng.

Fix: Tối thiểu 3 Sentinel, đặt ở 3 host/AZ khác nhau. sentinel monitor mymaster <ip> <port> 2 với quorum=2 trên 3 Sentinel.

AP-2 — Cluster với master không có replica

Vấn đề: Redis Cluster chia data thành 16384 slot, mỗi slot thuộc một master. Nếu một master crash mà không có replica, các slot đó mất hoàn toàn — Cluster chuyển sang trạng thái CLUSTER_FAIL và từ chối toàn bộ request. Không chỉ slot đó bị ảnh hưởng mà cả cluster ngừng phục vụ.

Fix: Mỗi master cần ít nhất 1 replica. Deploy với redis-cli --cluster create ... --cluster-replicas 1. Monitor bằng CLUSTER INFO để phát hiện node thiếu replica.

AP-3 — Single AZ deployment

Vấn đề: Đặt toàn bộ Redis node (master + replica + Sentinel) trong cùng một Availability Zone. Khi AZ đó down (sự cố nguồn, network, hoặc planned maintenance của cloud provider), toàn bộ Redis cluster mất theo.

Fix: Phân phối master và replica ra nhiều AZ. Với 3-master Cluster, mỗi master ở 1 AZ khác nhau; replica ở AZ khác master tương ứng.

3

Anti-patterns: Memory & OS

AP-4 — maxmemory > 80% RAM

Vấn đề: Khi Redis thực hiện BGSAVE hoặc BGREWRITEAOF, Linux fork một child process. Fork dùng Copy-on-Write (COW): ban đầu child và parent chia sẻ page, nhưng mỗi lần parent ghi một page trong khi child đang chạy, trang đó bị duplicate. Trong peak write, COW có thể nhân đôi bộ nhớ RSS. Nếu maxmemory đã chiếm > 80% RAM, không còn headroom cho COW — Linux OOM Killer sẽ kill Redis.

Fix: Giữ maxmemory < 70% RAM để dành 30% cho COW overhead, fragmentation, và page table copy. Trên server 32GB: maxmemory 22gb.

AP-5 — Transparent Huge Pages (THP) bật

Vấn đề: THP gộp nhiều page 4KB thành page 2MB. Khi COW xảy ra trên page 2MB, toàn bộ 2MB bị copy dù chỉ thay đổi vài byte. Trong trường hợp xấu, COW amplification có thể tăng lên 500×. Redis tự báo warning về điều này khi khởi động.

Fix:

# Tắt THP ngay lập tức (runtime):
echo never > /sys/kernel/mm/transparent_hugepage/enabled

# Vĩnh viễn (thêm vào /etc/rc.local hoặc systemd service):
echo never > /sys/kernel/mm/transparent_hugepage/enabled
echo never > /sys/kernel/mm/transparent_hugepage/defrag

AP-6 — Swap bật trên Redis host

Vấn đề: Khi Redis bị đẩy sang swap, đọc/ghi từ disk chậm hơn RAM khoảng 1000×. Latency chuyển từ sub-millisecond lên hàng trăm ms. Với Redis single-threaded, một operation swap là đủ để block toàn bộ client pipeline. Hệ thống coi đây là downtime trong thực tế.

Fix: Tắt swap hoặc giảm vm.swappiness=1 để OS cực kỳ tránh dùng swap. Kết hợp với maxmemory đúng để Redis không cần đến vùng swap.

sysctl vm.swappiness=1
# Kiểm tra Redis có đang dùng swap không:
cat /proc/$(pgrep redis-server)/smaps | grep -A 1 "^Swap:" | grep -v "^--$"
4

Anti-patterns: Key Design & Operations

AP-7 — Cluster không dùng hash tag cho multi-key ops

Vấn đề: Redis Cluster hash key để phân slot bằng CRC16. Nếu hai key ở hai slot khác nhau, bất kỳ command nào cần cả hai (MGET, MSET, SUNIONSTORE, Lua script, transaction MULTI/EXEC trên nhiều key) đều trả CROSSSLOT Keys in request don't hash to the same slot.

Fix: Dùng hash tag {tag} trong tên key. Chỉ phần trong {} được dùng để tính slot, nên user:{123}:profileuser:{123}:session luôn cùng slot.

# Sai — hai key có thể ở slot khác nhau:
MGET user:123:profile user:123:session

# Đúng — hash tag đảm bảo cùng slot:
MGET user:{123}:profile user:{123}:session

AP-8 — Big key không split

Vấn đề: Một HASH với 1M field, LIST với 500k item, hay STRING 10MB: bất kỳ command đọc toàn bộ (HGETALL, LRANGE 0 -1, GET) đều block Redis event loop hàng trăm ms. Việc di chuyển key giữa shard trong cluster cũng chậm theo.

Fix: Shard HASH lớn thành nhiều key nhỏ (user:hash:{123}:0, user:hash:{123}:1...). Giới hạn LIST bằng LTRIM sau mỗi LPUSH. Dùng HSCAN/SSCAN thay vì HGETALL/SMEMBERS.

AP-9 — Hot key không có mitigation

Vấn đề: Trong Redis Cluster, một key rất hot (ví dụ counter của flash sale item, leaderboard top entry) chỉ nằm trên 1 shard. Node đó chịu 100% CPU cho key đó trong khi các node khác rảnh. Cluster không tự cân bằng load cho hot key.

Fix: Kết hợp nhiều kỹ thuật theo mức độ:

  • Local in-process cache: giữ bản sao trong memory của app server với TTL ngắn (1–5s).
  • Read replica routing: route read đến replica bằng READONLY trong Cluster.
  • Sharded counter: thay vì 1 key counter:item:123, dùng N key counter:item:123:{shard} rồi cộng tổng khi cần đọc.
5

Anti-patterns: Commands & Eviction

AP-10 — DEL big key (blocking)

Vấn đề: DEL trên key lớn (LIST 500k item, HASH 1M field) giải phóng memory synchronously trong event loop — latency spike từ 100ms đến vài giây tùy size.

Fix: Dùng UNLINK thay cho DEL. UNLINK unlinking key khỏi keyspace ngay lập tức (O(1)) rồi đẩy việc giải phóng memory sang background thread.

# Sai:
DEL large_hash_key

# Đúng:
UNLINK large_hash_key

AP-11 — KEYS pattern trong production

Vấn đề: KEYS * hoặc KEYS user:* scan toàn bộ keyspace O(N) trong event loop single-threaded. Với 10M key, một lệnh KEYS có thể block Redis 1–2 giây, làm timeout tất cả client đang chờ.

Fix: Dùng SCAN 0 MATCH user:* COUNT 100 để scan theo cursor, mỗi lần chỉ xử lý batch nhỏ. Hoặc dùng cấu trúc dữ liệu phụ (SET để track key names) nếu cần lookup nhanh.

AP-12 — MONITOR trong production

Vấn đề: MONITOR stream mọi command đến client. Redis phải serialize và gửi mỗi command — overhead CPU tăng đáng kể, có thể lên 50% CPU trên instance tải cao. Không bao giờ dùng trên production lâu dài.

Fix: Chỉ dùng MONITOR trên dev/staging, hoặc production với time limit rất ngắn (< 30s) khi debug cụ thể. Dùng SLOWLOGLATENCY để diagnostic production.

AP-13 — noeviction với dataset có thể tăng

Vấn đề: Policy noeviction (mặc định) khiến Redis trả lỗi OOM command not allowed when used memory > 'maxmemory' thay vì evict key. Nếu dataset không có TTL và tiếp tục tăng, application sẽ nhận lỗi OOM khi ghi — thường xuất hiện ở peak traffic và là triệu chứng, không phải nguyên nhân.

Fix: Xác định rõ use case trước khi chọn policy:

  • Cache thuần: allkeys-lru hoặc allkeys-lfu.
  • Session (có TTL): volatile-lru hoặc volatile-lfu.
  • Data store không được mất: noeviction nhưng phải có maxmemory phù hợp + alerting.

AP-14 — Không monitor evicted_keys

Vấn đề: Eviction xảy ra silently. Nếu allkeys-lru đang evict hàng nghìn key/giây (do maxmemory quá thấp hoặc dataset tăng đột biến), application không biết — hit ratio giảm, nhưng không có error. Data đang mất mà không ai hay.

Fix: Alert trên evicted_keys từ INFO stats. Bình thường có thể có eviction nhỏ; spike đột ngột là dấu hiệu maxmemory quá chật hoặc dataset tăng bất thường.

# Kiểm tra eviction rate:
redis-cli INFO stats | grep evicted_keys

# Prometheus alert example:
# rate(redis_evicted_keys_total[5m]) > 100
6

Anti-patterns: Client & Failover

AP-15 — Sentinel client cache master address mãi mãi

Vấn đề: Client kết nối Redis qua Sentinel: lần đầu query Sentinel để lấy địa chỉ master, sau đó cache địa chỉ đó vĩnh viễn. Khi Sentinel thực hiện failover, master mới ở IP khác — client vẫn kết nối IP cũ (đã là slave hoặc đã down) và nhận lỗi. Application phải restart thủ công để lấy master mới.

Fix: Dùng Sentinel-aware client với auto re-discovery. Các client hiện đại (ioredis, redis-py, Jedis) hỗ trợ sentinel configuration và tự reconnect khi failover:

# redis-py — Sentinel-aware client:
from redis.sentinel import Sentinel

sentinel = Sentinel(
    [('sentinel-1', 26379), ('sentinel-2', 26379), ('sentinel-3', 26379)],
    socket_timeout=0.1
)
master = sentinel.master_for('mymaster', socket_timeout=0.1)
slave  = sentinel.slave_for('mymaster', socket_timeout=0.1)
// ioredis — Sentinel-aware:
const redis = new Redis({
  sentinels: [
    { host: 'sentinel-1', port: 26379 },
    { host: 'sentinel-2', port: 26379 },
    { host: 'sentinel-3', port: 26379 },
  ],
  name: 'mymaster',
});
7

Incident: BGSAVE OOM Killed — Bối Cảnh

Đây là tổng hợp từ dạng sự cố thực tế xảy ra nhiều lần tại các e-commerce platform khi không tuân thủ nguyên tắc memory headroom. Tình huống cụ thể:

  • Platform: E-commerce, ~5M user active.
  • Redis role: Cache sản phẩm, session user, shopping cart (session-cached).
  • Instance: Một Redis instance duy nhất, server 32GB RAM vật lý.
  • Config tại thời điểm incident: maxmemory 30gb, save 60 10000 (RDB enabled), appendonly no.
  • Dataset: 28GB (93.3% maxmemory, 87.5% RAM).
  • Eviction policy: allkeys-lru.
  • Replica: 1 replica ở AZ khác, cấu hình giống hệt master.
  • THP: Không được tắt (mặc định enabled trên Linux).
  • Swap: Không enabled.

T-1 ngày (chuẩn bị sale): Black Friday-like event. Dev team scale app servers (thêm instance), thêm Redis replica. Redis instance chính không được thay đổi gì — đánh giá "đã đủ tải".

8

Timeline Chi Tiết

T+0:00 — Sale bắt đầu (10:00 AM)

Traffic tăng đột ngột: từ ~100k req/s lên ~800k req/s trong 3 phút. Dataset tăng theo: 28GB → 30GB (maxmemory hit). Eviction bắt đầu — evicted_keys tăng vài trăm/giây, chưa gây alert.

T+0:10 — BGSAVE trigger

Config save 60 10000: khi có ≥ 10.000 write trong 60s, Redis trigger BGSAVE tự động. Với 800k req/s (tỷ lệ write ~20%), điều kiện này được đáp ứng sau khoảng 10 phút. Redis gọi fork().

T+0:10:01 — Fork phase

Fork phải copy page table của process cha — với dataset 30GB, page table khoảng 200MB. Trong thời gian copy này Redis parent bị block. Thực tế quan sát: fork latency 800ms. Các client đang chờ response nhận timeout. Error rate tăng đột ngột nhưng chưa đến mức alarm critical.

# Redis log tại thời điểm này:
# * Background saving started by pid 12847
# WARNING: 1 bigsave latency spikes in the last minute.
#          Worst case delta T was 812ms.

T+0:10:02 — COW amplify

BGSAVE child đang serialize RDB snapshot. Parent tiếp tục phục vụ ~800k req/s với write rate cao. Mỗi page bị ghi đều bị duplicate bởi COW. THP đang bật: mỗi lần COW không phải 1 page 4KB mà 1 huge page 2MB bị copy. RSS bắt đầu leo: 30GB → 33GB → 35GB trong vòng chưa đầy 60 giây.

T+0:10:03 — OOM Killer kích hoạt

Tổng RAM system 32GB. RSS của Redis đã vượt 32GB (35GB). Linux không có swap để overflow. OOM Killer chọn process có oom_score cao nhất — Redis đang chiếm nhiều RAM nhất. Redis bị kill.

# /var/log/kern.log:
# kernel: Out of memory: Kill process 12841 (redis-server) score 920 or sacrifice child
# kernel: Killed process 12841 (redis-server) total-vm:37748736kB, anon-rss:33554432kB

T+0:10:04 — Cascade bắt đầu

App servers nhận connection refused từ Redis. Session lookup fail → user logout đồng loạt. Cart data mất (lưu trong session). Sentinel phát hiện master down sau ~30s (default down-after-milliseconds 30000). Sentinel bầu chọn replica làm master mới — failover thành công về mặt kỹ thuật.

Tuy nhiên: replica được cấu hình giống hệt master — maxmemory 30gb, THP enabled, RDB save enabled. Ngay sau khi promote, replica (giờ là master mới) phải handle toàn bộ traffic đang dồn vào. Dataset của nó cũng ~29GB. Eviction + write rate cao → BGSAVE trigger lại sau khoảng 5 phút.

T+0:15 — Replica cũng bị OOM Killed

Replica mới promote cũng bị OOM Killer vì cùng nguyên nhân. Cả hai Redis instance đã down. Không còn Redis nào để failover sang. Application hoàn toàn không còn Redis.

T+0:15 — Manual intervention

Ops team vào xử lý. Bước đầu: disable BGSAVE trên cả hai instance bằng cách thêm save "" vào config, restart Redis (dataset rỗng). Restore từ RDB snapshot cuối cùng trên S3 — snapshot cách đó 1 giờ.

T+1:00 — Service khôi phục

Data stale 1 giờ. Session của user bị mất toàn bộ. Ops migrate sang instance 64GB RAM. Customer support nhận flood complaint.

9

Root Causes

  1. [CHÍNH] maxmemory 30GB trên server 32GB RAM (93.75%)
    Không có headroom cho fork COW. Với write rate 800k req/s và THP enabled, COW cần thêm 3–6GB trong vài giây. 32GB - 30GB = 2GB là không đủ. Đây là nguyên nhân trực tiếp.
  2. Transparent Huge Pages không được tắt
    THP khuếch đại COW từ 4KB/page lên 2MB/page. Với write rate cao, tốc độ tiêu thụ memory tăng gấp bội. Redis documentation cảnh báo rõ điều này.
  3. RDB save config không phù hợp với peak write rate
    save 60 10000 quá dễ trigger khi write rate lên 800k req/s. Không có mechanism tắt RDB khi detect peak traffic.
  4. Single instance, không shard
    Toàn bộ 30GB data trên một instance. Không thể redistribute load hoặc memory ngang hàng.
  5. Replica cấu hình giống hệt master — cascade failure by design
    Replica được tạo như bản sao nguyên xi của master (bao gồm cả maxmemory 30gb, THP, RDB save). Khi failover, replica gặp đúng điều kiện gây ra sự cố ban đầu.
10

Cascade Failure & Thiệt Hại

Timeline dẫn đến mức thiệt hại cao nhất:

  1. Master OOM Killed → Sentinel failover (đúng như thiết kế).
  2. Replica promote thành công → nhưng traffic dồn vào replica cũ cũng trigger BGSAVE sau 5 phút.
  3. Replica cũng OOM Killed → không còn Redis nào.
  4. Không có Redis: session fail, cart fail, không cache → DB hit trực tiếp tăng đột biến.
  5. Restore từ S3 snapshot mất ~45 phút (snapshot stale 1 giờ).

Thiệt hại tổng kết:

  • Downtime: ~1 giờ trong peak sale.
  • Direct revenue lost: ~$200,000 (estimate từ conversion rate × traffic × average order value).
  • Indirect: refunds + support cost ~$50,000.
  • Data mất: session của tất cả user đang active, cart data.
  • Tất cả user online (~50,000) bị logout và mất cart.
11

Fix Permanent

  1. maxmemory < 70% RAM — không thương lượng
    Trên server 64GB RAM mới: maxmemory 44gb. Để 20GB headroom cho COW, fragmentation, page table. Tỷ lệ 70% là conservative nhưng an toàn kể cả khi THP chưa kịp tắt.
  2. Tắt THP vĩnh viễn trên tất cả Redis host
    Thêm vào startup script hoặc systemd unit trước khi Redis start:
    echo never > /sys/kernel/mm/transparent_hugepage/enabled
    echo never > /sys/kernel/mm/transparent_hugepage/defrag
    Verify sau restart: cat /sys/kernel/mm/transparent_hugepage/enabled phải hiển thị [never].
  3. Disable RDB save, chuyển sang AOF với BGREWRITEAOF off-peak
    # redis.conf — production:
    save ""
    appendonly yes
    appendfsync everysec
    auto-aof-rewrite-percentage 100
    auto-aof-rewrite-min-size 1gb
    BGREWRITEAOF cũng dùng fork nhưng kiểm soát được thời điểm gọi — schedule vào giờ thấp điểm.
  4. Migrate sang Redis Cluster 3 shard × 2 node (master + replica)
    Mỗi shard chịu ~10GB data thay vì 30GB. OOM headroom tính theo shard, không theo toàn bộ dataset. Đồng thời replica của mỗi shard có maxmemory phù hợp với RAM của node đó, không copy nguyên config master.
  5. Replica cấu hình độc lập
    Replica giữ cùng maxmemory nhưng khi promotion, Ops có runbook để điều chỉnh config trước khi mở traffic. Dùng Ansible để enforce config đúng.
  6. Pre-warm cache trước peak event
    Script chạy trước 30 phút: nạp sản phẩm trending, session warm-up. Giảm write burst ngay khi sale bắt đầu.
12

Lessons Learned

  1. maxmemory > 70% RAM là time bomb có thể tính toán được
    Đây không phải edge case — đây là behavior được document rõ trong Redis documentation. Fork COW overhead là predictable nếu biết write rate và THP status. Có thể ước tính: peak RSS ≈ dataset × (1 + write_ratio_during_bgsave). Với dataset 30GB và write_ratio 30%, peak RSS ≈ 39GB — vượt RAM 32GB là chắc chắn.
  2. THP phải được tắt trước khi Redis start, không phải sau
    Redis warning về THP khi khởi động bị nhiều team bỏ qua vì hệ thống "vẫn chạy được". Nó chỉ bị gặp vấn đề khi BGSAVE chạy đồng thời với write rate cao — điều không xảy ra hàng ngày.
  3. Failover design phải tính đến cascade: replica không được có cùng vulnerability
    Sentinel failover là đúng, nhưng nếu backup có cùng vấn đề với primary thì failover chỉ mua thêm 5 phút. Replica cần có cấu hình được review độc lập — không chỉ copy config.
  4. Load test phải include BGSAVE simulation
    Load test thông thường tăng QPS và đo latency. Ít team test kịch bản: "tăng QPS đồng thời với BGSAVE đang chạy". Đây là kịch bản chính xác gây ra incident.
    # Trigger BGSAVE thủ công trong khi load test đang chạy:
    redis-cli BGSAVE
    # Quan sát RSS:
    watch -n 1 'redis-cli INFO memory | grep rss'
  5. Sale event cần capacity planning riêng cho data layer
    Mọi năm team đều scale app server cho peak event. Redis thường bị bỏ qua vì "cache, không phải DB". Nhưng với session + cart trong Redis, đây là single point of failure cho user experience.
  6. Sentinel failover là cần thiết nhưng không đủ nếu root cause không được address
    Sentinel đã hoạt động đúng — nó failover trong 30s. Vấn đề là sau failover, replica gặp chính xác cùng điều kiện. Tính sẵn sàng cao cần giải quyết root cause, không chỉ thêm failover layer.
13

Tổng Kết Module 9

Module 9 Production & Scaling gồm 11 bài (100–110), đi qua toàn bộ vòng đời một Redis deployment production-ready:

  • Replication (Bài 100–101): Master-Replica setup, replication lag, INFO replication, partial resync (PSYNC2), diskless replication.
  • Sentinel (Bài 102): Kiến trúc Sentinel, quorum, failover, Sentinel-aware client, cấu hình và vận hành.
  • Redis Cluster (Bài 102–103): Hash slot, resharding, node add/remove, CROSSSLOT, hash tag convention.
  • Monitoring (Bài 103): INFO sections (server, clients, memory, persistence, stats, replication), SLOWLOG, CLIENT LIST, MEMORY USAGE/DOCTOR, LATENCY, redis_exporter + Prometheus + Grafana, alert thresholds.
  • Benchmarking (Bài 104): redis-benchmark, memtier_benchmark, capacity planning từ throughput và latency numbers.
  • Memory Tuning (Bài 105): Encoding internals (listpack → skiplist/hashtable), ngưỡng encoding, active defragmentation, OS tuning.
  • Eviction Policies (Bài 106): LRU vs LFU mechanics, allkeys vs volatile, noeviction, chọn policy theo use case.
  • Big Keys & Hot Keys (Bài 107–108): Detection (MEMORY USAGE, --bigkeys, --hotkeys), mitigation (shard, HSCAN, local cache, sharded counter, replica routing).
  • Fork & COW (Bài 109): Fork latency, COW mechanics, THP amplification, persistence config cho production (AOF vs RDB), headroom calculation.
  • Anti-patterns & Incident (Bài 110): 15 anti-pattern tổng hợp, incident BGSAVE OOM Killed end-to-end.
14

Checklist Production Deployment

Danh sách này dùng làm gate trước khi đưa Redis vào production. Mỗi mục cần được verify, không chỉ assume.

High Availability

  • [ ] Triển khai 3+ Sentinel (số lẻ) ở 3 host/AZ riêng, hoặc Redis Cluster với 3+ master + replica.
  • [ ] Mỗi master có ít nhất 1 replica, replica không cùng AZ với master.
  • [ ] Replica có cấu hình được review riêng — không copy nguyên xi từ master.
  • [ ] Failover test: shutdown master thủ công, verify Sentinel elect master mới trong < 60s, client reconnect tự động.

Memory & OS

  • [ ] maxmemory < 70% RAM — tính theo RAM vật lý của instance, không phải RAM available.
  • [ ] Transparent Huge Pages tắt: cat /sys/kernel/mm/transparent_hugepage/enabled[never].
  • [ ] vm.overcommit_memory=1 (cho phép fork không bị ENOMEM ngay cả khi free RAM thấp).
  • [ ] Swap tắt hoặc vm.swappiness=1. Verify bằng free -hswapon --show.
  • [ ] Eviction policy chọn đúng use case — document lý do chọn.

Persistence

  • [ ] Quyết định rõ RDB vs AOF vs không (pure cache không cần persistence).
  • [ ] Nếu dùng RDB: tính peak RSS = dataset × (1 + write_ratio), verify không vượt RAM.
  • [ ] Nếu dùng AOF: appendfsync everysec là balance tốt giữa safety và performance.
  • [ ] Backup RDB snapshot định kỳ sang S3 hoặc object storage ngoài host.
  • [ ] Verify restore từ backup thực tế (không chỉ test write backup).

Monitoring & Alerting

  • [ ] redis_exporter + Prometheus + Grafana dashboard running.
  • [ ] Alert: used_memory_rss / used_memory (fragmentation ratio) > 1.5.
  • [ ] Alert: evicted_keys spike > threshold.
  • [ ] Alert: replication lag > 10s.
  • [ ] Alert: blocked_clients > 0 cho production use case.
  • [ ] SLOWLOG threshold config: slowlog-log-slower-than 10000 (10ms).

Key Design & Operations

  • [ ] Hash tag convention documented nếu dùng Cluster + multi-key ops.
  • [ ] Không có KEYS hoặc SMEMBERS large set trong production code.
  • [ ] DEL big key thay bằng UNLINK.
  • [ ] Big key và hot key detection chạy định kỳ (weekly redis-cli --bigkeys --hotkeys).

Capacity & Load Test

  • [ ] Load test đã chạy đến peak QPS dự kiến.
  • [ ] Load test bao gồm BGSAVE simulation trong khi peak write đang chạy.
  • [ ] Capacity planning cho peak event (sale, launch) có section riêng cho Redis.
  • [ ] Pre-warm cache script sẵn sàng trước event.
15

Bài Tiếp Theo

Module 10 chuyển sang Hardening: tại sao Redis mặc định không an toàn cho public network, AUTH, ACL (Access Control List), TLS transport, network isolation, và cách disable các dangerous command trong production.

Tham khảo