1P by neo 2달전 | favorite | 댓글 1개

650,000,000 체크박스 체크하기: 예상치 못한 인기 대처하기

2024년 6월 26일, One Million Checkboxes (OMCB) 웹사이트를 출시함
  • 100만 개의 글로벌 체크박스를 가진 사이트로, 체크박스를 체크하면 모든 사용자에게 즉시 반영됨
  • 출시 후 30분 만에 수천 명의 사용자가 수백만 개의 체크박스를 체크함
  • Hacker News, /r/InternetIsBeautiful, Mastodon, Twitter 등에서 유입됨
  • Washington Post와 New York Times에도 소개됨
  • 첫날 5천만 개 이상의 체크박스가 체크됨
  • 2주 후 사이트를 종료하기 전까지 6억 5천만 개 이상의 체크박스가 체크됨

원래 아키텍처

  • 체크박스 상태는 100만 비트(125KB)로 저장됨
  • 클라이언트는 비트셋을 사용하여 체크박스를 렌더링하고 서버에 체크 상태를 알림
  • 서버는 Redis를 사용하여 비트를 업데이트하고 모든 클라이언트에 브로드캐스트함
  • nginx를 통해 정적 콘텐츠를 제공하고, Flask 서버를 통해 비트셋 상태와 웹소켓 연결을 처리함
  • Redis는 상태 저장 및 메시지 큐 역할을 함

확장 원칙

  • 비용 제한: 서버리스로 확장하여 파산하지 않도록 비용을 수학적으로 계산함
  • 단기적 해결책 수용: 사이트의 인기가 일시적일 것으로 가정하고, 빠른 해결책을 선택함
  • 간단하고 자체 호스팅된 기술 사용: 직접 서버를 운영하고 디버깅할 수 있는 기술만 추가함
  • 재미 추구: 돈보다는 재미를 우선시함
  • 글로벌 유지: 모든 사용자가 즉시 변화를 볼 수 있도록 글로벌 상태를 유지함

첫날: 폭발적인 인기

  • 30분 만에 서버 부하가 급증함
  • 추가 서버를 스핀업하여 부하를 분산시킴
  • Redis 연결 문제 해결을 위해 배치 업데이트를 도입함
  • Digital Ocean의 관리형 Redis 인스턴스를 업그레이드함

밤새 계획이 없었음

  • ITP 캠프에서 얼굴 인식 Pacman 게임을 전시하기 위해 계획을 세움
  • iPad를 가져가서 서버를 스핀업함
  • 서버 네이밍 규칙을 발전시키며 8개의 워커 VM을 운영함
  • 플라스크 프로세스 수를 줄이고 업데이트 배치 크기를 늘려 부하를 줄임

대역폭 문제

  • Digital Ocean의 대역폭 가격을 고려하지 않음
  • 상태 스냅샷 빈도를 줄이고, 업데이트 크기를 줄임
  • tc 유틸리티를 사용하여 초당 전송 데이터 양을 제한함

둘째 날: 계속 성장함

  • 입력 유효성 검사를 제대로 하지 않아 사이트가 다운됨
  • Redis 복제본을 추가하여 부하를 분산시킴
  • 플라스크 프로세스가 계속 충돌하여 자동 재시작 스크립트를 작성함

오래된 업데이트 문제

  • 클라이언트가 오래된 업데이트를 적용하여 상태가 잘못 표시되는 문제 발생
  • 타임스탬프를 추가하여 업데이트 순서를 보장함

Go로 재작성

  • 성능 엔지니어 친구와 함께 백엔드를 Go로 재작성함
  • 성능이 크게 향상됨
  • DDOS 공격을 CloudFlare를 통해 방어함

사이트 종료

  • 체크박스가 빠르게 체크 해제되지 않으면 동결되도록 변경함
  • Redis를 사용하여 동결 상태를 관리함
  • 2주 후 사이트를 종료함

