Điều kiện tiên quyết: Đây là Phần 2 của Khóa Học System Design. Hãy đọc Phần 1: Tư Duy System Design trước để nắm vững các khuôn rập đánh đổi (trade-off frameworks) nền tảng.

Answer-first: Cân bằng tải L4 (L4 load balancing) định tuyến traffic dựa trên dữ liệu siêu dữ liệu tầng giao vận (transport-layer) (IP/TCP/UDP) — chi phí CPU cực kỳ bèo bọt (minimal CPU overhead) nhưng độ thông minh thì hạn hẹp. Cân bằng tải L7 (L7 load balancing) thì xoi mói vào các headers, paths, và cookies của HTTP — cho phép định tuyến dựa trên nội dung (content-based routing) và rà soát sức khỏe cấp cao, bù lại phải trả giá bằng chi phí xử lý cao hơn cho từng cái request (higher processing overhead per request).


So Găng Cân Bằng Tải L4 vs L7 — Bảng Tóm Tắt Chốt Hạ

Answer-first: Sự khác biệt cốt lõi nằm ở vị trí ra quyết định định tuyến trên cái tháp mạng (network stack). L4 (Tầng Giao vận - Transport Layer) định tuyến ở đẳng cấp TCP/UDP xài tới cặp đôi IP+port. L7 (Tầng Ứng dụng - Application Layer) định tuyến ở đẳng cấp HTTP xài tới headers, URLs, và payloads (ruột dữ liệu).

Mổ Xẻ Kiến Trúc (Architecture Comparison)

graph TD
    subgraph l4["Cân bằng tải L4 (Tầng Giao vận)"]
        C1([Khách]) -->|"TCP SYN → dst:80"| LB1["L4 LB\n(HAProxy/IPVS)"]
        LB1 -->|"Chuyển tiếp luồng TCP\n(Ghi đè IP - IP rewrite)"| B1["Backend 1\n:8080"]
        LB1 -->|"Chuyển tiếp luồng TCP"| B2["Backend 2\n:8080"]
        LB1 -->|"Chuyển tiếp luồng TCP"| B3["Backend 3\n:8080"]
    end

    subgraph l7["Cân bằng tải L7 (Tầng Ứng dụng)"]
        C2([Khách]) -->|"HTTP GET /api/v1"| LB2["L7 LB\n(Nginx/Envoy)"]
        LB2 -->|"Đường dẫn: /api/* → service-api"| S1["API Service"]
        LB2 -->|"Đường dẫn: /static/* → CDN"| S2["Dịch vụ tĩnh (Static)"]
        LB2 -->|"Header: X-Beta → true"| S3["Bản thử nghiệm (Beta Canary)"]
    end

Ma Trận Ra Quyết Định (Decision Matrix)

Thuộc Tính (Property)L4 (TCP của HAProxy)L7 (Nginx / Envoy)
Tầng OSI (OSI Layer)Tầng Giao vận (Lớp 4)Tầng Ứng dụng (Lớp 7)
Dựa hơi vào (Routing based on)Cặp IP + PortĐường dẫn URL, HTTP headers, cookies, chuỗi JWT
Ăn bớt độ trễ (Latency overhead)~0.1–0.3ms~0.5–2ms (phân tích nát cái cục HTTP)
Thông lượng (Throughput)Hàng triệu kết nối/giâyVài trăm ngàn/giây
Chốt hạ TLS (TLS termination)❌ Chỉ cho đi xuyên (Pass-through)✅ Tích hợp sẵn trò bóc phốt TLS
Khám sức khỏe (Health checks)Chỉ kiểm tra kết nối TCPHTTP 200, phản hồi tùy biến (custom response body)
Dính ghế (Sticky sessions)Băm IP gốc (Source IP hash)Dựa vô Cookie (SERVERID)
Chỗ xài (Use case)Đua tốc độ TCP thuần, luồng stream, máy chủ gameREST APIs, gRPC, rải mồi thử nghiệm (canary), test A/B

[!TIP] Đồ nghề thực chiến (Real-world stack): Quất con L4 (HAProxy/IPVS) ra rào ngoài cùng làm lá chắn chịu đòn (raw throughput) vớt vát mớ traffic thô, rồi thảy con L7 (Envoy/Nginx) vào sâu trong trung tâm dữ liệu (datacenter) để làm trò định tuyến thông minh (intelligent routing). Shopee với hằng hà sa số các hệ thống khổng lồ đều xài cái lối đánh xếp tầng này — L4 đưa lưng ra đỡ bão kết nối (connection burst), L7 thì bẻ lái dựa trên logic nghiệp vụ (business logic).


