Stack Overflow: The Architecture - 2016 Edition

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

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

Bài 1 trong series của Nick Craver. Tiền thân: Stack Overflow 2013; các bài sau: Stack Overflow 2016, Stack Overflow 2016, Stack Overflow 2018, Stack Overflow 2019.

Bối cảnh

Số liệu một ngày (9/2/2016):

  • 209 triệu HTTP request, trong đó 66 triệu page load;
  • 504 triệu SQL query, 5,8 tỷ Redis hit;
  • trang câu hỏi render trung bình 22,7ms, trang chủ 11,8ms.

So với 11/2013: thêm 61 triệu request/ngày mà thời gian xử lý ASP.Net giảm từ 757 xuống 447 giờ, nhờ nâng cấp phần cứng 2015 và tối ưu code ("performance is still a feature").

Thay đổi chính (kiến trúc 2016, gần như không đổi so với 2013)

  • Phần cứng toàn bộ: 4 SQL Server, 11 web server IIS, 2 Redis, 3 tag engine, 3 Elasticsearch, 4 HAProxy. Thực tế chỉ cần 1 web server, và họ đã vô tình thử điều đó vài lần.
  • Ứng dụng Q&A multi-tenant: một app phục vụ mọi site Stack Exchange; có thể chạy cả mạng lưới trên một app pool.
  • Service tier: tag engine và API nội bộ chạy 3 bản thay vì 9, vì việc nặng (tải lại bài và tag mỗi 2 phút) không cần lặp trên mọi web server.
  • Cache 2 tầng: L1 là HTTP cache trong process, L2 là Redis (dữ liệu dạng Protobuf). Miss cả hai thì lấy từ nguồn và ghi vào cả hai. Pub/sub của Redis dùng để xoá L1 trên các server khác. Redis ~160 tỷ op/tháng mà mỗi instance dưới 2% CPU.
  • Websocket: ~500.000 kết nối đồng thời lúc cao điểm, chạy ngay trên web tier, thay polling. Vấn đề họ gặp: cạn ephemeral port và file handle ở load balancer.
  • SQL Server là nguồn sự thật duy nhất: 2 cluster AlwaysOn, mỗi cluster 1 master (gánh gần hết tải) + 1 replica ở New York + 1 replica ở Colorado (DR), replicate bất đồng bộ. Máy 384–768GB RAM, SSD PCIe. Dùng SQL đơn giản qua Dapper (micro-ORM tự viết); chỉ còn 1 stored procedure.
  • Elasticsearch cho tìm kiếm, vì CPU của SQL Server đắt; index tăng dần bằng ROWVERSION.

Vì sao

Theo Stack Overflow: SQL đơn giản thì nhanh; máy mạnh + cache tốt + code được tối ưu (họ tự viết nhiều thư viện hiệu năng cao: Dapper, StackExchange.Redis, Jil, MiniProfiler) đủ cho quy mô của họ. Họ cố ý cấp dư web tier vì rolling build, headroom và dự phòng.

Dự phòng (trả lời câu hỏi "scale dọc thì một điểm hỏng?")

"Mọi thứ đều dư thừa":

  • mỗi server có một cặp ở rack còn lại;
  • 2 nguồn điện, 2 UPS, 2 máy phát;
  • 4 ISP, 4 router edge;
  • cả hệ thống được nhân đôi ở data center thứ hai (Colorado).

Scale dọc ở đây đi kèm dư thừa theo chiều ngang ở mức hạ tầng, không phải chạy trên một máy duy nhất.

Bài học cho SWE

  • Monolith + DB quan hệ + cache vẫn phục vụ được hàng trăm triệu request/ngày nếu đo mọi request (MiniProfiler chạy trên mọi trang) và tối ưu liên tục.
  • Phân biệt cần bao nhiêu máy với chạy bao nhiêu máy: phần dư là để deploy và chịu lỗi.
  • Đưa việc nặng, lặp lại ra một tầng riêng ít bản (tag engine) thay vì làm trên mọi web server.
  • Đây là bối cảnh workload đọc nhiều, cache được tốt. Không suy ra rằng mọi hệ thống đều không cần tách.

Liên quan