Tích 650.000.000 ô checkbox: ứng phó với mức độ phổ biến ngoài dự kiến
Ngày 26 tháng 6 năm 2024, ra mắt website One Million Checkboxes (OMCB)
- Một trang web có 1 triệu ô checkbox toàn cục; khi một ô được tích, thay đổi sẽ được phản ánh ngay lập tức cho mọi người dùng
- Chỉ sau 30 phút kể từ khi ra mắt, hàng nghìn người dùng đã tích hàng triệu ô checkbox
- Lưu lượng đến từ Hacker News, /r/InternetIsBeautiful, Mastodon, Twitter, v.v.
- Cũng được giới thiệu trên Washington Post và New York Times
- Trong ngày đầu tiên, hơn 50 triệu ô checkbox đã được tích
- Trước khi đóng site sau 2 tuần, đã có hơn 650 triệu lượt tích ô checkbox
Kiến trúc ban đầu
- Trạng thái checkbox được lưu dưới dạng 1 triệu bit (125KB)
- Client dùng bitset để render checkbox và báo trạng thái tích lên server
- Server dùng Redis để cập nhật bit và broadcast tới mọi client
- Phục vụ nội dung tĩnh qua nginx, còn server Flask xử lý trạng thái bitset và kết nối WebSocket
- Redis đóng vai trò vừa lưu trạng thái vừa là hàng đợi thông điệp
Nguyên tắc mở rộng
- Giới hạn chi phí: tính toán chi phí bằng công thức để có thể mở rộng theo kiểu serverless mà không bị phá sản
- Chấp nhận giải pháp ngắn hạn: giả định độ phổ biến của site chỉ là tạm thời và chọn giải pháp nhanh
- Dùng công nghệ đơn giản, tự host: chỉ bổ sung những công nghệ có thể tự vận hành và debug trực tiếp
- Ưu tiên niềm vui: đặt sự thú vị lên trên tiền bạc
- Duy trì tính toàn cục: giữ trạng thái toàn cục để mọi người dùng có thể thấy thay đổi ngay lập tức
Ngày đầu tiên: bùng nổ mức độ phổ biến
- Tải server tăng vọt chỉ sau 30 phút
- Spin up thêm server để phân tán tải
- Áp dụng cập nhật theo lô để giải quyết vấn đề kết nối Redis
- Nâng cấp instance Redis managed của Digital Ocean
Không có kế hoạch cho cả đêm
- Lập kế hoạch để trưng bày trò chơi Pacman nhận diện khuôn mặt tại trại ITP
- Mang theo iPad để spin up server
- Vừa phát triển quy tắc đặt tên server vừa vận hành 8 worker VM
- Giảm số tiến trình Flask và tăng kích thước batch cập nhật để giảm tải
Vấn đề băng thông
- Ban đầu không tính đến giá băng thông của Digital Ocean
- Giảm tần suất chụp snapshot trạng thái và giảm kích thước cập nhật
- Dùng tiện ích
tc để giới hạn lượng dữ liệu truyền mỗi giây
Ngày thứ hai: tiếp tục tăng trưởng
- Site bị sập do không kiểm tra hợp lệ đầu vào đúng cách
- Thêm bản sao Redis để phân tán tải
- Các tiến trình Flask tiếp tục crash nên đã viết script tự khởi động lại
Vấn đề cập nhật cũ
- Phát sinh vấn đề client áp dụng các cập nhật cũ khiến trạng thái hiển thị bị sai
- Thêm timestamp để bảo đảm thứ tự cập nhật
Viết lại bằng Go
- Cùng một người bạn là kỹ sư hiệu năng viết lại backend bằng Go
- Hiệu năng được cải thiện đáng kể
- Chống đỡ tấn công DDOS thông qua CloudFlare
Đóng site
- Thay đổi để các checkbox sẽ bị đóng băng nếu không được bỏ tích đủ nhanh
- Dùng Redis để quản lý trạng thái đóng băng
- Đóng site sau 2 tuần
Điều rút ra
- Đây là lần thứ hai triển khai một server có backend “thực sự” lên Internet công cộng
- Việc chọn các giải pháp ngắn hạn là một quyết định đúng đắn
- Một lần nữa khẳng định sức mạnh của Redis và nginx
- Xác nhận rằng mọi người rất khao khát những website nơi họ có thể tương tác ẩn danh
Tóm tắt của GN⁺
- Bài viết này nói về các vấn đề kỹ thuật phát sinh do website bất ngờ trở nên cực kỳ phổ biến và quá trình giải quyết chúng
- Cho thấy ngay cả với một kiến trúc đơn giản dùng Redis và nginx vẫn có thể xử lý lưu lượng rất lớn
- Giải thích cách nhanh chóng xử lý sự cố và ổn định site bằng các giải pháp ngắn hạn
- Đề cập đến nhiều thách thức kỹ thuật như viết lại bằng Go và phòng thủ DDOS qua CloudFlare
- Một dự án có chức năng tương tự là các dự án cộng tác quy mô lớn như /r/Place của Reddit
1 bình luận
Ý kiến trên Hacker News
Có thể học được nhiều bài học và kiến thức lịch sử
Bài viết rất tuyệt! Chúc mừng cả website nữa, nhưng bản thân bài viết mới là phần đáng tự hào nhất
Việc xây dựng trang chỉ trong hai ngày là một lựa chọn đúng đắn
Dự án liên quan gần đây:
Dự án thú vị
Bài viết rất hay - tôi tò mò không biết chi phí là bao nhiêu
Điều này củng cố niềm tin rằng con người khao khát những tương tác ẩn danh có giới hạn
Với tư cách là người mới học backend, tôi tự hỏi liệu có một kiến trúc thay thế đơn giản hơn cho dự án này không
Hay đấy!
Tôi tự hỏi liệu trò này còn đang chạy hay không