투다 속도 개선 작업 - 2. Redis를 활용한 성능 개선

최민길(Gale)·2023년 1월 7일
1

안녕하세요 여러분! 오늘은 저번 포스팅에 이어 Redis를 활용한 성능 개선 내용에 대해 포스팅해보려고 합니다ㅎㅎ

저번 게시글에서처럼 현재 로그인 토큰을 벨리데이션하는 과정에서 유저 정보가 맞는지를 DB를 통해 검증해왔습니다. 하지만 AWS 성능 개선 도우미 지표에 따르면 이 과정에서 쿼리 실행 요청이 매우 많아 쿼리 실행 대기가 발생하는 것을 알 수 있습니다. 따라서 이를 해결하기 위해 DB에서 벨리데이션하는 과정을 조금 더 효율적으로 변경하려고 합니다.

이에 따른 해결책으로서 Redis를 이용하여 벨리데이션이 완료된 토큰의 경우 추가 검사를 하지 않고 Redis에 필요한 내용을 저장하여 접근하는 방식을 고안했습니다. 따라서 기존에 API를 실행 시 매번 실행되던 벨리데이션 방식이 로그인 토큰이 유효할 동안 토큰 정보를 Redis에서 가져와 데이터를 가져옴으로서 DB의 쿼리 요청 수가 줄어 성능이 향상되는 것을 기대하고 있습니다.

Redis란 Key, Value 구조의 인메모리 데이터베이스입니다. 인메모리 데이터베이스란 주 메모리에 데이터를 저장하는 방식으로 기존 DB의 경우 디스크 단위까지 내려가 저장된 데이터를 가져오기 때문에 속도가 느린 반면 인메모리 DB의 경우 캐시에 데이터를 저장하여 빠르게 읽어올 수 있습니다. 대표적으로 Redis와 Memcached 등 많은 서비스가 존재합니다. Memcached의 경우 멀티 스레드를 지원하여 더 많은 작업 처리를 할 수 있으나 다양한 타입을 지원하진 않습니다. 반면 Redis의 경우 다양한 타입을 지원하나 싱글 스레드 방식으로 복잡한 작업을 진행 시 성능이 떨어질 수 있습니다. 저는 로그인 토큰을 디코딩한 결과를 저장하고, 로그인 토큰이 들어왔을 때 Redis에 존재 여부에 대해서만 확인할 예정이기 때문에 싱글 스레드로도 충분히 가능할 것이라 판단하였고 유저 정보에 필요한 다양한 타입을 저장할 수 있는 Redis를 선택했습니다.

우선 PHP에서 Redis를 직접적으로 지원하지 않아 php-redis 모듈을 추가 설치하여 redis를 사용하였습니다. 로그인 토큰을 입력받으면 디코딩 후 Redis에 같은 정보가 존재한다면 DB에서 참조하지 않고 벨리데이션을 마치고, 만약 Redis에 정보가 없다면 DB에서 유저 정보를 체크한 후 Redis에 관련 정보를 추가합니다.

배포 후 약 1시간 후 유저 벨리데이션 쿼리 실행 비율 및 이로 인한 latency time이 거의 0에 가까운 것을 통해 기존에 발생한 수많은 쿼리 콜을 절약할 수 있었습니다. 이를 통해 DB 부하를 줄여 사용자들이 많이 몰려 더 많은 쿼리가 실행될 때에도 서버를 안정적으로 유지할 수 있습니다. 하지만 배포 시 로드밸런싱으로 두 개의 서버에서 실행시켰을 시 오류가 발생하였는데, 이 부분의 원인 파악 후 추후 로드밸런싱을 가동하여 더 많은 트래픽을 처리할 수 있도록 조치할 예정입니다. 이상으로 오늘의 포스팅 마치도록 하겠습니다!

+++ 수정
오후 10시에 101명의 동접자들이 몰렸을 때 기존 약 1분 가량의 로딩이 발생한 것에 비해 최대 2초 가량의 로딩이 발생하여 30배 이상의 성능 향상을 이루어냈습니다. 이를 통해 쿼리 실행 수를 줄여 DB 부하를 성공적으로 줄여 사용성 향상에 크게 기여했다는 것을 알 수 있습니다.

profile
저는 상황에 맞는 최적의 솔루션을 깊고 정확한 개념의 이해를 통한 다양한 방식으로 해결해오면서 지난 3년 동안 신규 서비스를 20만 회원 서비스로 성장시킨 Software Developer 최민길입니다.

0개의 댓글