Hot partition và thundering herd

Chủ đề Dành cho thành viên
Bài đọc thử: 2/3 · còn 1 bài miễn phí · Xem gói thành viên

Bài toán

Chia dữ liệu và tải ra nhiều máy chỉ hiệu quả khi tải chia đều. Thực tế tải lệch: một khách hàng khổng lồ, một kênh có @everyone, một bài của người nổi tiếng. Có hai dạng hay gặp:

  • Hot partition / hot spot: một phần dữ liệu (shard, partition, key) nhận phần lớn tải. Một node chậm có thể kéo cả cụm chậm theo.
  • Thundering herd / retry storm: rất nhiều client cùng lao vào một tài nguyên cùng lúc, ví dụ khi cache miss, khi service chậm và client retry, hoặc khi hàng loạt kết nối lại sau sự cố.

Diễn tiến theo thời gian

  • 2006 · Google: developer hay viết vòng retry vô hạn khi file chưa có trên Chubby; phạt bằng độ trễ tăng dần chỉ lộ bug và tốn công giáo dục, cuối cùng làm cho Open() lặp lại rẻ. Một hệ hàng trăm máy chạy phục hồi hàng chục phút mỗi lần Chubby đổi master, khuếch đại sự cố gấp trăm lần. Google 2006
  • 2010→2013 · Twitter: tweet lưu trên MySQL shard theo thời gian, một master, nên mọi lượt ghi mới dồn vào DB mới nhất và tạo hot spot đọc/ghi. Họ chuyển sang hash tweet (Gizzard/T-Bird). Khi mới tách service, client retry dồn dập vào service chậm gây thundering herd. Họ chặn bằng thư viện RPC chung Finagle có back-pressure và failover. Twitter 2013
  • 2012→2013 · Alibaba: Double 11 năm 2012 làm DB tồn kho quá tải và bán vượt tồn kho hàng loạt. Gốc là hot row: nhiều người cùng trừ tồn kho một sản phẩm, tức là cùng update một dòng dưới row lock. Năm 2013 kernel AliSQL được vá để biến tranh chấp hỗn loạn thành hàng đợi có thứ tự. Alibaba 2019
  • 2013 · Twitter (qua HighScalability): một tweet của người có hàng chục triệu follower là hàng chục triệu lần chèn vào Redis, đuôi giao hàng p99 tới 5 phút và race condition khắp site, càng tệ khi người nổi tiếng trả lời nhau; xử lý tài khoản lớn bằng đường riêng (kéo lúc đọc). Twitter 2013
  • 2013 · Netflix (Scryer): autoscale phản ứng bị bẫy sau sự cố: traffic tụt kích hoạt scale-down, rồi retry storm ập vào cụm đã nhỏ; instance mất 10–45 phút mới lên. Scryer dự đoán capacity theo mẫu ngày/tuần, AAS phản ứng làm lưới an toàn. Netflix 2013
  • 2014 · Pinterest: pipeline analytics MapReduce bị dữ liệu lệch (vài profile/domain chiếm phần lớn) làm reducer không đều; cắt trước bản ghi gần như không thể vào kết quả. Ở HBase, row key đặt khoá phân tán đầu để rải đều region server, ngày cuối để một biểu đồ là một scan liền. Pinterest 2014
  • 2014 · WhatsApp (qua HighScalability): user ở rất nhiều group (hàng nghìn tin/giờ) làm bẩn cache nên bị loại khỏi cache; bảng account 512 fragment có chuỗi băm dài hơn 2K (mục tiêu 7) khiến tăng gấp đôi host lại giảm throughput, sửa hai dòng hàm băm nhanh gấp 4. WhatsApp 2014
  • 2015 · Instagram: sau khi chuyển sang invalidate cache theo vùng, mỗi like xoá counter khỏi cache, và với bài của người nổi tiếng thì hàng loạt web server cùng miss rồi cùng query DB. Giải pháp: memcache lease (chỉ một server được đi DB, server khác nhận giá trị cũ hoặc chờ) + denormalize counter. Instagram 2015
  • 2015 · Medium: DynamoDB chia capacity của bảng cho số partition mà không cho biết số partition (1.400 WCU trên 28 partition chỉ còn 50 mỗi partition), nên biểu đồ tổng dư capacity mà vẫn có đỉnh 150.000 request bị throttle. Họ tự ghi access log qua ELK để thấy top key (một key lên 400 lần trên bảng postChunk). Medium 2015
  • 2016–2017 · Segment: DynamoDB bị throttle dù đã cấp dư, vì tiền capacity quyết định số partition chứ không phải tổng throughput. Hạ capacity để cố tình gây throttle rồi log key: thủ phạm là khách hàng test tự động gửi hàng trăm nghìn event cho cùng userId = "user_id". Chặn key xấu, hạ capacity 4 lần; hướng lâu dài là partition từ Kafka phía trên. Segment 2017
  • 2016→2020 · Slack: shard theo workspace làm các khách doanh nghiệp lớn thành hot spot, trong khi phần lớn fleet bị cấp dư. Vitess cho phép đổi khoá shard (ví dụ theo channel) và tách keyspace nóng. Slack 2020
  • 2016→2017 · Alibaba: hot key trên cache (một key chỉ ở một máy) giải bằng băm key nóng ra cả cụm; cold start lúc 00:00 Double 11 giải bằng làm ấm trước. Alibaba 2019
  • 2017 · Discord (DB): partition Cassandra theo (channel, bucket 10 ngày) để giới hạn kích thước partition dưới 100MB. Một kênh bị xoá hàng triệu tin tạo ra partition đầy tombstone, gây GC stop-the-world 10 giây cho cả node. Discord 2017
  • 2017 · Discord (runtime): khi lookup nhanh hơn, gần 5 triệu session "giẫm đạp" 10 process registry; timeout + retry chồng chất làm OOM cả VM. Giải pháp: semaphore để từ chối sớm. Discord cố ý không dùng circuit breaker. Discord 2017
  • 2017 · Figma: rate limiter kiểu sliding window counter (60 counter nhỏ trong một Redis hash, INCR nguyên tử) chặn được đợt spam đầu tiên; chuyển từ trả 429 sang shadow ban vì kẻ tấn công dựa vào 429 để biết mà tạo tài khoản mới. Figma 2017
  • 2017 · LinkedIn: một endpoint hỏng hoặc service phía dưới chậm kéo chậm cả monolith API (gọi gần 300 service phía dưới); tách thành cụm theo vertical giảm fan-out trung bình còn 35%. LinkedIn 2017
  • 2017 · Walmart: quan hệ cha-con trên Cassandra với cha làm partition key tạo hot spot (cha một triệu con); thêm shard key nhân tạo (tối đa 1.000 con, partition dưới khoảng 10 MB), được luôn phân trang. Walmart 2017
  • 2017 · CapitalOne: file giao dịch từ mainframe đã sắp theo khoá chính, nạp tuần tự làm DynamoDB throttle vì hot partition; test nhỏ không lộ, chỉ thấy khi nạp ở quy mô thật. Sửa bằng xáo trộn dữ liệu trước khi nạp và xem lại thiết kế key. CapitalOne 2017
  • 2017 · Slack: bão kết nối lại (cả văn phòng mất mạng rồi vào cùng lúc) mà mỗi lần kết nối đắt như lần đầu; Flannel ở edge trả dữ liệu khởi động từ cache. Slack 2017
  • 2017 · Box: Throttling DynamoDB do mọi object cùng thư mục chung khoá partition chứ không do capacity tổng; salt khoá bằng hash của path + object. Box 2018
  • 2017 · Etsy: Key cache nóng làm bão hoà card mạng một máy; thêm máy chỉ dời vấn đề. Cache smearing: thêm số ngẫu nhiên 0–8 hoặc 0–16 vào vài key nóng nhất để một key thành vài bản trên nhiều máy, đổi không gian và rủi ro đọc lệch lấy thông lượng. Etsy 2017
  • 2018 · Segment: retry của một destination lỗi ngập hàng đợi chung, gây head-of-line blocking cho mọi destination. Đây là lý do ban đầu để tách mỗi destination một queue. Segment 2018
  • 2018 · Pinterest: Scorpion (xếp hạng ML) chặn thundering herd khi cache miss bằng đồng bộ ở mức object; shard để cache hit trên 90%. Pinterest 2018
  • 2018→2021 · OpenAI: ở cụm Kubernetes lớn, mọi thứ tăng theo số node thành bão vào control plane: agent giám sát trên mọi node poll API server (hơn 500 MB/s đọc từ etcd ở khoảng 1.000 node); WATCH Endpoints tăng theo N² (có lúc hơn 1 GB/s) tới khi có EndpointSlices; thêm hàng trăm node cùng lúc làm quá tải API server. OpenAI 2021
  • 2018 · SoundCloud: cache Memcached cho bộ đếm công khai bị xoá hằng ngày để chặn độ trôi, với TTL ngẫu nhiên để các track nóng không hết hạn cùng lúc. SoundCloud 2018
  • 2018 · Segment: tải khách theo luật lũy thừa; một khách gửi 50.000 message tới một đích giới hạn 1.000/giây/khách sẽ chặn khách nhỏ 50 giây nếu dùng một queue mỗi đích. Centrifuge cô lập theo cặp (khách, đích) bằng queue ảo trong DB; retry vẫn từng đẩy khoảng 100.000 request/giây vào đối tác đang yếu. Segment 2018
  • 2018→2022 · Netflix: mọi cấu trúc của một queue Timestone nằm cùng một shard Redis để thao tác nguyên tử; đổi lại queue nóng (khi thiếu compute) phình to trên một shard, đang làm shard theo queue. Netflix 2022
  • 2018→2022 · Slack (Kafka): mất ổn định của cụm Kafka gốc là hot spot: số partition khác nhau giữa topic làm vài broker nóng, và thao tác thêm/bớt broker khuếch đại điểm nóng. Sửa bằng partition là bội số broker, consumer chia đều, throttle replication. Slack 2022
  • 2018 · LinkedIn: "superactor" hàng triệu follower sinh hàng triệu ứng viên thông báo mỗi hoạt động; partition bước chấm điểm theo người nhận (không theo người tạo) làm tải rải đều và mỗi host chỉ giữ feature của người nhận băm về nó. LinkedIn 2018
  • 2018 · Netflix: Join-the-shortest-queue trên nhiều load balancer gây herding (cùng chọn server ít tải rồi đè nó); choice-of-2 + utilization do server báo giải mà không cần chia sẻ state giữa các LB. Netflix 2018
  • 2019 · Grab: bulkhead bằng MaxConcurrentRequests của Hystrix, đặt mỗi thao tác/API một tên circuit; fallback khi retry vô ích (trả rỗng, giá trị mặc định, cache với thời hạn dài hơn khi lỗi, backup service độc lập). Grab 2019
  • 2019 · Disney Hotstar: traffic "sóng thần" khi đội Ấn Độ ra sân: scale-up mất ~4 phút, tức "lỡ 2 triệu người", nên buffer +2 triệu user hoặc +30% traffic trong sự kiện live. Disney Hotstar 2019
  • 2019 · Atlassian: Guava cache không chặn các request đồng thời khi miss (5 caller thì 5 lời gọi xuống store); chuyển sang Caffeine (refresh nền, gộp request trùng) thì p99 cải thiện rõ. Atlassian 2019
  • 2019 · Tinder: chia lưới đều theo kinh/vĩ độ tạo hot shard (ô ngoài biển rỗng, châu Âu đông). Họ cân shard theo load score bằng cách tối thiểu độ lệch chuẩn trên đường Hilbert (S2). Tinder 2019
  • 2019 · Tinder (múi giờ): shard theo địa lý nên giờ cao điểm lệch nhau, RPS giữa các shard chênh hơn 10 lần. Xếp tay là bài toán NP-hard, nên họ rải ngẫu nhiên primary/replica lên host và chỉnh số replica tới khi đủ đều. Retry ghi index dùng exponential backoff có jitter. Tinder 2019 Tinder 2019
  • 2019 · GitLab: lỗi SSH chập chờn dồn vào 10 giây đầu mỗi phút (đỉnh gấp 3 nền) và các mốc tròn giờ: cron của người dùng khắp internet, được NTP đồng bộ, cùng git fetch. Vượt MaxStartups của sshd; sửa bằng tăng ngưỡng, rate limit phiên mới ở HAProxy và đổi balance source sang leastconn. GitLab khuyên thêm sleep ngẫu nhiên cho job định kỳ. GitLab 2019
  • 2019 · Postman: mỗi lần deploy service giữ WebSocket là một triệu client kết nối lại cùng lúc, làm server suy giảm và ngắt thêm; mất 6–8 giờ mới hồi. Sửa bằng cách tách lớp giữ kết nối ra khỏi lớp hay deploy. Postman 2020
  • 2019 · Tinder: Swipe Night mở cho cả nước trong một khung giờ, kèm nhiều đợt push toàn quốc: đỉnh nhọn do chính mình tạo, autoscaler phản ứng không kịp. Diễn tập bằng push thật trong 5 phút làm vài bảng Dynamo vượt burst capacity và bị throttle; autoscaler Dynamo mất 10 phút. Tinder 2020
  • 2019 · Stack Overflow: GetSet(key, lookup, duration, serveStale): hết hạn thì vẫn trả giá trị cũ và refresh ở luồng nền; khoá theo key trên mỗi server để 400 request miss chỉ gọi DB một lần; lỗi thì trả lại giá trị cũ. Stack Overflow 2019
  • 2019 · Dropbox: LB phân tán chỉ thấy tải cục bộ và subsetting ngẫu nhiên làm lệch tải giữa backend; server fail nhanh trông như rảnh và hút thêm request nếu không tính lỗi vào điểm. Dropbox 2019
  • 2020 · Pinterest: consistent hashing chia đều key nhưng theo Pinterest không giải được hot key: lượng request bất thường cho vài key vẫn tạo shard nóng. Pinterest 2020
  • 2020 · Medium: bỏ event no-op của email digest làm tải tới service gợi ý Rex thành cụm đỉnh mỗi 10 phút (no-op từng là lớp đệm), Rex scale lên xuống liên tục. Sửa bằng delay ngẫu nhiên trong 10 phút cho mỗi event, tách shard event ra hàng đợi riêng để phát đúng nhịp, hạ rate tối đa 500 → 250. Medium 2020
  • 2021 · Wix: partition key là chatroom id, mà các phòng không đều về traffic lẫn dung lượng, nên tạo hot spot và có node Cassandra crash. Wix 2021
  • 2021 · Dream11: route qua nhiều load balancer bằng weighted DNS không chia đều vì client cache DNS theo TTL (độ lệch tăng theo số LB và TTL); TTL cache client hết đồng loạt cũng gây spike CPU ở tầng GraphQL. Dream11 2021
  • 2021 · Wix: phân bố đuôi dài (ít site nhiều traffic, rất nhiều site ít traffic) loại cả cold start lẫn "một pod mỗi site"; nhiều scheduler không phối hợp có thể cấp hai pod cho một site, Wix chấp nhận như scale miễn phí và chỉ thêm từng pod một để tránh cấp thừa. Wix 2021
  • 2022 · Grab: dựa vào adaptive capacity của DynamoDB, vốn tự dồn sức chứa cho partition nóng và cô lập item hay truy cập. Grab 2022
  • 2022–2023 · Discord: hot partition trên Cassandra (quorum read) làm latency lan ra cả cụm. Giải pháp không nằm ở DB mà ở tầng trên: data service gộp request (request coalescing) và route theo channel_id bằng consistent hash. Discord nói rõ: đổi sang ScyllaDB thì hot partition vẫn có thể xảy ra. Discord 2023
  • 2022→2025 · Zalando: PRAPI dùng consistent hash load balancing theo product-id để cache cục bộ hiệu quả; thêm bounded load (mỗi pod tối đa 2 lần trung bình, vượt thì tràn sang pod kế) để sản phẩm hot không đè sập một pod; mỗi pod 100 vị trí cố định trên vòng hash nên scale chỉ mất 1/N cache. Zalando 2025
  • 2022 · Gojek: hệ gọi dịch vụ tìm tài xế retry cố định mỗi 15 giây, lúc cao điểm kéo sập toàn hệ khoảng một giờ. Sau đó chia query geo thành vùng nhỏ để trộn vùng nóng với vùng nguội khi chia shard, và dùng best-effort timeout để node chậm không kéo cả request. Gojek 2022
  • 2022 · Shopify: hơn 10.000 DAG Airflow; lịch dạng khoảng tuyệt đối làm hàng loạt DAG sinh tự động chạy cùng lúc rồi lặp lại đúng chu kỳ, crontab do người viết dồn về đầu giờ. Dùng lịch ngẫu nhiên tất định băm từ dag_id; tải mỗi 10 phút phẳng hẳn. Shopify 2022
  • 2022 · Slack (2-22-22): restart Consul agent tuần tự làm Mcrib thay node memcached bằng node rỗng; query thành viên GDM trên keyspace shard theo user phải hỏi mọi shard khi miss, tải tăng siêu tuyến tính theo tỷ lệ miss, query timeout nên cache không nạp lại: trạng thái quá tải tự duy trì (metastable). Slack 2022
  • 2022 · Meta: một use case lớn của ACS cache trên điện thoại rồi gửi lô cùng một giờ mỗi đêm, thực chất tự DDoS dịch vụ; sửa bằng dithering cho use case đó và rate limiter toàn cục cho mọi use case. Meta 2022
  • 2023–2024 · Figma: khoá shard là auto-increment hoặc ID tiền tố thời gian, nên nếu chia theo khoảng sẽ dồn dữ liệu mới vào một shard. Họ hash khoá shard để chia đều, chấp nhận range scan kém đi. Figma 2024
  • 2023 · Monzo: "stampeding herd" khi hàng triệu người mở app cùng lúc (ngày lương, push). Đo thấy khoảng 70% GET trùng response trong 24 giờ; bỏ ý tưởng changes API (bản chất là cache invalidation), chuyển sang load shedding có điều kiện ở edge: ETag mang thời điểm tính và header nguyên nhân request, trả 304. Cắt được gần 50% GET với độ chính xác khoảng 90%, chạy shadow mode trước. Monzo 2023
  • 2023 · Uber: hot account trong sổ cái thanh toán (fleet operator, nhà vận hành marketplace) không chia nhiều dòng được mà không phá khái niệm một số dư; giải bằng gom lô theo tài khoản, Redis giữ lô là nguồn thời gian duy nhất cho ranh giới lô (bài 3/2026). Uber 2026
  • 2023 · Discord: cụm Scylla xác thực mất một zone vì nâng cấp, thêm một node disk suy giảm và cache nguội sau restart; app retry lỗi xác thực tạo retry storm; cắt tải bằng tắt sự kiện đang gõ và đánh dấu đã đọc chỉ khôi phục khoảng 50% người dùng. Discord 2023
  • 2024 · Canva: mặt trái của gộp request: Cloudflare gộp request cho một file JS bị mạng làm chậm 20 phút, giữ hơn 270.000 request rồi thả cùng lúc, tạo 1,5 triệu req/s (gấp 3 đỉnh thường) lên API Gateway. Task mới vừa lên đã bị đè chết; phải chặn ở CDN rồi mở dần theo vùng. Canva 2024
  • 2024→2026 · Inngest: queue trên Valkey: một tenant làm hết RAM là cả cụm sập, và đơn luồng nên không bảo đảm công bằng giữa tenant. Khoảng 2 năm vá (key queue v1/v2, Constraint API) đều vướng cùng một gốc, dẫn tới quyết định đổi DB. Inngest 2026
  • 2024 · TigerBeetle: theo TigerBeetle, OLTP vốn có tranh chấp nội tại: hàng chục triệu tài khoản khách đối ứng với vài tài khoản nội bộ, nên vài dòng nóng bị khoá trong hầu hết giao dịch. Khoá giữ qua 2 RTT × 0,5 ms thì mỗi dòng tối đa khoảng 1000 giao dịch/giây, và scale ngang không giúp. Lời giải của họ là bỏ row lock, gom tới 8000 giao dịch vào một request. TigerBeetle 2024
  • 2024 · OpenAI: tải do chính hệ thống tạo ra: mỗi node chạy thao tác API đắt, hàng nghìn node cùng lúc làm API server Kubernetes sập; khi khôi phục, nhiều service cùng tải tài nguyên khởi động làm vài cụm kẹt tiếp. OpenAI 2024
  • 2025 · Shopify: giữ hàng tồn kho bằng SELECT ... FOR UPDATE SKIP LOCKED (mỗi đơn vị hàng một hàng, pool tối đa 1.000) để không tranh chấp khoá trên một hàng; khi pool cạn chỉ một transaction được bổ sung, còn lại chờ, tránh thundering herd. Nút thắt thật là connection bị các phần khác của checkout giữ quá lâu. Shopify 2026
  • 2025 · Cloudflare: bug useEffect ở dashboard gọi API nhiều lần mỗi lần render (kèm retry) làm quá tải Tenant Service; restart tạo thundering herd vì mọi dashboard cùng xác thực lại. Sửa bằng hotfix, jitter cho retry, và đánh dấu request là retry hay request mới. Cloudflare 2025
  • 2025 · Cloudflare: DDoS 31,4 Tbps trong 35 giây được hấp thụ phân tán: mỗi server tự nhận diện và bỏ gói ở NIC (XDP), không gom về trung tâm lọc. Cloudflare 2026
  • 2025 · Cockroach Labs: vector index C-SPANN không có điều phối trung tâm; vector mới rải khắp partition của cây K-means nên không có range nóng; cột tiền tố cho mỗi tenant một cây riêng nên các user ít tranh chấp. Cockroach Labs 2025
  • 2025 · Uber: retry storm: mỗi hop retry một lần thì độ sâu d nhận 2^d lần request, retry budget 10% vẫn là 1,1^d; error ownership qua header (claim/unclaim) chỉ cho retry ở hop đầu tiên phía trên service sinh lỗi, giữ bảo đảm retry ít nhất một lần. Sự cố 18/11/2025: tránh khoảng 9,5 triệu request thừa; bán kính retry storm từ tối đa 25 xuống 3 (bài 9/2026). Uber 2026
  • 2026 · Uber: rải shard tự do trong M3DB làm mỗi node chia sẻ dữ liệu với gần cả cụm. Chia thành subcluster để giới hạn phạm vi; thêm subcluster mới bằng thuật toán tham lam chọn shard để tránh skew (hot spot) trong subcluster nhường shard. Uber 2026
  • 2026 · Discord: 17% session chết cùng lúc kéo theo: bão kết nối lại; rate limit tạo session chưa chỉnh lại sau khi lên Kubernetes; supervisor đơn luồng trên đường tạo kết nối HTTPS bị tắc khiến instance rơi khỏi hash ring. Khôi phục cũng gây thundering herd (cold start). Theo Discord, đây là bài toán tăng cung hay giảm cầu. Discord 2026
  • 2026 · Etsy: scatter query qua 1.000 shard làm một query từ 2s xuống 20ms, nhưng mặc định bị tắt để tránh vô tình bắn query đắt tới mọi shard. Etsy 2026
  • 2026 · Airbnb: quota QPS theo caller không thấy được hot key (nhiều caller, mỗi người trong quota, cùng đè một shard). Kho KV Mussel thêm ba lớp: tính phí theo request unit (byte, latency), load shedding theo mức quan trọng (tỷ lệ p95 dài/ngắn hạn, hàng đợi CoDel), và phát hiện hot key (top-k Space-Saving) với cache cục bộ 3 giây cộng gộp request. Diễn tập DDoS khoảng một triệu QPS mà backend gần như không nhận thấy. Airbnb 2026
  • 2026 · Inngest: queue multi-tenant trên FoundationDB: nhiều executor cùng lấy việc thì account nhiều function sẽ chiếm hết. Họ dùng weighted scan theo cây account → function → key, cộng sequential scan để việc cũ không bị bỏ đói. Kết quả là công bằng theo xác suất. Inngest 2026
  • 2026 · Canva: worker queue "tham lam" tiếp tục kéo message tốc độ tối đa khi dependency lỗi, đổ dầu vào lửa; circuit breaker mở lại đột ngột cũng dồn tải. Worker Backpressure cho mỗi worker tự lùi và tự hồi dần theo tỉ lệ lỗi. Canva 2026
  • 2026 · Inngest: retry xoá cùng một account xếp hàng sau khoá của lần đầu, mỗi retry giữ một slot PgBouncer; client connection lên khoảng 14 lần bình thường và pool dùng chung cạn cho mọi service. Inngest 2026
  • 2026 · Salesforce: ở dịch vụ định danh dùng chung, identity chậm làm upstream retry, retry thêm tải: lỗi dây chuyền. Họ dùng queue time làm tín hiệu sớm để cắt tải trước khi retry khuếch đại, và quota toàn cục để một tenant không thành noisy neighbor. Salesforce 2026
  • 2026 · Canva: deploy là nguồn dồn dập: hàng trăm pod gateway khởi động cùng lúc, mỗi pod kéo hơn một triệu bản ghi từ MySQL. Tải tỉ lệ với số instance × dữ liệu, không với traffic; chuyển việc nạp sang S3 thì tải DB chỉ còn theo tốc độ ghi. Canva 2026
  • 2026 · Fastly: mặt kia của tập trung: với CDN, traffic dồn vào vài khách (bản phát hành game, sự kiện live) làm cache hiệu quả hơn, nên Fastly cố ý dồn tải phù hợp lên phần cứng cũ, có giới hạn vì dồn tải tạo hot spot và giảm cô lập lỗi. Fastly 2026
  • 2026 · GitHub: agent biến một repo thành điểm nóng: repo bận nhất khoảng một tỉ request trong tháng 8/2026, merge queue dồn mọi merge vào một ref, mỗi push nhân thành hàng nghìn lượt fetch của CI. Thu nhỏ đường găng cần đồng thuận xuống chỉ phần cập nhật ref, phần còn lại chạy song song. GitHub 2026
  • 2026 · Cloudflare: scheduler "đến hạn thì quét" dồn hàng trăm nghìn lượt quét trong vài phút: nhiều account cùng last_scheduled_at, đổi chu kỳ 15 → 7 ngày làm 53% account đến hạn một lúc, account nhiều zone sinh thác quét bão hoà partition, và topic giữ theo thời gian nên message bị xoá trước khi xử lý. Sửa: lập lịch zone riêng, ngẫu nhiên hoá last_scheduled_at, rate limit thích ứng tính lại mỗi nửa giờ từ tổng số account chia chu kỳ. Cloudflare 2026
  • 2026 · Redis: CLUSTER SLOT-STATS (8.2, thêm bộ nhớ ở 8.4) báo số key, CPU, byte vào/ra cho từng slot để tìm slot nóng và dời đi; dời nguyên slot thay vì từng key nên ít ảnh hưởng tới tải đang chạy (spike latency tối đa dưới 70 ms so với 127 ms, theo Redis). Redis 2026
  • 2026 · ScyllaDB: driver Alternator có hai chiến lược định tuyến. Với 99% request dồn vào ít partition và mọi ghi dùng LWT, round-robin tệ hơn cả SDK AWS (rải key nóng qua nhiều coordinator làm tăng tranh chấp); key affinity (mỗi key một coordinator) tốt nhất. ScyllaDB 2026
  • 2026 · Cloudflare: Workflows V1 có một Durable Object Account làm điều phối cho cả tài khoản; khi workflow do agent tạo ở tốc độ máy thì nó thành điểm nóng (trần 4.500 đồng thời, 100/giây). V2 chia cho các SousChef, Gatekeeper cho thuê slot, Account chỉ nhận số request bất biến. Cloudflare 2026
  • 2026 · Uber: CoDel với thời gian chờ cố định làm mọi request bị từ chối retry cùng lúc, thành vòng lặp quá tải–từ chối; PID điều chỉnh liên tục tránh được; regulator khoá partition nóng chặn hotspot do một khoá. Uber 2026
  • 2026 · Stream (nhà cung cấp): tải dồn lúc mở cửa thị trường: singleflight cho khoá cache nóng hết hạn (một request dựng lại, còn lại chờ), cache feed chung cho mọi người đọc, chống thundering herd lúc hàng nghìn người cùng join một luồng video. Stream (GetStream) 2026
  • 2026 · Jane Street: trong 24 phút mất mạng, retry của Kafka client "timeout" nhưng không huỷ lần thử, lần thử kẹt ở DNS vì timeout không bao DNS; khi mạng trở lại, throttle DNS xả cùng lúc và TCP từ 429 lên 474.033 kết nối trong nửa phút, hai relay vượt giới hạn FD. Jane Street 2026

