How Discord Indexed Trillion of Messages Without Crashing Their Database
- Discord는 수십억 개의 메시지를 효율적으로 검색하기 위해 비용 효율적이고 확장 가능한 인덱싱 인프라를 구축해야 했습니다. 🔍
- 관리형 SaaS 솔루션의 예산 문제로 인해 텍스트 검색에 최적화된 Elastic Search를 선택했습니다. ⚙️
- 대규모 클러스터 관리 복잡성을 피하기 위해 샤딩 및 라우팅을 애플리케이션 계층에 위임하고, 여러 개의 작은 클러스터를 활용했습니다. 🧩
- 사용자 메시지를 메시지 큐에 보내고, 인덱스 워커가 배치로 수집하여 서버 출처에 따라 Elastic Search 클러스터로 라우팅하는 큐 시스템을 구현했습니다. 📤
- Elastic Search에는 필수 검색 메타데이터(역색인)만 저장하고, 전체 메시지 내용은 Cassandra 데이터베이스에 보관하여 효율성을 높였습니다. 📚
- Redis를 활용한 부하 인식 샤드 할당자를 구현하여 각 Elastic Search 샤드의 부하 점수를 관리하고, 새로운 서버를 가장 낮은 점수의 샤드에 할당했습니다. ⚖️
- 초기에는 최근 7일간의 메시지를 먼저 인덱싱하고, 이후 오래된 콘텐츠를 점진적으로 백필하는 2단계 접근 방식을 사용했습니다. ⏳
- 이 시스템은 수십억 개의 문서를 안정적으로 처리하며 성공적으로 확장되었습니다. 🚀
- 메시지 수가 수조 개에 달하면서 클러스터 아키텍처의 조정 오버헤드 증가, 노드 실패율 상승 등 여러 문제가 발생했습니다. 💥
- 배치 내 일부 작업 실패 시 전체 배치가 실패하여 메시지가 큐로 돌아가는 비효율적인 벌크 인덱싱 방식이 문제였습니다. 🔄
- 일부 대규모 서버가 Lucene의 샤드당 약 20억 문서 제한에 도달하여 인덱싱 작업이 실패하고 메시지가 검색 불가능해지는 상황이 발생했습니다. 🚫
- 클러스터가 예상보다 훨씬 커져(200개 이상 노드) Log4Shell과 같은 보안 패치 시 전체 시스템을 오프라인으로 전환해야 하는 등 운영 문제가 심화되었습니다. 🚧
- 기존에 성공적으로 사용하던 Kubernetes와 Elastic Kubernetes Operator를 활용하여 선언적 구성 및 자동 업데이트를 가능하게 했습니다. 🏗️
- 몇 개의 거대한 클러스터 대신, 마스터, 인제스천, 데이터 노드로 구성된 여러 개의 작고 전문화된 '셀' 클러스터를 도입했습니다. 🔬
- 메시지 손실 없이 대규모 백로그를 처리할 수 있는 Google Pub/Sub으로 큐 시스템을 교체하여 메시지 전달을 보장했습니다. ✅
- 메시지를 목적지별로 그룹화하여 처리하는 배치 처리 시스템을 구현하여 인덱싱 효율성을 높였습니다. 📦
- 수십억 개의 메시지를 가진 초대형 Discord 서버를 위해 여러 개의 프라이머리 샤드를 가진 전용 Elastic Search 셀을 구성하여 Lucene 제한을 극복했습니다. 👑
- 사용자별로 샤딩되는 전용 셀을 생성하여, 사용자들이 모든 DM을 한 번에 검색할 수 있는 기능을 제공했습니다. 💬
- 아키텍처는 규모에 따라 진화해야 하며, 전문화된 구성 요소는 복원력을 높이고, 관리형 서비스를 활용하면 운영이 간소화된다는 점을 배웠습니다. 🌱
데브허브 | DEVHUB | How Discord Indexed Trillion of Messages Without Crashing Their Database