Our not-so-magic journey scaling low latency, multi-region services on AWS
Bài tóm tắt Atlassian 2019 3. Quy mô lớn Độ khó: Nâng cao
Atlassian · 2019 · 3. Quy mô lớn · Độ khó: Nâng cao — bài gốc
Bối cảnh
- Atlassian "all in" trên AWS từ 2016; nhiều service phải viết lại cho stateless.
- Jira: tenant được gom thành các nhóm nhỏ (shard) rải khắp thế giới để thu nhỏ blast radius, tránh "hàng xóm ồn ào" và scale ngang được. Vẫn giữ mô hình một DB cho mỗi tenant (nhiều DB trên một RDS).
- Vì vậy cả network ingress lẫn Jira đều cần biết "tenant này ở đâu". Họ gom thông tin này vào một service duy nhất, Tenant Context Service (TCS). TCS về sau thành dịch vụ metadata tenant cho toàn bộ Atlassian Cloud.
- Yêu cầu: được gọi nhiều lần trong mỗi request; latency cực thấp; có mặt ở mọi region; availability 4–5 số 9; dữ liệu không bao giờ hỏng vĩnh viễn; mỗi bên dùng chỉ thấy phần của mình. TCS sập thì mọi request tới instance của khách đều hỏng.
Thay đổi chính (4 bài học "không có phép màu")
- CQRS + DynamoDB: Catalogue Service giữ nguồn sự thật (nhất quán mạnh, yêu cầu availability và latency thấp hơn TCS một bậc) → Kinesis → bản ghi được phi chuẩn hoá cho từng use case → các TCS độc lập ở mỗi region chỉ đọc. Client tự chuyển sang region dự phòng khi một region hỏng.
- "DynamoDB không phải phép màu": ở vài nghìn req/s mỗi region, có lúc cả một AZ nhận 5xx khoảng 1 giây, có request >10ms, dù vẫn trong SLA của DynamoDB. Giải pháp: cache ngay trên node (không qua mạng) + invalidate qua SNS giữa các node.
- "Load balancer không phải phép màu": sập 5 phút ở 2 region Mỹ (toàn bộ sản phẩm cloud ở Mỹ ngừng). Nguyên nhân: mỗi lần deploy tạo ELB mới chưa scale (ELB cần 1–7 phút để scale), ELB hết bộ nhớ. Chuyển sang một ALB cố định, nhưng p99 tăng từ ~7–10ms lên 20ms vì ALB dùng round robin thay vì "ít kết nối nhất".
- "Cache không phải phép màu": Guava cache hết hạn theo TTL (nguội đi) và không chặn các request đồng thời khi miss (5 caller cùng miss thì 5 lời gọi xuống store). Chuyển sang Caffeine: refresh nền, luồng bảo trì riêng, chặn các request trùng khi dữ liệu cũ. p99 cải thiện rõ.
- "Client không phải phép màu": một team kêu TCS chậm. Thực ra client của họ gọi region tuần tự, cache bị tranh chấp, cạn connection pool. Giải pháp: sidecar client (không phụ thuộc ngôn ngữ, gọi qua localhost) với cache dài (tới hơn 1 giờ nhưng vẫn cập nhật trong vài giây nhờ nghe invalidate qua SNS), gọi song song nhiều region và lấy kết quả về trước, API giống hệt TCS thật.
Kết quả (2019)
Gần 100% reliability từ phía client; p99 ~0,7ms (đo ở client); tải lên TCS giảm mạnh dù client gọi song song nhiều region. Có công cụ chaos trên production: tắt cả region, chèn latency lớn ngẫu nhiên, làm chậm ingest dữ liệu, mà client không thấy ảnh hưởng.
Bài học cho SWE
- Gom ánh xạ tenant → vị trí vào một service duy nhất. Theo Atlassian, nhiều công ty tại re:Invent 2018 cũng làm vậy. Nhưng service đó thành phụ thuộc cứng của mọi request, nên phải được thiết kế khắt khe nhất. Đối chiếu: index DB của Etsy là điểm hỏng chung (Etsy 2026).
- Managed service hoạt động "trong SLA" vẫn có thể không đủ cho SLA của bạn. Theo Atlassian: AWS là nền móng, không phải lời giải.
- Cache cần cơ chế single-flight (chặn miss đồng thời), giống memcache lease của Instagram (Instagram 2015).
- Tự viết client cho service của mình (sidecar) vì người làm service biết cách gọi tốt nhất. Cùng ý với mcrouter sidecar của Pinterest (Pinterest 2020).
Liên quan
Độ tin cậy và multi-regionNền tảng nội bộ cho service (đường ray chung)Hot partition và thundering herdSharding và tách databaseCache và invalidationMulti-tenancy và cô lập tenant
Được nhắc tới trong
Chủ đề (6)
Công ty (1)
Bài tóm tắt (3)