배운 점

  • 두 번째로 '실제' 백엔드를 가진 서버를 공개 인터넷에 배포한 경험
  • 단기적인 해결책을 선택한 것이 좋은 선택이었음
  • Redis와 nginx의 강력함을 다시 확인함
  • 사람들이 익명으로 상호작용하는 사이트에 대한 갈망을 확인함

GN⁺의 정리

  • 이 글은 웹사이트의 예상치 못한 인기로 인해 발생한 기술적 문제와 해결 과정을 다룸
  • Redis와 nginx를 사용한 간단한 아키텍처로도 대규모 트래픽을 처리할 수 있음을 보여줌
  • 단기적인 해결책을 통해 빠르게 문제를 해결하고 사이트를 안정화하는 방법을 설명함
  • Go로의 재작성과 CloudFlare를 통한 DDOS 방어 등 다양한 기술적 도전을 다룸
  • 비슷한 기능을 가진 프로젝트로는 Reddit의 /r/Place와 같은 대규모 협업 프로젝트가 있음
Hacker News 의견
  • 많은 교훈과 역사적 지식을 배울 수 있었음

    • 모든 종류의 중단과 실패 지점을 다루었지만, 저장 공간 문제는 언급되지 않음
    • Redis가 Lua를 사용할 수 있다는 것을 몰랐으며, 이를 대체 상태로 사용하는 것에 관심이 생김
    • 클라우드 서비스의 대역폭 문제는 청구 초과를 피할 수 있는 하드 리미트가 없다는 점에서 가장 큰 불만 중 하나임
  • 훌륭한 글이었음! 웹사이트도 축하하지만, 글 자체가 가장 자랑스러워해야 할 부분임

  • 두 날 만에 사이트를 구축한 것은 좋은 선택이었음

    • 초기 경력 엔지니어들이 배워야 할 중요한 교훈임
    • 스케일링 문제는 실제로 문제가 될 때까지는 문제가 아님
    • 그 시점에서 좋은 문제이며, 생각보다 해결하기 어렵지 않음
  • 최근 관련된 프로젝트:

    • "One Million Checkboxes" - 링크 - 2024년 6월 (305개의 댓글)
  • 재미있는 프로젝트임

    • 6년 전 안드로이드에서 Pixmap이라는 협업 픽셀 편집 앱을 출시했음
    • 큐를 사용하여 각 이벤트를 PNG 이미지에 적용하고, 클라이언트는 연결 시 초기 PNG를 로드함
    • 각 픽셀 드로우 이벤트는 클라이언트에 작은 객체로 전송됨
    • 초기 로드 시 이미지 압축을 활용하고, 변경 세트는 매우 작음
    • 각 이벤트가 로그에 저장되므로 이미지를 "되감기"할 수 있음
    • 데모 링크
  • 훌륭한 글이었음 - 비용이 얼마나 들었는지 궁금함

  • 사람들은 제한된 익명 상호작용을 갈망한다는 믿음이 확인되었음

  • 백엔드 초보자로서 이 프로젝트에 대한 간단한 대체 아키텍처가 있는지 궁금함

    • 백만 개의 상태를 호스팅하고 클라이언트와 동기화하는 더 쉬운 방법이 있기를 바람
    • 글의 일부 솔루션이 이해하기 어려웠음
    • 작성자에게 찬사를 보냄 - 프로젝트가 훌륭함
  • 멋짐!

    • 다음 글은 체크박스의 통계 분석이 될 것인지 궁금함
    • 내가 선택한 체크박스가 거의 즉시 해제되어 슬펐던 기억이 있음
  • 게임이 아직도 라이브인지 궁금함

    • One Million Checkboxes에 접속했을 때 아무 것도 체크되지 않았고, JS 콘솔에 다음과 같은 메시지만 보였음
    • {"total":0,"totalGold":0,"totalRed":0,"totalGreen":0,"totalPurple":0,"totalOrange":0,"recentlyChecked":false}