Các lựa chọn và đánh đổi

Kỹ thuật Chống cái gì Ví dụ Cái giá
Hash khoá thay vì khoảng/thời gian Hot spot do dữ liệu mới dồn một chỗ Twitter T-Bird, Figma Mất range scan hiệu quả
Đổi khoá shard (chi tiết hơn) Khách hàng lớn chiếm một shard Slack (workspace → channel) Migration nhiều năm
Giới hạn kích thước partition Partition phình vô hạn Discord bucket thời gian Đọc nhiều partition cho kênh ít hoạt động
Request coalescing Nhiều người đọc cùng một hàng Discord data service Thêm một tầng service
Lease / single-flight cho cache Thundering herd khi cache miss Instagram memcache lease Có thể trả giá trị cũ
Semaphore / back-pressure Retry storm, giẫm đạp Discord Semaphore, Twitter Finagle Từ chối bớt request
Hàng đợi riêng cho từng đích Một đích lỗi chặn tất cả Segment (trước khi gộp) Chi phí vận hành nhân lên
DB tự xử lý (adaptive capacity) Hot key Grab DynamoDB Phụ thuộc nhà cung cấp

Quy tắc rút ra

  1. Khoá chia dữ liệu phải chia đều cả tải chứ không chỉ dung lượng. Khoá theo thời gian và khoá theo khách hàng là hai bẫy lặp lại (Twitter, Slack, Figma).
  2. ID tốt cho sắp xếp có thể xấu cho chia shard. Snowflake sắp được theo thời gian (Sinh ID phân tán) nhưng Figma phải hash nó trước khi route.
  3. Bảo vệ DB từ tầng phía trên (coalescing, lease, semaphore) bền hơn là chỉ thay DB (Discord 2023).
  4. Retry phải có giới hạn. Ở ba bối cảnh khác nhau (Twitter, Discord, Segment), retry không kiểm soát biến một sự cố nhỏ thành sự cố lớn.
  5. Làm một đường nóng nhanh hơn có thể đẩy điểm nghẽn sang chỗ khác: tốc độ chậm trước đó vô tình là back-pressure (Discord 2017).
  6. Hot key có thể do khách hàng dùng sai (Segment: userId = "user_id"). Cần cách quan sát key nóng, và quyền chặn chúng.
  7. Rate limit và giới hạn đồng thời phải chỉnh lại khi topology đổi (Discord 2026: nhiều pod hơn làm giới hạn theo host thành lỏng hơn).
  8. Khi quá tải chỉ có hai đòn: tăng cung hoặc giảm cầu (Discord 2026). Lúc khôi phục, giảm cầu trước (rate limit), rồi mới tăng cung, để không tự tạo thundering herd khi khởi động lạnh.
  9. Bug ở client có thể DDoS chính backend của mình: retry cần jitter và cần đánh dấu là retry để phân biệt với request mới khi điều tra (Cloudflare 2025).
  10. Cache cần cơ chế single-flight (chặn miss đồng thời): memcache lease (Instagram), Caffeine (Atlassian), đồng bộ ở mức object (Pinterest Scorpion).
  11. Cân shard theo tải, không theo số khoá hay diện tích: Tinder dùng load score và tối thiểu độ lệch chuẩn; consistent hashing vẫn không giải được hot key (Pinterest 2020).
  12. Lịch tròn của con người cũng là thundering herd: job định kỳ của nhiều khách cùng chạy đầu phút/giờ (GitLab 2019). Phía cung cấp cần nhìn lỗi theo giây trong phút; phía dùng nên thêm jitter vào cron.
  13. Deploy và khởi động hàng loạt cũng là thundering herd: mọi instance nạp cache cùng lúc tạo tải tỉ lệ số instance × dữ liệu, không theo traffic người dùng; đưa đường nạp ra khỏi DB nguồn (Canva 2026 dùng S3).
  14. Bỏ việc vô ích có thể đổi hình dạng tải: event no-op từng làm phẳng tải cho service phía sau; bỏ chúng thì phải tự thêm jitter (delay ngẫu nhiên trong cửa sổ) và giữ nguồn phát đúng nhịp (Medium 2020).
  15. Lịch định kỳ tự dồn về cùng thời điểm; thêm độ lệch tất định theo định danh (Shopify 2022 băm dag_id để sinh crontab), cùng bài với GitLab 2019. Shopify 2022 GitLab 2019
  16. Dịch vụ dùng chung phải chịu được client hành xử sai; khi không sửa được client, làm đường đi sai rẻ đi (Chubby làm Open() lặp lại rẻ thay vì phạt). Google 2006
  17. Scheduler "đến hạn thì chạy" phải rải tải chủ động: ngẫu nhiên hoá mốc lịch hiện có, tách thác con (zone của account lớn) thành lịch riêng, và giới hạn tốc độ tính từ tổng khối việc chia chu kỳ, tính lại định kỳ khi số khách tăng (Cloudflare 2026). Cloudflare 2026
  18. Với key nóng cần đồng thuận, dồn về một coordinator tốt hơn rải đều: round-robin làm tăng tranh chấp LWT, key affinity giảm (ScyllaDB 2026). Cân tải đều chỉ đúng khi request độc lập. ScyllaDB 2026
  19. Retry storm tăng theo lũy thừa độ sâu chuỗi gọi; retry budget chỉ hạ cơ số, chặn chỗ retry (error ownership) mới cắt được lũy thừa. Uber 2026