Trả Về Máy Chủ Trực Tiếp (DSR - Direct Server Return) — Trò Định Tuyến Bất Đối Xứng Chạy Thế Nào

Answer-first: Chơi trò DSR (DSR mode), cục cân bằng tải chỉ hứng giùm mớ request đi vào (inbound requests), còn đám máy chủ backend thì ném thẳng cục phản hồi (response traffic) vả lật mặt thằng client — nhảy vọt chẳng thèm qua mặt thằng cân bằng tải (bypassing the load balancer entirely). Trò này tiệt nọc (eliminates) vụ để cục LB chết cứng làm điểm nghẽn (bottleneck) kẹt xe băng thông trả về.

Dòng Chảy Traffic Trong DSR (DSR Traffic Flow)

sequenceDiagram
    participant C as Khách (IP: 1.2.3.4)
    participant LB as L4 LB (VIP: 10.0.0.1)
    participant B as Máy chủ Backend (IP: 10.0.0.10)

    C->>LB: Gửi SYN (đích: VIP:80)
    LB->>B: Quăng cục packet<br/>(IP đích vứt nguyên: VIP:80)<br/>MAC nguồn → MAC Backend (Ghi đè ARP)
    Note over B: Backend mở cửa rước vào vì nó có ôm cái VIP<br/>gắn vô lỗ hổng (lo:0 alias)
    B->>C: Nhả lại HTTP Response (nguồn: VIP:80)
    Note over LB: Cục phản hồi bay thẳng qua đầu LB luôn!

Gõ Lệnh Cấu Hình HAProxy DSR (HAProxy DSR Configuration)

# /etc/haproxy/haproxy.cfg — Bật L4 DSR mode
global
    log /dev/log local0
    maxconn 500000

defaults
    mode tcp
    timeout connect 5s
    timeout client  30s
    timeout server  30s

frontend http_front
    bind *:80
    default_backend http_backend

backend http_backend
    balance leastconn
    server backend1 10.0.0.10:80 check
    server backend2 10.0.0.11:80 check
    server backend3 10.0.0.12:80 check
# Gõ vô TỪNG con máy chủ backend — trói cái VIP vào loopback để ngửa tay hứng DSR packets
# ÉP BUỘC cái kernel KHÔNG ĐƯỢC há mỏ trả lời (reply) mấy cái lệnh đòi ARP cho cái VIP (tránh trò giành giật đập lộn ARP conflict)
sudo ip addr add 10.0.0.1/32 dev lo label lo:vip

# Bóp miệng (Suppress) chặn phản hồi ARP cho cái VIP mọc trên cổng mạng công khai (primary interface) của backend
echo 1 > /proc/sys/net/ipv4/conf/eth0/arp_ignore
echo 2 > /proc/sys/net/ipv4/conf/eth0/arp_announce

[!IMPORTANT] Mấy cục tham số sysctl này có tính sinh tử (critical): arp_ignore=1 có nghĩa là “chỉ mở mỏ trả lời (reply) cho mấy cái request ARP đi tìm mấy cái địa chỉ bám trên chính cái cổng (interface) nhận được request” — thành thử con backend nó chẳng thèm nhúc nhích há mồm phản hồi ARP cho cái VIP nằm mọc trên cái cổng công khai (public interface) của nó. Lỡ tay quên đắp bùa này, là hai con máy chủ nhảy vào xâu xé giành giật nhau chung một cục IP (claim the same IP), rồi traffic nó nhào lộn như điên éo biết đâu mà lần (unpredictable).

Vì Sao DSR Đáng Cực Kỳ Ở Quy Mô Khủng (Why DSR Matters at Scale)

Điển hình như đám Shopee mùa Flash Sale gánh bão 500k+ RPS, một cục phản hồi (response payloads - mớ hình ảnh, danh sách món hàng) nó bự xấp xỉ 50–200KB. Nếu ôm cứng cái trò proxy truyền thống (standard proxy mode), từng byte một sẽ phải chui nhủi lết qua cái lỗ load balancer. Kẹp trò DSR vô, thằng LB chỉ đứng vểnh râu bóp mấy cái hột SYN packets nhỏ nhoi, còn mớ hàng phản hồi cứ thế phi qua đầu nhảy vọt (bypassing it entirely). Thông lượng trả về (Response throughput) sẽ bung lụa phình to (scales linearly) ăn theo số lượng con backend rải ra, chớ chẳng thèm ăn nhằm gì sức mạnh của thằng LB (not LB capacity).


