[Redis] 디버깅 시 MONITOR 명령을 조심하세요
안녕하세요.
여러분은 Redis를 자주 사용하시나요? 아마 대부분 사용해 보셨거나 사용 예정이실 겁니다. 😏
Redis는 굉장히 빠르며 가장 인기있는 키-값 데이터베이스입니다.
이번에는 Redis의 MONITOR 명령을 조심해서 사용해야 하는 이유에 대해 소개하겠습니다.
요약
- Redis의 MONITOR 명령으로 쿼리 패턴과 빈도를 분석할 수 있다.
- MONITOR 명령을 사용하면 50% 이상의 성능 감소가 발생할 수 있다.
- 꼭 필요하다면 최소한의 시간만큼 사용하거나, 비-운영 환경에서 재현하거나, 외부 로깅 도구를 사용한다.
이 글에서 얻을 수 있는 것
- Redis MONITOR 명령이 무엇이고 어떻게 사용하는지 알 수 있다.
- MONITOR 명령 사용 시 성능이 느려지는 것을 확인하고 느려지는 원인을 알 수 있다.
- MONITOR 명령의 대안을 알 수 있다.
MONITOR 명령이 필요한 상황
Redis에 수행되는 명령어들을 모니터링하고 싶을 때 MONITOR 명령어를 사용합니다.
$ redis-cli monitor
1339518083.107412 [0 127.0.0.1:60866] "keys" "*"
1339518087.877697 [0 127.0.0.1:60866] "dbsize"
1339518090.420270 [0 127.0.0.1:60866] "set" "x" "6"
1339518096.506257 [0 127.0.0.1:60866] "get" "x"
1339518099.363765 [0 127.0.0.1:60866] "eval" "return redis.call('set','x','7')" "0"
1339518100.363799 [0 lua] "set" "x" "7"
1339518100.544926 [0 127.0.0.1:60866] "del" "x"
위는 MONITOR 명령 수행 예시입니다.
모니터링 세션이 열리고, 연결된 Redis에 입력되는 모든 명령을 스트리밍 해서 출력합니다.
언제 사용하면 좋을까요?
테스트와 디버깅
로컬 혹은 개발 환경에서 테스트할 때 유용합니다. 예를 들어, Spring Data Redis를 사용해서 Redis와 연결하고 명령을 보냈는데 실제로 명령이 잘 들어갔는지 확인할 때 사용할 수 있습니다. 문제가 발생해서 디버깅을 해야 할 때도 유용하게 사용할 수 있습니다.
명령 패턴과 빈도 분석
명령 패턴과 빈도를 분석할 수 있습니다. 중복된 명령을 찾아내거나 데이터 흐름을 파악하거나 캐싱 전략에서 개선할 수 있는 점을 찾아서 궁극적으로 성능 개선을 할 수 있습니다.
MONITOR 명령이 위험한 이유
MONITOR로 세션이 연결되어 있는 동안, Redis 서버는 심각하게 느려질 수 있습니다.
그 이유가 무엇일까요?
데이터가 너무 많다
『승정원일기』는 승정원(承政院)에서 처리하는 모든 일을 일기체 형식으로 기록한 문헌이다. 승정원은 왕명(王命) 출납(出納)을 맡았던 관청이었고, 그에 따라 『승정원일기』에는 국정 전반이 기록되어 있다. 총 3,243책으로, 글자 수가 2억 4,300만 자에 달한다.
조선 왕의 일거수일투족을 기록한 승정원일기는 실로 그 양이 방대합니다. MONITOR 명령도 마찬가지입니다. Redis의 일거수일투족을 담아서 모니터 클라이언트에게 보내야 합니다. 엄청난 데이터를 생산하게 되고, 이로 인해 서버의 작업 부하가 크게 증가합니다.
CPU가 할 일이 많다
Redis의 모든 명령을 로깅하고 모니터 클라이언트로 스트리밍 하려면 CPU가 온전히 명령어 처리나 데이터 관리에 힘을 쏟지 못합니다. 마치 요리사가 요리를 하면서 요리 과정을 주변 사람들에게 설명하는 것과 똑같습니다.
네트워크 대역폭을 많이 차지한다
MONITOR 출력은 Redis에서 처리되는 모든 명령의 세부 정보가 포함되어 있습니다. 따라서 매우 장황한데, 이 데이터를 네트워크를 통해 모니터 클라이언트에게 전달하면 네트워크 대역폭의 상당수를 차지하게 되어 네트워크 병목이 발생할 수 있습니다.
다른 명령어가 블록킹 된다
Redis의 가장 큰 특징이 싱글 스레드로 매우 빠르게 동작한다는 점입니다. 싱글 스레드이기 때문에 명령이 순차적으로 하나씩 수행되는데, 그 사이에 MONITOR 명령도 계속 수행되어야 하니, 필요한 명령이 느려지는 것은 당연합니다.
MONITOR 명령이 처리율을 낮추는 시나리오
(저는 Docker 환경에서 Redis를 실행하고 있지만, 명령은 동일합니다.)
실제로 MONITOR 명령을 사용 중일 때 다른 명령어에 영향을 미치는지 확인해 봅시다.
우선 redis-benchmark를 사용해서 다양한 명령어를 10,000번 수행해 봤습니다.
redis-benchmark -q -n 10000
RPS를 살펴보면,
- SET은 28만
- GET은 32만
- HSET은 32만 - 정도 나오는 것을 확인할 수 있습니다.
그리고 MONITOR 명령을 실행했습니다.
$ redis-cli monitor
그리고 다시 벤치마크를 해봤더니,
- SET은 28만 ➡️ 25만
- GET은 32만 ➡️ 22만
- HSET은 32만 ➡️ 18만으로 - 처리율이 눈에 띄게 낮아진 것을 확인할 수 있었습니다.
(공식문서에서는 50% 이상 감소될 수 있다고 합니다.)
결론
모니터링 혹은 디버깅을 위해 오픈소스인 redis-stat을 사용하거나 Datadog을 사용하고 있다면 대시보드를 열어보는 것도 좋습니다. MONITOR 명령은 성능이 확 느려져서 장애로 이어질 수 있으니 비-운영 환경에서만 사용하도록 합시다!
References
- https://redis.io/commands/monitor/
- https://velog.io/@sossont/Redis
- http://contents.history.go.kr/mobile/kc/view.do?levelId=kc_r300705&code=kc_age_30