채용 공고 우대사항에서 심심치 않게 볼 수 있는 대규모 트래픽 처리에 대한 경험 여부를 보고 어디서 그런 경험을 할 수 있을 까 생각을 했는데, 직접 대규모 트래픽 처리를 할 수 있는 경험을 갖는 것은 신입 개발자로써는 거의 불가능한 일이라고 생가합니다.간접 경험으로 지식을 쌓고자 이 글이 눈에 들어와 읽어보게 되었습니다.
분당, 초당 수십만 건의 요청을 처리하기 위해서는 물리적 서버 증설로 다량의 트래픽을 모두 처리하는 것이 가장 간단한 방법일 수 있습니다. 하지만 증설 비용, 특정 시점에만 몰리는 트래픽인 경우 자원이 낭비되는 것은 기업의 입장에서는 충분히 고려해야만 하는 상황입니다. 이 분이 겪었던 문제는 크게 Redis 과부하 문제, 선착순 포인트 지급과 데이터베이스 과부하 문제 , API 중복 요청 및 Gateway 과부화 문제가 있었습니다.
Redis 과부하 문제를 해결하기 이전에 Redis가 캐싱하는 데이터를 두가지로 분류하여 해결법을 접근하려고 하셨습니다. 모든 유저에게 동일하게 보이는 Universal Data와 유저 별로 다르게 사용되는 User-Specific Data입니다.
Universal Data로 인한 Redis CPU 과부하 문제를 웹 서버의 Local Cache를 사용하여 Universal Data를 서버 내에서 전부 캐싱하는 방법으로 Redis의 사용량을 줄임으로써 해결을 하셨습니다. 또한 Universal Data의 빠른 캐시 초기화가 중요한 경우, Redis에서 제공하는 메시지 패턴 중 하나인 Pub/Sub를 통해 Redis 채널을 구독하여 캐시를 업데이트할 수 있는 구독자를 구현하고 이 구독자는 Redis에서 메시지를 수신하고 로컬 캐시를 초기화하는 작업을 수행하게 하는 것입니다.
User-Specific Data의 경우는 유저 수에 비례하여 캐싱해야하는 데이터가 많아지고, 데이터 크기가 커질수록 Redis 메모리 사용량이 늘어난다는 문제가 생길 수 있다고 하셨습니다. 이러한 문제의 해결법으로 Redis에 DTO와 같은 데이터 저장 시 다양한 압축방법을 활용하여 데이터 크기를 최소화하여 저장하는 방식을 사용하셨습니다. 여기서 주의사항은 아주 작은 크기의 데이터를 압축하면 오히려 데이터가 커질 수 있다는 것이었습니다.
Redis 과부하로 데이터를 처리하지 못하면 그 데이터가 그대로 데이터베이스로 들어가 장애가 생기지 않도록 Fallback 로직을 구현하는 것도 중요하다고 하셨습니다.