로블록스의 캐시가 Redis의 한계를 넘어 13억 8천만 QPS를 유지한 방법
신뢰성과 효율성을 바탕으로 10배 증가한 트래픽 급증에 대응하기

Roblox의 대규모 멀티플레이어 게임 환경에서는 사용자가 표준 캐싱 패턴으로는 감당할 수 없는 방대한 양과 속도로 데이터를 읽고 씁니다. 사용자는 정적 데이터를 캐싱하는 일반 웹페이지에서 200ms의 지연은 눈치채지 못할 수 있지만, 로블록스에서 상호작용 데이터나 서버 메타데이터를 가져오는 데 200ms의 지연이 발생하면 게임 플레이가 중단되고 시뮬레이션된 게임 세계가 붕괴될 수 있습니다. 로블록스는 예측 불가능하고, 속도가 빠르며, 일시적인 데이터로 구성된 생태계에서 운영되며, 몰입감을 유지하기 위해 이러한 데이터를 밀리초 단위로 가져와야 합니다.
당사의 캐싱 계층은 수백만 명의 동시 사용자와 영구 저장소 사이에서 거대한 충격 흡수 장치 역할을 하도록 설계되었습니다. 이 계층은 초당 13억 8천만 쿼리(QPS)의 피크 부하를 처리하며, 단일 논리 클러스터는 초당 1억 QPS를 상회합니다. 이 글에서는 최대 클러스터에서 전례 없는 10배의 트래픽 급증을 처리하는 동시에, Redis® 노드 한계를 넘어 대규모 처리량을 확보하기 위해 어떻게 연합 캐싱 서비스를 아키텍처화했는지 그 비하인드 스토리를 공개합니다.

끊임없이 증가하는 수요를 충족하기 위해 업계 한계를 넘어 확장
Roblox의 캐싱 서비스는 Redis® 기술을 기반으로 구축되었으며, 하나의 Redis® 클러스터는 최대 1,000개의 노드를 지원할 수 있는 잠재력을 가지고 있습니다. 그러나 경험적으로 입증되고 업계에서 인정하는 한계는 그보다 훨씬 낮은 약 400~500개 노드 수준입니다.1 이는 노드 간 통신을 통해 상태, 운영 현황 및 샤드 매핑을 공유하는 Redis®의 분산형 Gossip 프로토콜 때문입니다. 노드 수가 수백 개를 넘는 클러스터에서는 Gossip 프로토콜로 인한 통신량이 상당한 CPU 및 네트워크 리소스를 소모하기 시작합니다. 각 노드는 끊임없이 증가하는 피어(peer)들로부터 상태 업데이트를 처리해야 하므로, 저지연으로 데이터를 제공하는 주된 업무에 할당되어야 할 리소스를 빼앗기게 됩니다. 이러한 제어 플레인 오버헤드는 불안정성과 예측 불가능한 성능으로 이어질 수 있으며, 이것이 바로 관리형 클라우드 제공업체들이 노드 수 제한을 적용하는 이유입니다. 이는 신뢰성을 저해하지 않고서는 넘을 수 없는 실질적인 한계입니다.
이러한 단일 클러스터에 대한 실질적인 제한은 Roblox 규모의 플랫폼을 지원하기에는 충분하지 않습니다. Roblox의 경우, 가장 큰 백엔드 서비스가 피크 시점에 하나의 논리적 Redis® 클러스터에서 1억 QPS 이상을 요구했는데, 이는 3개월 만에 1,000만 QPS에서 급증한 수치입니다.
우리는 이러한 아키텍처적 한계를 극복하기 위해 연합 아키텍처를 채택하여, 여러 개의 더 작고 독립적인 Redis® 클러스터 앞에 클라이언트 리버스 프록시를 배치했습니다. 예측 가능한 성능을 보장하기 위해 클러스터당 400노드 제한을 적용하고 있습니다.
수천 개의 애플리케이션과 서비스 관점에서 볼 때, 클라이언트 리버스 프록시는 이러한 서로 다른 클러스터들을 단일하고 통합된 확장 가능한 캐싱 서비스로 제공합니다. 이러한 페더레이션 덕분에 Gossip 프로토콜의 제약을 완전히 우회하여, 페더레이션에 클러스터를 추가하는 것만으로 거의 제한 없이 수평적으로 확장할 수 있습니다. 현재 당사의 최대 단일 캐싱 배포 환경은 6,000개 이상의 Redis® 노드로 구성되어 있으며, 이는 15개 이상의 독립적인 Redis® 클러스터에 의해 지원됩니다. 이러한 규모는 이 페더레이션 모델을 통해서만 가능해졌습니다.

