관리 메뉴

피터의 개발이야기

[Redis] 쿠버네티스 환경에서 Redis 모니터링의 필요성 본문

DevOps/Redis&Redict

[Redis] 쿠버네티스 환경에서 Redis 모니터링의 필요성

기록하는 백앤드개발자 2024. 2. 17. 05:48
반응형

ㅁ 개요

 ㅇ Redis 모니터링에 관한 글을 적으면서 정작 Redis를 왜 모니터링 해야하는 지 정리를 해야겠다는 생각을 하게 되었다.

 ㅇ Redis를 메인디비로 쓰고 있는 이유와 그로인해 서비스 performance를 위해 지속적으로 모니터링이 필요한 이유를 정리하였다.

 

ㅁ 고가용성 쿠버네티스 환경에서의 Redis의 필요성

  RDS의 속도한계는?

 내가 현재 담당하고 있는 서비스는 금융사들의 대량 메시지를 처리하는 업무이다. 유동적인 고객의 트래픽을 소화하기 위해 AWS + 쿠버네티스 환경에서 오케스트레이션 환경을 구축하여 고가용으로 처리하고 있다. 대량 트래픽을 처리하는 과정에서 RDS의 환경은 한계가 있었다. 버스트 트래픽이 발생하면  집중적으로 하나의 테이블에 데이터를 Create, Update하기에는 한계가 있었다. RDS의 부담을 줄이기 위해 디비를 클러스터링 하고 CQRS(Command Query Responsibility Segregation) 패턴을 적용하여 읽기 및 쓰기 작업을 분리하여 성능과 확장성을 개선을 하였다. 하지만, 건당 처리 속도는 아무리 빨라도 2~10ms가 필요하였다. 그래서 초당 처리할 수 있는 트래픽이 1000TPS를 넘기긴 어렵다.

 

  ms VS μs

 Redis의 command당 처리 속도는 10~90μs로 측정되었다. ms(밀리초)는 1000분의 1초이고, μs(마이크로초)sms 1,000,000분의 1초이다. RDS의 데이터는 SSD에 저장한다고 하지만 Redis의 데이터는 서버의 주 메모리에 저장된다. Redis와 같은 형태를 인 메모리 데이터베이스라고 하는데, 이 형태는 디스크에 액세스해야 할 필요가 없어서 검색 시간으로 인한 지연을 방지한다. RDS처럼 CPU가 index를 조회하고 다시 index에 따른 해당 데이터를 디스크에서 액세스해야하는 일련의 과정이 절약되어 Redis가 빠른 속도를 보장할 수 있게 되어, 초당 3000TPS를 버틸 수 있다.

 

  결국 Redis는 RDS보다 더 간결한 로직을 구현하여 데이터를 액세스하기 때문에 일반적으로 작업을 실행하는 데 1밀리초 미만이 소요된다. 간결한 구조는 이름으로도 나타나는데, Redis는 REmote Dictionary Server의 약어이다. 한마디로 서버의 메모리 키 값 스토어인 것이다. 

 