Thuật Toán Cân Bằng Tải — Trò Nào Mùa Nào Xài Cho Hợp (Load Balancing Algorithms)

Answer-first: Đứng giữa ngã ba đường chọn thuật toán (Algorithm selection) cốt là phải canh me cái biên độ chênh lệch của cục request bự cỡ nào (request size variance). Vòng Tròn Xoay Tua (Round Robin) và Bám Thằng Ít Việc Nhất (Least Connections) làm trùm khi mớ request nó đồng đều nhan nhản (homogeneous). Băm Nhất Quán (Consistent Hashing) lại là mệnh lệnh bắt buộc cho đám giao thức giữ trạng thái (stateful protocols - kiểu Redis, luồng gRPC). Chơi chiêu Băm IP (IP Hash) thì dán dính người dùng vô ghế (sticky sessions) mà khỏi tốn công vác thêm đống hành trang cookie nặng nề.

Thuật Toán (Algorithm)Độ Phức Tạp Thuật Toán (Time Complexity)Ngôi Vương Dành Cho (Optimal For)Kiểu Chết (Failure Mode)
Vòng Tròn Xoay Tua (Round Robin)O(1)Trọng lượng request ngang phè (Homogeneous request cost)Đám request dai dẳng (Long-tail) dắt mũi đớp cạn sạch mớ node
Xoay Tua Kẹp Tạ (Weighted Round Robin)O(1)Bầy backend mạnh yếu khác biệt (Heterogeneous backend capacity)Cân tạ lệch (Weight misconfiguration) là bẹp ruột quá tải (overload)
Ít Kết Nối Nhất (Least Connections)O(log N)Độ dài ngắn request tả pín lù (Mixed request duration)Node mới toe bị úp sọt lụt ngập (số kết nối đếm = 0)
Băm Nhất Quán (Consistent Hashing)O(log N)Giữ vía (Stateful): Redis, gRPC streamsDính chìa khóa nóng (Hot keys) → sập node (node overload)
Băm IP (IP Hash)O(1)Dán ghế dính (Sticky sessions) mà chẳng cần cookiesBất cân xứng nếu đám IP gốc túm tụm (office NAT - cả công ty xài chung 1 IP)

Viết Middleware Giới Hạn Tốc Độ (Rate Limiting) Token Bucket Chạy Bằng Go

Answer-first: Thùng Chứa Token (Token Bucket) là cái thuật toán giới hạn tốc độ chuẩn mực rập khuôn của ngành (industry-standard) bởi lẽ nó bật đèn xanh cho ba cái trò xả bão request (request bursting) (rót đầy token rề rề theo giới hạn) trong lúc tiện tay là phẳng mài nhẵn (smoothing out) mấy cú sốc quá tải dai dẳng (sustained overload). Gói golang.org/x/time/rate của con đẻ Go rinh nguyên cái Token Bucket vô với tốc độ bàn thờ O(1) (time complexity) chắp vá bằng mô hình lười rót đong (lazy refill model).

Token Bucket Chạy Kiểu Gì (How Token Bucket Works)

$$\text{tokens} = \min\left(\text{sức chứa (capacity)}, \text{tokens} + r \times \Delta t\right)$$

Trong đó:

  • $r$ = tốc độ rót đong (tokens/giây)
  • $\Delta t$ = khoảng thời gian bay hơi từ bận soi gần nhất (lazy refill)
  • $\text{sức chứa (capacity)}$ = kích cỡ cục bão xả tối đa (maximum burst size)

Cứ mỗi nháy request ập vô: vặt trụi 1 token. Nếu mớ tokens < 1: phũ phàng đạp cửa văng HTTP 429 vô mặt.

[!NOTE] Mớ code bùa chú bên dưới chỉ đắp vô cái trạm gác đơn côi (single-node). Muốn dựng một trạm thu phí dàn hàng ngang rải khắp mấy chục con app replicas (chung một cái hầu bao chia năm xẻ bảy - same user quota shared across pods), bắt buộc phải có trò rà đồng hồ trượt (sliding window counter) đồng bộ chung qua cửa Redis — mổ xẻ nát bét ở Phần 11: Bảo Mật & Giới Hạn Tốc Độ API.

package ratelimit

import (
    "context"
    "fmt"
    "net/http"
    "sync"
    "time"

    "golang.org/x/time/rate"
)

