What it takes to run Stack Overflow

Bài tóm tắt Stack Overflow 2013 3. Quy mô lớn Độ khó: Dễ

Stack Overflow · 2013 · 3. Quy mô lớn · Độ khó: Dễ — bài gốc

Bài tiền thân của series kiến trúc 2016 (Stack Overflow 2016, Stack Overflow 2016). Số liệu 2013 trong bài 2016 lấy từ đây.

Bối cảnh

Nick Craver mô tả Stack Overflow là chạy "with scale" nhưng không "at scale": vận hành rất hiệu quả nhưng chưa "lớn". Số liệu một ngày (12/11/2013), chỉ tính data center đang hoạt động, không tính CDN:

  • 148 triệu HTTP request, trong đó 36 triệu page load; gửi đi khoảng 1 TB;
  • 334 triệu SQL query (chỉ từ HTTP request), 412 triệu Redis hit, 3,6 triệu request tới tag engine;
  • tổng thời gian: SQL 155 giờ, Redis 27 giờ, tag engine 36 giờ, xử lý ASP.NET 757 giờ.

Thay đổi chính (ảnh chụp kiến trúc 2013)

  • Phần cứng đang chạy: 4 SQL Server, 11 web server IIS, 2 Redis, 3 tag engine, 3 Elasticsearch, 2 HAProxy, 2 mạng (Nexus 5596), 2 firewall ASA, 2 router.
    • 2 trong 4 SQL Server trước chỉ để backup, vừa được dùng cho tải chỉ đọc (chủ yếu Stack Exchange API).
    • 2 web server dành cho dev và meta, gần như không có tải.
  • Phần cứng thực sự cần (bỏ phần dư thừa, giữ hiệu năng): 2 SQL Server (Stack Overflow một máy, mọi site khác một máy, và theo tác giả gộp vào một máy vẫn còn dư), 2 web server ("có thể 3"), 1 Redis, 1 tag engine, 1 Elasticsearch, 1 load balancer, 1 mạng.
  • Scale up: SQL Server 384 GB RAM và 1,8 TB SSD; Redis 96 GB; Elasticsearch 196 GB; tag engine dùng CPU nhanh nhất mua được; web server bình thường (32 GB, 2 CPU 4 nhân).
  • Lưu trữ: khoảng 2 TB dữ liệu SQL, toàn bộ trên SSD. Thời gian ghi trung bình "0 ms", tức dưới đơn vị đo được. SAN chỉ dùng cho VM phụ trợ; nếu SAN chết, các site vẫn chạy.
  • Tỉ lệ đọc/ghi trên đĩa của DB là 40:60 (ghi nhiều hơn đọc), vì DB nằm gọn trong RAM và có 2 tầng cache phía trước nên gần như mọi lần đọc không chạm tới đĩa.
  • Hiệu năng trang: Question/Show (29,7 triệu hit/ngày) render trung bình 28 ms, mục tiêu dưới 50 ms; trang chủ 65 ms, bị coi là "rất chậm" và đang được sửa.
  • Đo mọi request: thời gian xử lý của mọi request đều được ghi lại. Theo tác giả, thiếu số liệu như vậy thì không biết dựa vào đâu để ra quyết định.

Vì sao

  • Mức dùng tài nguyên rất thấp: web server 5–15% CPU, SQL Server 5–10% CPU (2013). Phần dư dùng làm headroom khi có query hỏng, code lỗi hay tấn công, và để chưa phải nâng cấp khi tăng trưởng.
  • Theo tác giả, nguyên nhân chính là code hiệu quả: thứ không cần làm thì không làm. Code kém hiệu quả tốn điện, tốn phần cứng, khó hiểu hơn và làm trang chậm đi, nên giá của nó "cao hơn bạn nghĩ".
  • Cấu hình máy như vậy, theo tác giả (2013), không thuê được trên cloud với giá hợp lý.

Bài học cho SWE

  • Tách riêng số máy đang chạy và số máy thực sự cần. Phần chênh lệch là dư thừa có chủ đích (dự phòng, deploy cuốn chiếu), không phải lãng phí.
  • Biết workload đọc/ghi của mình ở từng tầng: khi cache tốt, đĩa của DB có thể chủ yếu là ghi.
  • Ghi thời gian từng phần (SQL, Redis, tag engine) cho mọi request là nền cho mọi tối ưu sau này.

Liên quan