3단계 마이그레이션 프로세스
수백 개의 활성 프로덕션 클러스터를 관리하면서 기존 환경에서 연합 아키텍처로 전환하는 것은 상당한 과업이었습니다. 2024년 말, 이들 클러스터 중 상당수가 이미 400노드 한도에 근접해 있었기 때문에, 더 높은 용량의 모델로 전환하는 것이 시급했습니다. 주요 과제는 표준 Redis® 인스턴스가 독립적으로 작동하며 다른 클러스터를 인식하지 못한다는 점이었는데, 이로 인해 마이그레이션 과정에서 데이터를 복제하기 위한 맞춤형 방법이 필요했습니다.
이를 해결하기 위해, 우리는 고객의 개입이나 애플리케이션 측의 변경 없이 서비스를 전환할 수 있도록 설계된 투명한 3단계 마이그레이션 파이프라인을 개발했습니다.
마이그레이션 워크플로
- 이중 쓰기: 클라이언트 리버스 프록시를 구성하여 이중 쓰기를 수행하도록 했으며, 들어오는 데이터를 기존 클러스터와 새로운 페더레이션 대상 모두에 동시에 전송했습니다.
- 패리티 및 읽기 전환: 이중 쓰기 프로세스를 통해 새 클러스터에 동일한 데이터가 채워지면, 모든 데이터에는 유효 기간(TTL)이 설정되어 있으므로 기존 클러스터의 읽기 트래픽을 새로운 페더레이션 아키텍처로 전환했습니다.
- 가동 중단: 새 클러스터의 안정성을 확인한 후, 기존 클러스터에 대한 모든 쓰기 작업을 중단하고 클러스터를 폐기했습니다.
가장 중요한 서비스를 단일 Redis® 클러스터의 한계를 훨씬 뛰어넘는 6,000개 이상의 노드를 지원하는 페더레이션 모델로 성공적으로 이전했습니다.
Grow a Garden의 폭발적인 성장 대응
2025년 4월부터 우리는 그 어떤 서비스도 경험하기 힘든 규모의 용량 문제에 직면했습니다. 그 촉매제는 'Grow a Garden'의 경이로운 성공이었습니다. 출시 불과 몇 주 만에 'Grow a Garden'은 Roblox의 기록뿐만 아니라 동시 접속자 수(CCU) 측면에서 게임 업계의 역대 최고 기록까지 경신하기 시작했습니다. 불과 3개월 만에 이 게임의 이용자 수는 기존 단일 게임 CCU 기록인 280만 명을 훌쩍 넘어 2,100만 명 이상의 정점을 기록했습니다. 이러한 폭발적인 성장으로 인해 가장 큰 Redis® 클러스터로 유입되는 트래픽은 10배, 전체 캐싱 시스템으로 유입되는 트래픽은 3배 증가했습니다.
Roblox는 자체 데이터 센터의 물리적 서버에서 캐싱 시스템을 운영하고 있으며, 이러한 전례 없는 성장은 당사의 장기 용량 계획에 포함되지 않았습니다. 이 거대한 물결을 견뎌내고 플랫폼의 안정성을 유지하기 위해, 우리는 신뢰성을 최우선으로 하면서 기존 서버 군의 효율성을 획기적으로 개선해야 했습니다.
트래픽 급증 시 효율성 개선
먼저, 최적화 작업의 우선순위를 정하기 위해 시스템 내 가장 큰 영향을 미치는 병목 현상을 파악해야 했습니다. Roblox 캐싱은 Redis® 백엔드 노드용과 Envoy용, 두 가지 서로 다른 하드웨어 풀에서 실행됩니다. Redis® 플릿은 주로 메모리 제약이 있는 반면, 클라이언트 프록시는 컴퓨팅 제약이 있습니다.
메모리 제약이 있는 Redis® 플릿의 경우, 물리적 머신 그룹 간 메모리 사용량을 더 균형 있게 분배하기 위해 새로운 스케줄링 정책을 도입했습니다. 또한 메모리 조각화를 줄이기 위해 컨테이너 크기를 미세 조정했습니다.
CPU 활용도를 높이기 위해 캐시 시스템에 두 가지 주요 최적화를 적용했습니다:
- 클라이언트 프록시 자동 확장: 컴퓨팅 자원에 의존하는 클라이언트 프록시 클러스터의 자동 확장 정책을 조정했습니다. 목표 CPU 값에 대한 허용 편차를 낮춤으로써, 스케일업 임계값을 변경하지 않고도 작업의 평균 CPU 사용률을 높일 수 있었습니다.
- 내부 클러스터 상태 점검: 불필요한 하트비트를 제거하기 위해 내부 상태 점검을 최적화하여, 기존 감지 간격을 유지하면서도 컴퓨팅 리소스를 절약했습니다.
이러한 변경 사항으로 인해 CPU 활용도가 약 10% 향상되었습니다. 마지막으로, cgroup 컨테이너 수준 격리를 통해 이 두 가지 매우 다른 워크로드를 동일한 머신 풀에 함께 배치함으로써 전체 용량 요구 사항을 25% 줄일 수 있었습니다.
흔들림 없는 신뢰성을 위한 엔지니어링
기록적인 수요를 충족하기 위해 분주하게 움직이는 와중에도 신뢰성은 여전히 최우선 과제였습니다.
종단간 가시성
우리는 먼저 캐싱 시스템의 포괄적인 종단 간 상태 모니터링을 위해 가시성 스택에 대대적으로 투자하여 잠재적인 장애를 파악하는 데 주력했습니다. 전체 요청 라이프사이클에 걸쳐 서버 성공 및 클라이언트 측 오류를 추적함으로써, 문제를 신속하게 감지하고 진단하여 사용자 영향이 발생하기 전에 미리 예방할 수 있었습니다. 예를 들어, 실시간 트래픽을 샘플링하여 과도하게 액세스되어 캐싱 계층에 부하를 주는 데이터를 식별하는 핫 키 감지 기능을 추가했습니다. 시스템이 핫 키를 감지하면, 서버와 클라이언트 양쪽에서 해당 키에 대한 트래픽을 선제적으로 제한하여 시스템 과부하를 방지할 수 있습니다.
오류 처리
이 정도 규모의 분산 시스템에서는 부분적인 오류가 가끔 발생합니다. 우리는 이러한 오류를 우아하게 처리하고 그 영향을 최소화하도록 시스템을 설계했습니다.
- 배치 요청의 부분적 장애: 우리는 배치 요청에서 발생하는 부분적 장애를 처리할 수 있도록 시스템을 재설계했습니다. 이전에는 샤드화된 배치 요청에서 단 하나의 요청이 실패해도 전체 배치가 실패했습니다. 이제 일부 키의 검색이 실패하더라도 나머지 요청은 성공할 수 있습니다.
- 헤드-오브-라인(head-of-line) 차단 완화: 캐싱 시스템은 빠른 속도를 요구받습니다. 사소한 네트워크 지연이라도 요청이 쌓여 타임아웃이 발생할 수 있으며, 이를 헤드-오브-라인 차단이라고 합니다. 우리는 클라이언트와 프록시 계층 모두에 지능형 재시도 메커니즘과 연결 풀링 전략을 구현하여, 단 하나의 느린 요청이 다른 요청에 영향을 미치지 않도록 방지했습니다.
- 오류 및 지연 시간 주입: 복원력을 테스트하기 위해, 저희는 오류 주입 프레임워크를 사용하여 프로덕션 환경에 정기적으로 제어된 오류(노드 중단, 랙 중단, 네트워크 지연, API 오류)를 주입합니다. 이러한 조건 하에서 시스템의 동작을 분석함으로써, 취약점을 사전에 파악하고 수정하여 지속적인 안정성을 보장합니다.
클라이언트 측 복원력
캐싱 시스템이 갑작스러운 트래픽 급증으로 인해 과부하되는 것을 방지하기 위해, 견고한 클라이언트 측 장애 복원력을 구현했습니다. 이 메커니즘은 애플리케이션 수준에서 작동하여, 단일 서비스가 캐시 리소스를 독점하지 못하도록 보장합니다.
- 흐름 제어를 위한 속도 제한: 클라이언트는 총 아웃바운드 트래픽에 제한을 두어, 백엔드 서비스가 처리할 수 있는 양보다 많은 요청을 보내지 않도록 합니다. 이 한도를 초과하면 요청이 제한되어 서비스가 과부하되는 것을 방지합니다.
- 재시도 및 타임아웃 메커니즘: 당사의 클라이언트 라이브러리는 타임아웃 및 재시도 예산 등 세심하게 조정된 재시도 메커니즘을 사용하여 '썬더링 허드(thundering herd)' 현상을 방지합니다. 이를 통해 영향 범위를 제한하고, 리소스를 확보하며, 무기한 중단이나 동시 재시도로 인해 시스템이 과부하되는 것을 방지함으로써 전반적인 시스템 응답성을 향상시킵니다.