// PerClientRateLimiter vung roi đánh từng thằng client một (per-client rate limits)
// Xài một cái map (bản đồ) móc IP client → chỉ thẳng vô cái token bucket limiter của riêng thằng đó
type PerClientRateLimiter struct {
    mu      sync.RWMutex
    clients map[string]*clientState
    r       rate.Limit    // Rót rả rích bao nhiêu Tokens mỗi giây
    burst   int           // Cho phép xả cục bão (burst) bự cỡ nào
    ttl     time.Duration // Đá chóp (Evict) đám client trùm mền lười biếng sau mốc TTL
}

type clientState struct {
    limiter  *rate.Limiter
    lastSeen time.Time
}

func NewPerClientRateLimiter(rps float64, burst int, ttl time.Duration) *PerClientRateLimiter {
    rl := &PerClientRateLimiter{
        clients: make(map[string]*clientState),
        r:       rate.Limit(rps),
        burst:   burst,
        ttl:     ttl,
    }
    go rl.cleanupLoop() // Quăng cái goroutine chạy ngầm đi dọn dẹp quét rác (evict stale clients)
    return rl
}

func (rl *PerClientRateLimiter) getLimiter(clientIP string) *rate.Limiter {
    rl.mu.RLock()
    state, ok := rl.clients[clientIP]
    rl.mu.RUnlock()

    if ok {
        state.lastSeen = time.Now()
        return state.limiter
    }

    // Client mới toanh — đúc ngay một cái token bucket mới cáu
    rl.mu.Lock()
    defer rl.mu.Unlock()
    limiter := rate.NewLimiter(rl.r, rl.burst)
    rl.clients[clientIP] = &clientState{limiter: limiter, lastSeen: time.Now()}
    return limiter
}

// cleanupLoop đi xách cổ đá chóp mớ trạng thái client (client state) nào trốn rịt chưa lòi mặt ra trong vòng TTL
func (rl *PerClientRateLimiter) cleanupLoop() {
    ticker := time.NewTicker(rl.ttl / 2)
    defer ticker.Stop()
    for range ticker.C {
        rl.mu.Lock()
        for ip, state := range rl.clients {
            if time.Since(state.lastSeen) > rl.ttl {
                delete(rl.clients, ip)
            }
        }
        rl.mu.Unlock()
    }
}

// Middleware mửa ra một cái cục http.Handler làm trạm gác (enforces rate limits)
func (rl *PerClientRateLimiter) Middleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        clientIP := r.RemoteAddr
        if xff := r.Header.Get("X-Forwarded-For"); xff != "" {
            clientIP = xff // Cứ tin tưởng xài X-Forwarded-For nếu núp lùm sau lưng một con reverse proxy
        }

        limiter := rl.getLimiter(clientIP)

        // Lệnh WaitN sẽ đứng lại hóng cho tới khi đẻ ra token hoặc bị rứt dây rút ống (context is cancelled)
        // Áp vô APIs: khuyên chân thành xài Reserve() để khỏi kẹt (non-blocking) kẹp với cái header Retry-After
        if !limiter.Allow() {
            w.Header().Set("Retry-After", "1")
            w.Header().Set("X-RateLimit-Limit", fmt.Sprintf("%.0f", float64(rl.r)))
            http.Error(w,
                `{"error":"rate_limit_exceeded","message":"Lấn làn lố ga rồi ba, từ từ đợi 1 giây sau rỉa tiếp (Too many requests, please retry after 1 second)"}`,
                http.StatusTooManyRequests,
            )
            return
        }

        next.ServeHTTP(w, r)
    })
}

Dàn Trận Giới Hạn Tốc Độ Phân Tán (Distributed Rate Limiting) Kẹp Với Redis

Ba cái token bucket quăng vô một lò (Single-process) dứt khoát hụt hơi cúp đuôi khỏi mong bành trướng phình to (scales across multiple pods). Trò INCR kẹp chung vô mâm với EXPIRE của Redis đẻ ra con quái vật giới hạn tốc độ đấm phát chết luôn (atomic cross-pod rate limiting):

package ratelimit

import (
    "context"
    "fmt"
    "time"

    "github.com/redis/go-redis/v9"
)

type RedisRateLimiter struct {
    rdb      *redis.Client
    limit    int64
    window   time.Duration
}