Câu hỏi mở

  • Resharding khi đang chạy: Uber M3DB có thuật toán nhường shard tránh skew (Uber 2026), Shopify dời cả pod (Shopify 2018). Vẫn chưa có nguồn về tách một tenant khổng lồ ra nhiều shard; Notion 2023 ghi nhận chiều ngược lại: reshard đều thành nhiều máy nhỏ hơn làm workspace ngoại lai càng nổi bật (Notion 2023).
  • Circuit breaker hay semaphore? Đã rõ hơn: MaxConcurrentRequests của Hystrix mà Grab dùng thực chất là một semaphore gắn theo tên circuit (Grab 2019), và Discord sau các sự cố DB đã thêm circuit breaking tự động ở API (Discord 2026). Hai cơ chế bổ sung cho nhau chứ không loại trừ nhau. Vẫn chưa có nguồn so sánh định lượng.
  • Liên hệ: Sharding và tách database, Realtime và fan-out.
  • Liên hệ: Cache và invalidation (lease/single-flight, invalidate giữa region, cache như một dịch vụ).
  • Liên hệ: Load shedding, rate limit và backpressure (rate limit, cắt tải, bulkhead, backpressure: cách điều tiết tải đã dồn).
  • Liên hệ: Load test và kiểm chứng capacity (diễn tập đỉnh nhọn do push trước ngày ra mắt: Tinder 2019).
  • Liên hệ: Multi-tenancy và cô lập tenant (noisy neighbor: tenant lớn là hot key ở cấp khách hàng; công bằng theo key, shuffle sharding).