Roblox 캐싱의 미래
Roblox의 캐싱 여정은 각 애플리케이션 소유자가 직접 관리하는 베어메탈 Redis® 클러스터로 시작되어, 이후 캐싱 팀이 관리하는 Memcached 클러스터로 이동했으며, 최종적으로는 Redis® 클러스터가 관리형 서비스로 제공되는 Redis®-as-a-service 모델로 전환되었습니다. 이 모델은 현재 규모에서는 매우 효과적인 것으로 입증되었지만, 로블록스처럼 역동적인 플랫폼의 경우 서비스 효율성과 리소스 격리 측면에서 한계가 있음을 인지하고 있습니다.
플랫폼이 지속적으로 성장함에 따라, 저희는 ValKey를 기반으로 구축된 차세대 멀티테넌트 캐싱 서비스에 상당한 투자를 할 계획입니다. 이 아키텍처는 멀티테넌시를 통해 공통 자원을 공유함으로써 비용을 대폭 절감하는 동시에, 각 테넌트에 대한 데이터, 자원 및 장애 격리를 보장하도록 설계되었습니다. 저희의 목표는 로블록스에서 점점 더 방대해지는 경험에 대한 수요를 충족시키기 위해 캐싱 인프라의 성능, 확장성, 안정성 및 비용 효율성을 크게 향상시키는 것입니다.
감사의 말씀:
이번 성과는 팀원들의 협력으로 이루어졌습니다. 크게 기여해 주신 팀원들인 Utkarsh Singh, Karthick Ramachandran, Vineesha Kasireddy, Weiji Hu, Leon Gao에게 감사의 말씀을 전합니다.
1AWS는 ElasticCache를 500노드로 제한합니다.
*Redis는 Redis Labs Ltd.의 상표입니다. 이에 대한 모든 권리는 Redis Labs Ltd.에 귀속됩니다.