// Allow soi xem cái request có nằm ngon lành trong giới hạn (within the rate limit) hay không bằng trò cửa sổ trượt (sliding window) của Redis
func (r *RedisRateLimiter) Allow(ctx context.Context, clientKey string) (bool, error) {
    key := fmt.Sprintf("ratelimit:%s", clientKey)
    
    // Nã bùa Lua script cho nó cắn chặt nguyên khối (atomic) cái cục INCR + EXPIRE
    script := redis.NewScript(`
        local count = redis.call('INCR', KEYS[1])
        if count == 1 then
            redis.call('EXPIRE', KEYS[1], ARGV[1])
        end
        return count
    `)
    
    count, err := script.Run(ctx, r.rdb,
        []string{key},
        int64(r.window.Seconds()),
    ).Int64()
    if err != nil {
        return true, nil // Có vấp té lủng Redis thì cứ mở toang cửa (Fail open) — đừng dại dột bóp cổ chặn họng dòng người vô tội (legitimate traffic)
    }
    
    return count <= r.limit, nil
}

[!WARNING] Nhắm mắt mở toang (Fail open) hay thẳng tay sập cửa (fail closed): Trong cái mớ code Redis rate limiter trút ở trên, rủi mà Redis ăn hành (errors) thì nó nhả ra true (cho đi lọt lưới - allow). Cái này cố tình đắp vào (intentional) cho mớ API phơi mặt ra cho thiên hạ (user-facing APIs) — một cú ngã ngựa đứt bóng của Redis chẳng được phép vạ lây bóp ngẹt đám traffic trong sạch (legitimate traffic). Đụng tới mấy cái ngóc ngách hiểm nghèo bảo mật (security-critical endpoints kiểu như đăng nhập, nhả tiền - login, payment), nhắm mắt fail closed đóng rầm cửa rồi ném cái lỗi 503 vô bản mặt thằng trạm gác (limiter errors) mới là đạo.


Mẫu API Gateway (API Gateway Patterns) — Mớ Lộn Xộn Kong / Envoy

Một con API Gateway đóng vai làm chốt chặn độc tôn (single entry point) đứng phễu hứng mọi loại đạn traffic từ khách, giơ đầu ra đỡ đạn cho dăm ba cái trò vặt vãnh lằng nhằng (cross-cutting concerns) để bọn lính lác microservices chẳng phải è lưng hì hục cắm đầu chế lại (re-implement them).

graph LR
    Client([Mobi / Web]) -->|HTTPS| GW["API Gateway\n(Kong / Envoy)"]
    GW -->|"Soi bùa JWT\nBóp dái Rate limit\nGhi chép Logging"| Auth["Nhà Tù Auth"]
    GW -->|"Đường bay: /orders/*"| Orders["Lò Order"]
    GW -->|"Đường bay: /products/*"| Products["Vựa Products"]
    GW -->|"Đường bay: /payments/*"| Payments["Két Payments"]
    
    style GW fill:#4a6cf7,color:#fff

Bổn phận mớ việc vặt của Gateway (Gateway responsibilities - cross-cutting):

  • Sàng lọc Kẻ Giang Hồ (Authentication/Authorization): Bóc bùa kiểm tra JWT (JWT validation), xăm soi xác minh token OAuth2 (token introspection).
  • Phanh Cản Tốc (Rate Limiting): Siết cổ gò ép (limits) lên từng đầu người (per-user) hay từng chiếc chìa khóa API (per-API-key).
  • Múa May Quay Cuồng Gói Hàng (Request/Response Transformation): Tiêm chích (Header injection), cắt gọt xào nấu ruột gan (body transformation).
  • Hệ Thống Trinh Sát (Observability): Gom hết sổ sách ghi chép dồn về một mối (Centralized access logging), tiêm dấu vết săn lùng phân tán (distributed tracing header injection).
  • Phán Trảm Quyết TLS (TLS Termination): Khép mành giấy chứng nhận (Certificates managed) ngay tại cổng gateway, để đám lính lác bên trong tung tăng xài mạng chổng mông trống trải (plaintext internally).

[!NOTE] Độ trễ lặc lè của Gateway (Gateway latency overhead): Mớ Envoy nó tròng cổ nhồi thêm ~0.5–1ms cho mỗi nháy request vô tội nào là đi soi rọi HTTP (HTTP parsing), cắm đủ thứ đồ chơi (plugin execution), và rà radar (telemetry). Với mấy con số SLO p99 < 50ms, độ hao hụt (overhead) này như muỗi chích inox (negligible). Đối với mấy tay cộm cán đòi đua tốc độ cực hạn (ultra-low-latency) đú đỡn kiểu stream (bắn game, đẩy giá coin tài chính), rũ bỏ (bypass) ngay cái rọ gateway rồi nhảy xổ vào ôm đùi con L4 DSR xài trực tiếp.