ㅁ 마이크로서비스 패턴

 Redis의 필용성을 이야기 하면서 마이크로서비스의 패턴을 이해할 필요가 있다.

 

 CQRS(Command Query Responsibility Segregation) 패턴부하 분산 패턴
 RDS의 성능을 향상하기 위해 클러스터링, 즉 여러 DB 인스턴스를 구축하여 트래픽을 분산한다. 마이크로 서비스에서 읽기 및 쓰기 작업을 분리하여 성능과 확장성 및 유지 관리를 개선할 수 있다. 유지관리의 예를 들자면, [AWS] RDS Aurora 성능 증감 시 작업 과정 정리, fail over 처리가 있는데, 운영상 특정 시기에 대량 트래픽일 몰릴 경우 RDS CUP 사용량이 90%가 넘는 경우가 있는데 이를 대비하기 위해 RDS Aurora의 성능업 작업이 필요한 경우가 있다. 이럴 때에 CQRS패턴이 유리하다.

 

 Event-Driven Architecture(EDA) 패턴

 Redis는 메모리를 사용하여 빠른 속도를 보장하지만, 데이터 유실의 위험성도 커지게 된다. 정적 데이터는 필연적으로 RDS를 사용하여 SSD에 저장해야 한다. Redis와 RDS의 속도차이를 극복하기 위해 EDA 패턴이 필요하다. Redis의 큐에 RDS 작업을 적재하고 순차적으로 작업을 수행하는 방식이다. 이렇게 하면, EDA 패턴을 사용해 병렬처리도 가능하고, RDS 장애 시 데이터 유실을 방지할 수 있다. 그리고버스트 트래픽 시 갑작스러운 RDS Aurora의 성능 변경작업이 용이해 진다.

 

 재시도 패턴

 Redis를 큐형태로 사용하고 순차적으로 Aurora 작업을 수행할 때에 필연적으로 재시도 패턴이 필요하다. 큐의 작업을 이벤트로 받아서 처리할 때에 실패 시에 재시도를 할 수 있도록 매커닉적인 조치가 필요하다. RDS 장애이든, 성능변경을 위한 fail over처리든 SLA를 정하여 어느정도까지 재처리를 수행하고, 어느 정도까지 최종 실패처리를 하여 유실처리를 할 것인지 정해야 한다. 왜냐하면, 재시도 패턴은 필연적으로 Redis에 데이터가 적재만 되고 소비가 이루어지지 않으면, OOME가 발생하기 때문이다. 

 

  이 부분에서 Redis의 모니터링이 필요하다. Redis는 빠르지만, OOME도 빠르게 오기 때문이다. 그래서 Redis 지연에 대한 모니터링이 필요하다. 크게 네트워크 지연, 메모리 사용량에 따른 병목으로 모니터링의 필요성을 설명하려 한다. 

 

ㅁ Redis 모니터링 필요성:  네트워크

 Redis는 데이터의 일관성과 무결성을 보장하기 위해 싱글스레드를 사용하고 있고 이벤트루프 기반으로 비동기방식으로 요청을 처리하기 때문에 고성능이다. 하지만 간결한 알고리즘을 사용하여 이로인한 문제점이 발생한다. 

 

 첫번째로는 네트워크 지연문제이다. Redis는 기본적으로 TCP 기반의 네트워크를 사용하기 때문에 네트워크 I/O에서 병목이 발생할 수 있다. 일 예로 KEYS로 한꺼번에 많은 데이터를 불러올 경우 이 요청을 끝날 때까지 blocking이 걸리고 시스템 전체가 지연되는 문제가 발생할 수 있다. KEYS가 수행되는 동안 다른 요청들은 blocking을 waiting하면서 다른 요청 건들이 지연이 발생하였다. 대량 트래픽 상황에서는 응답지연의 기준을 3초로  정하고 있어서 그 이상 소요 시 실패처리가 발생하기 때문이다. 이를 예방하기 위해 slowlog를 확인하여 롱쿼리가 발생하는 로직의 개선이 필요하다.

 

모든 요청에 대해서는 0.1초 미만으로 처리되도록 모니터링하고 있다.

 

 한편으로 이를 개선하기 위해 scan을 사용한 적이 있었다.  scan이 count기준으로 데이터를 분산요청하였고, count 단위가 작은 경우 Redis까지 요청을 보내고 응답을 받을때까지의 네트워크 I/O가 발생하기도 한다. SCAN의 경우 다른 요청에 대한 blocking을 최소화할 수 있지만 처리하는 프로세스 자체는 지연이 발생하는 문제점이 발생하기도 하였다.

 

