OpenFreeMap, 초당 10만 요청을 견딘 경험 공유
(blog.hyperknot.com)- OpenFreeMap가 초당 10만 요청과 3억 건의 일일 트래픽을 성공적으로 처리함
- Wplace.live의 갑작스러운 인기와 자동화된 대량 요청이 트래픽 폭증의 원인임
- Cloudflare의 CDN 캐시율 99.4% , 서버는 남은 1,000 rps도 무난히 소화함
- 이로 인해 타일 누락 현상 등 사소한 장애만 발생, 서비스는 대부분 정상 운영임
- 앞으로는 참조자 기반 대역폭 제한 등 자동 트래픽 관리 개선 계획임
OpenFreeMap의 지난 10개월과 초대형 트래픽 대응 경험
OpenFreeMap은 지난 10개월간 매우 안정적인 운영 경험을 했음. Cloudflare의 대역폭 후원, Hetzner 서버의 안정성, Btrfs에서의 타일 서비스, nginx의 효율성 덕분에 시스템 신뢰성이 입증됨. 그러나 어느 날 갑자기 일부 타일이 로드되지 않는다는 보고를 받게 되었음. 이는 평소에는 알고리듬 버그 때문이지만 이번에는 open() "Too many open files" 오류가 nginx 로그에서 발견됨.
트래픽 모니터링 도구로 확인 결과, 24시간 동안 30억 요청이 발생했으며, 작은 타일 파일만으로도 215TB 트래픽을 기록함. 최근 5분간 3천만 건 요청, 즉 초당 10만 요청에 달하는 폭증 현상이 있었음. 이 트래픽은 상업용 지도 서비스에서는 월 600만 달러 이상의 비용이 들 것임.
Cloudflare 대시보드에는 96%가 200 OK로 응답했고, 3.6%만 비정상(206 Partial Content)임. 대다수 요청이 정상적으로 서비스되고, 일부 누락 타일을 제외하고는 전체 시스템이 잘 동작함을 확인함.
트래픽 폭증 원인: Wplace.live
이번 폭증의 원인은 Wplace.live라는 새로운 협업 드로잉 웹사이트임. 오픈 직후 수많은 사용자가 몰려들었고, 이들이 OpenFreeMap 기반 지도를 사용하도록 설계됨. 사용자들이 1픽셀/30초 제한을 우회하기 위해 자동화 툴(예: Puppeteer/Chromium, IP 회전 등)로 대량 요청을 발생시킴.
관리자는 예전 Neal.fun과 협력했던 경험을 들어, 트래픽 발생 전 사전 소통의 중요성을 강조함. 이번에는 서비스 운영에 지장을 줬기에 Cloudflare 규칙을 처음으로 적용하여 차단함. 향후에는 referer 또는 custom header 기반의 자동 트래픽 제어 방안(Cloudflare API 활용 포함)을 모색 중임.
Cloudflare의 지원과 OpenFreeMap 아키텍처의 성과
Cloudflare는 대역폭 후원을 매우 빠른 절차(주말 포함 48시간 내)에 승인해줬으며, 엔지니어들과 아키텍처 적합성 논의까지 진행함. 대규모 기업임에도 유연한 대응력을 보여줬음.
운영자는 99.4% CDN 캐시율을 달성했으며, 서버가 1,000 rps 로드도 견딘 것에 자부심을 느낌. 주간 데이터 업데이트를 제공하는 서비스에서는 상당히 높은 성과임.
Wplace.live 개발자와의 소통, 그리고 해결 제안
이후 Wplace.live 개발자와 연락이 닿아, 갑작스러운 200만 사용자 증가로 준비 부족을 이해함. 이들에게 OpenFreeMap 셀프 호스팅 인스턴스 지원을 제안, 트래픽 집중을 막고 효율성을 높이기로 논의함.
또한, 실제 200만 사용자 수에 비해 30억 요청이 발생한 것은 스크립트 기반 대량 요청이 압도적임을 시사함. 일반 사용자는 10~20회 요청에 그치므로, 서비스 정책을 변경해 불필요한 자동 요청을 방지하도록 추천함.
향후 개선 및 학습 내용
운영자는 두 가지 문제 개선을 예고함.
-
참조자(Referer) 기반 대역폭 제한
- Cloudflare에서 참조자별 요청을 24시간당 1억~2억회 등으로 제한하는 방안 도입 예정임
- 네이티브 앱은 custom header를 사용하는 쪽으로 유도 예정임
-
타일 누락 처리 및 서버 구성 개선
- 잘못된 서버 설정으로 인한 빈 타일이 생성되지 않도록 조치 예정임
OpenFreeMap은 현재 매월 500달러의 기부로 운영 중임. 인프라 비용은 충분히 충당하지만, 신규 개발은 한정된 개인 시간에 의존함. 추가 지원을 통해 개발 속도 및 서비스 안정성 확대 가능함.
GitHub 후원을 통해 프로젝트 지원에 참여할 수 있음: https://github.com/sponsors/hyperknot
Hacker News 의견
-
몇몇 이미지들은 스크립트키디들이 그린 거라고 추정함. 이 사이트는 모든 사용자에게 30초당 1픽셀만 허용했기에, 다들 Puppeteer나 Chromium으로 새로운 브라우저를 열고 픽셀을 클릭한 다음, 브라우저를 종료하는 방식으로 자동화를 돌렸던 것으로 생각함. IP 주소 회전까지 했을 수도 있는데, 어쩌면 그 정도 필요도 없었을 수 있음. 이 현상이 하룻밤 사이에 엄청난 규모로 커졌다는 걸 과소평가하지 않았으면 좋겠음. 내가 집 근처에 그려진 그림을 몇 사람에게 언급했더니, 웹사이트 언급도 안 했는데 다들 무슨 얘기인지 바로 알아챘음. 사람들이 이런 /r/place류의 프로젝트를 몇 년마다 정말 좋아하고, 이번엔 전세계 지도 위에 그릴 수 있어서 자기 집 위치 근처에 직접 그릴 수 있다는 점이 큰 호응을 불러온 것 같음
-
이게 maplibre에서 직접 static pmtiles 파일을 읽는 방식이었으면 어떤 차이가 있었을지 궁금함. Bunnycdn에서 pmtiles를 range request로 가져올 때, 실제 타일 서버에서 받아오는 것과 거의 동일한 응답속도를 경험했음
-
wplace는 커스텀 static pmtile 한 장으로 전체 요구사항을 해결할 수 있을 거라 생각함. 150GB OSM 데이터를 처리할 필요는 전혀 없을 케이스임
-
관련 링크 공유함
-
-
이런 자세한 설명과 투명성에 감사함. StatusGator의 장애 지도에 MapTiler 대신 OpenFreeMap을 도입하는 걸 고민 중임
- 언제든 이전해도 좋음. 만약 높은 가용성이 걱정되면 직접 호스팅하면 됨. 퍼블릭 인스턴스를 최대한 안정적으로 만들려고 계속 노력 중임
-
스크린샷만 봤을 땐 이거 VPS 한 대로도 충분해 보이고, 너무 복잡한 설계 같았음. 그런데 픽셀이 전 지구 지도 위에 얹혀 있다는 걸 깨달았음. 최고 요청 처리량이 어느 정도 될지 궁금함. 벤치마킹이 용이한 웹서버가 겨우 감당할 수 있을 수준일 수도 있을 것으로 생각함. 물론, 앱 특성상 큰 폭의 성능 저하가 있을 수도 있음. 1km에 64픽셀이면, 무압축 컬러로 전 지구 커버시 8TB 필요함(장기적으로 봐야 할 문제!). Hetzner에서 10TB 박스가 한 달 20유로임, 캐싱은 필수일 것 같음. wplace가 드로잉 레이어에 1000x1000 픽셀 png를 쓰고, 그림은 바로 뜨지만 지도 자체는 엄청 느리고 일부는 아예 안 뜨는 구간도 있음
- Hetzner에서 한 달 20유로면 좋아 보이긴 하겠지만, 실제로 필요한 순간에 항상 잘 돌아갈지는 또 다른 이야기임
-
열린 파일 수 제한이 문제였던 것 같은데, 그 제한만 올렸다면 감당할 수 있었을까 궁금함. 스팸 트래픽을 차단하는 건 이해가 가지만, 이론상으론 제한만 올려도 더 처리 가능하지 않았을까 의문임
- 여러 LLM과 긴 디버깅 끝에 nginx 커뮤니티 포럼에 질문글을 남겼음. 현재로썬 multi_accept와 open_file_cache, 그리고 worker_rlimit_nofile 조합 때문이라고 추정 중임. 자세한 내용은 여기 참고. 서버가 200 Mbps까지 사용 중이었어서, 제한을 올려도 오래 버티긴 어려웠을 것임
-
캐싱이 구현되어 있지 않은 사이트는 무조건 '귀찮아서' 그런 것인지 궁금함. 왜 wplace.live는 openfreemap에 그렇게 많은 트래픽을 넘기고, 본인 서버에 캐싱 서버 하나만 놔도 openfreemap보다 빠르거나 비슷하게 서비스할 수 있을 것 같은데?
-
openfreemap이 CDN 뒤에 있고, 홈페이지에도 다음과 같이 써 있음: "퍼블릭 인스턴스 무료, 뷰 수/요청수 제한없음, 회원가입/쿠키/API 키 필요없음. 비용은 기부로 충당함. 상업적 사용도 허용함". 읽어보면 그냥 바로 써도 되는 것으로 느껴짐. 굳이 CDN 앞단에 캐시 서버를 둘 이유가 없어보임. 대역폭을 확인하고 고민할 법도 하지만, 예상못한 바이럴 상황에서 다른 일에 쫓길 수 있음
-
이 질문에 딱 답할 수 있음: 우선순위 때문임. 나는 꽤 인기가 있는 경매 사이트를 운영하고 있고 지도 타일은 stadia maps에서 받아옴. 월 80달러를 내고 있는데, 타일을 캐싱해서 프록시에서 제공하면 더 저렴하게 가능함을 알지만, 더 긴급한 일이 항상 있어서 아직 캐싱 작업을 못 했음
-
여기서 다루는 데이터양이 어마어마함. 순간 56Gbps(서버 56대가 100% 트래픽 소비!)가 찍혔음. 단순 캐싱 서버 한 대로 커버할 수 없는 수준임. 이런 건 CDN 네트워크(Cloudflare 등)급이어야 감당 가능함
-
재밌는 사이트처럼 보이고, 영리 목적이 아닌 것 같음. 이런 사이트의 초점은 대개 "잘 돌아가게 만드는 것"에 있고, 대규모 트래픽 대응이 1순위엔 아님. 사용자도 하룻밤 사이 지수가 두 배로 늘었고, 유지보수하는 이도 혼자 혹은 소수로 보임
-
-
Cloudflare 직접 써본 적도 없고, 웹 맵 기술도 익숙하지 않음. 사이트가 대부분 정적 파일만 제공한다면 굳이 Hetzner를 계속 써야 하는 이유가 궁금함. Cloudflare Pages로 완전히 옮길 수는 없는지 의문임
- 타일은 렌더링이 필요함. 자주 쓰는 타일은 이미 cache되고, 그 캐시 역할이 Cloudflare에서 처리됨. 이론상 tileserver를 Cloudflare Pages로 이식할 순 있어도, 결국 포팅 작업도 해야 하고, 비용이 더 저렴해질 것 같지도 않음
-
리퍼러(Referrer) 기반 제한은 이상한 선택 같음. 만약 정상 사용자가 분당 10~20번 요청한다면, IP별로 분당 100건(평균 5배) 제한을 두면 대부분 차단 가능하지 않겠음? 아니면 소수 악의적 사용자라면 JA4/JA3 패턴으로 차단이 가능하지 않겠음?
-
한 명이 정말 지구 곳곳을 탐험하고 싶을 때도 있음. 예전에 Google Earth를 반나절 구경했던 기억이 있음. 리퍼러 기반 제한을 두는 게 더 낫다고 생각함, (트래픽 많이 쓰는) 사용자에겐 직접 퍼블릭 인스턴스 대신 셀프호스팅을 안내할 수 있음
-
리퍼러로 제한하는 게 좋은 첫 단계임(메인화면 안내 메시지도 바꿔야 할 듯). 사이트 단위로 사용량을 추적하는 게 더 효과적임. 사이트 측엔 사용 패턴을 바꿔달라고 요청할 수 있지만, 개별 사용자에겐 힘듦. IP 단위 제한도 추가하면 좋겠지만, 너무 낮게 설정하면 이런 경우엔 효과가 없을 것
-
-
멋지게 잘 차단했다고 생각함. 이건 ddos 공격임. 대역폭 요금을 별도로 안 냈으니 다행임, 그랬으면 진짜 '지갑 마비' 공격이었을 것임
-
캐시 히트율이 엄청 높음. 뭔가 특별히 구현한 기술이 있는지 궁금함
- 전체 경로 구조와 location block을 캐시를 염두에 두고 직접 설계했음. 궁금하면 nginx.conf 예시 참고하면 좋을 것임