Hỏi Nhanh Đáp Gọn (FAQ)

Giữa hai thằng cân bằng tải L4 với L7, lật mặt ra thì chúng nó khác nhau cái quái gì?

L4 nhắm đường húc bừa ở đẳng cấp TCP vịn vô IP+port — chẳng màng tới việc xoi mói ruột gan HTTP (no HTTP parsing). Thụt lùi (overhead) mỏng cỡ ~0.1ms, húp trọn hàng triệu nháy kết nối trong nháy mắt (connections/second). Khuyết tật ở chỗ (Limited to) chỉ dòm ngó xoi mói ngang tầm kết nối (connection-level decisions - kiểu băm IP, lựa thằng ít TCP để gởi gắm - least-connections). Lực bất tòng tâm (Cannot route) khi đụng ba cái bài chia chác theo đường dẫn URL hay HTTP headers.

L7 gác cổng ở đẳng cấp HTTP — xoi mói vạch lá tìm sâu từng cái headers, đường đi nước bước URL (URL paths), đống bánh quy (cookies). Thụt lùi mập hơn ~0.5–2ms nhưng bù lại mở đường cho (enables) ba cái trò bẻ lái theo URL (URL-based routing), thả mồi thử nghiệm bám theo header (header-based canary releases), và rờ rẫm sức khỏe chuẩn bài HTTP (HTTP-aware health checks). Bùa hộ mệnh dứt khoát phải có (Required) cho thế giới microservices nơi từng con đường dẫn lạng lách (different routes) cắm rễ chui nhủi vào từng hang hốc lính lác (backend services) khác nhau.

Kế rải quân DSR (Direct Server Return) bơm thông lượng bằng đường nào?

Nếu cứ cắm đầu chui vào cái ống proxy rập khuôn (standard proxy mode), cả chiều đi (request) LẪN chiều về (response) đều phải cun cút xếp hàng đâm chui lọt qua cái cổng load balancer. Kẹp trò DSR, duy nhất mớ request lù đù bước qua ngõ; thằng lính lác (backend) móc vòi tống rác (responds) quăng thẳng lật lọng (directly) về phía ông cố nội khách (client) bằng cách đội lốt khoác áo (using the VIP as the source IP) cái VIP. Khi vớ trúng hũ vàng phản hồi cực bự (large responses - mớ ảnh ọt, file tải nặng trịch), trò này cắt tiết vặt lông (reduce) giảm lượng traffic đè cổ LB xuống được hẳn 90%+ bởi lẽ mớ rác quăng lại bao giờ cũng phình to lấp lửng (dwarf) so với cái hình hài nhỏ nhặt của đống yêu cầu tới.

Lúc chẳng nào vác Băm IP (IP Hash) ra chém, lúc nào rút Băm Nhất Quán (Consistent Hashing)?

Băm IP (IP Hash): Đơn sơ mộc mạc (Simple), O(1), húp trọn điểm ngon lành vụ đổ keo ghế dính (sticky sessions). Gót Achilles (Problem): cả bầy đống user bấu víu chung một cái lỗ NAT (office NAT) tự dưng biến thành một mớ rồng rắn chung một cái vỏ IP → bóp chết nghẹt một con server (overload one server).

Băm Nhất Quán (Consistent Hash): Trút hàng húp trọn vụ điều phối (routing) quăng thẳng vô mồm bầy lính lác giữ ghế (stateful backends kiểu băm nát Redis shards, xả dòng thác gRPC streams), nơi mà một tay khách hàng (same client) bắt buộc phái luồn lách nương tựa dứt khoát vô chỉ một thằng đệ (same backend) mặc xác cả làng cụm cluster phình xẹp cơi nới chắp vá cỡ nào (regardless of cluster size changes). Đóng vai giảm chấn (Minimizes remapping) mổ cò chắp vá lại cực ngon khi giật cục thêm/bớt mấy cái ngòi nổ (nodes). Bới móc moi gan nát bét vụ này ở Phần 9: Băm Nhất Quán (Consistent Hashing).


🔗 Bay Sang Bài Tới: Phần 3: Bài Toán Caching & Hội Chứng Voi Giẫm Đạp Caching Trong Go — Thuật toán XFetch, moi móc ruột gan Redis LRU/LFU, và tiệt nọc trùng lặp bằng singleflight (singleflight deduplication).