ㅁ Redis 모니터링 필요성:  메모리 사용량에 따른 병목현상

 둘째 Redis는 인 메모리 프로스세 이기 때문에 메모리가 쌓일 수록 병목현상이 쉽게 발생하고 그래서 외부장애에 민감하다. 현재 처리하는 프로세스 중 Redis List 데이터 구조를 사용하여 요청을 받고 이를 다음 List에 큐형태로 전달하여 마이크로서비스로 세분화된 모듈에서 처리를 하고 있다. 프로세스 중에 외부연동에 문제가 발생하여 큐가 처리가 되지 않고 적체가되면 적체가 된 만큼 처리지연이 발생하고 그만큼 더 적체가 발생하는 악순환이 발생한다. 

  다른 비유를 들자면, 우리가 쓰는 개인컴퓨터 환경에서  메모리 사용량이 증가하면 가상메모리를 사용하는 단계에서 심각하게 컴퓨터가 늦어지는 병목현상을 경험한다. 이를 해결하기 위해서 특정프로세스를 강제종료하여 적정수준의 메모리를 사용하게 되면 시스템이 정상화 되곤한다. Redis도 메모리 기반의 프로세스이기 때문에 특정큐가 용량이 증가하여 메모리 사용량이 높아질 경우 병목현상이 발생할 확률이 높다. 더욱이 대량트래픽을 처리하기 때문에 조금의 지연은 곧 적체를 불러와 교착상태에 빠지기 때문이다.

 

  지연 지연을 사전에 예방하기 위해서는 Redis의 지연율를 체크하고 있다. 롱쿼리가 발생하거나, Redis의 메모리사용량이 증가하는 경우 지연율 지표를 통해서 그 상황을 파악할 수 있다. 위의 그램에서 두대 동일 스팩의 Redis를 사용하고 있는데, 첫째의 Main의 경우 0.2밀리초 미만인데 반해 Sub의 경우 0.9밀리초 미안으로 나타나고 있다. 차이의 이유는 메모리사용량에 있다. Main은 1GB을 유지하고 있고, Sub의 경우 프로세스처리를 위한 백데이터를 저장하고 있어서 8GB를 차지하고 있다. 메모리 사용량에 따라 처리 performance가 발생하기 때문에 가비지 데이터가 발생하는지 여부와 키별 메모리 사용량을 메일 체크하고 있다.  

 

  실제로 우리 시스템에 연동되어 있는 고객의 시스템에 문제가 발생할 경우 우리쪽에 처리 결과가 지속적으로 증가하게 된다. 이런 증가는 Redis performance에 영향을 주기도 하겠지만, 고객장애에 대한 즉각적인 모니터링이 가능하고 고객에게 시스템 문제점을 역으로 알려드릴 수도 있는 것이다.

 

ㅁ Redis 모니터링의 필요성 정리

 Redis는 인 메모리 방식의  간결한 알고리즘으로 고가용성, 고트래픽에 있어서 꼭 필요하다. 내가 경험만 바에 의해 비유를 들자면, RDS는 안전성과 편의성을 우선 시하는 세단차량과 같다면, Redis는 속도라는 중요한 목표를 위해 간결하고 performace를 지향하는 F1레이스카에 비유할 수 있다. 레이스카는 속도로 인해 큰 사고가  발생할 가능성이 크다. 마찬가지로 Redis도 performance를 지향하고 있어  병목진행 속도도 빨라서 즉각적인 모니터링으로 Redis 병목으로 인한 시스템 전체 장애를 예방하도록 해야한다. 

 

ㅁ 함께 보면 좋은 사이트

https://aws.amazon.com/ko/elasticache/what-is-redis/

 

Redis란 무엇입니까? – Amazon Web Services(AWS)

Redis 개발자는 백 개가 넘는 오픈 소스 클라이언트를 사용할 수 있으며, Java, Python, PHP, C, C++, C#, JavaScript, Node.js, Ruby, R, Go를 비롯한 다수의 언어가 지원됩니다.

aws.amazon.com

반응형
Comments