728x90
반응형
Redis 장애 원인
- redis 는 메인 스레드가 대부분의 처리를 하는 싱글 스레드 형태이기에 하나의 명령에서 시간이 많이 걸리면 전체 성능 저하가 일어난다.
- 실제로 더 빠른 CPU, 더 많은 메모리를 사용할 수록 성능이 좋아지지만, Scale Up 을 하더라도 잘못된 사용 패턴은 장애를 일으킬 수 있다.
Redis 장애 종류
- 메모리
- 메모리 과다 사용 (maxmemory 설정)
- 캐시로만 사용시 all key, LRU 사용.
- RSS 관리
- 실제 물리 메모리보다 더 많은 메모리를 사용하지 않도록 계속 모니터링 해야
- 메모리 관련 장애는 redis 메모리 관리를 잘 하는 방법 밖에 없다.
- scale up
- 비용이 발생하지만 가장 좋은 방법이다.
- Redis 는 항상 fork의 위험성이 있으므로 메모리가 충분한 게 좋다.
- 혹은 key 삭제로 메모리를 확보 해야 한다.
- 효율성이 떨어지는 key 를 지운다.
- Redis는 캐별 key의 hit, miss를 제공하지 않으므로 개별적으로 관리해야 한다.
- 실제 캐시되는 키가 줄어드므로, DB 부하가 늘어날 수 있다.
- scale up
- 메모리 이슈 발생 시
- Redis 속도 저하 (swap 등의 이슈)
- OOM이슈로 처리가 되지 않고 명령이 실패한다.
- 메모리 관련 이슈
- Copy on Write 이슈
- redis가 fork 할 때 메모리 사용량이 최대 2배까지 늘어날 수 있다.
- redis는 Relica 가 연결되는 순간 데이터 이전을 위한 RDB를 만들면서 fork
- AOP Rewrite 를 하기 위한 경우 fork
- RDB 생성을 하기 위한 경우 fork
- 이와 같은 이슈 때문에 한 대의 redis 서버의 메모리 사용량을 물리 메모리의 절반 이하로 유지하는 것이 좋다.
- redis가 fork 할 때 메모리 사용량이 최대 2배까지 늘어날 수 있다.
- Copy on Write 이슈
- 메모리 과다 사용 (maxmemory 설정)
- 설정
- 기본 설정 사용
- 기본 설정 사용시 SAVE 설정은 많은 변경이 되면 디스크에 메모리를 덤프하게 된다. 결국 IO를 과다하게 사용해 장애가 발생한다.
- redis 기본 설정 사용으로 인한 과도한 IO 로 인한 성능 저하
- Redis 가 bgsave 동작이 fork로 인해서 메모리 사용량도 늘어날수 있다.
- redis 기본 설정 관련 장애 확인 방법으로는
- 서버 레벨에서의 확인
- disk 사용량을 확인한다. bgsave 옵션으로 인해 write가 많아지므로 write 가 많아지는지 확인한다.
- redis 레벨에서의 확인
- SAVE 관련 설정으로 확인한다. ( 서비스를 위해 해당 설정은 끄는 것이 좋다.
- 명령어: config get save 입력해 "save" 가 "3600 1 300 60 10000" 가 나온다면 기본 설정 사용중. 그냥 "save" 만 나오면 문제 없다.
- 실행 중이라면 redis.conf에 SAVE "" 를 넣고 다른 SAVE 설정은 지워준다.
- SAVE 관련 설정으로 확인한다. ( 서비스를 위해 해당 설정은 끄는 것이 좋다.
- 서버 레벨에서의 확인
- 기본 설정 사용
- 싱글 스레드
- 과도한 Value의 크기
- redis는 싱글 스레드 이기에 하나의 명령이 긴 시간을 차지하면 결국 redis 성능 저하로 이어진다.
- redis의 sorted set, hash set 등의 자료 구조는 내부적으로 다시 hash table등을 구성해 관리한다.
- O(N)명령의 사용
- Keys, flushdb/flushall 큰 크기의 collection을 지우는 등의 문제는 redis의 성능을 떨어트린다.
- keys는 scan으로 변경 가능. flushdb, flushall 은 lazy 설정을 해 백그라운드에서 삭제하게 한다.
- Keys, flushdb/flushall 큰 크기의 collection을 지우는 등의 문제는 redis의 성능을 떨어트린다.
- 싱글 스레드 관련 장애 확인
- 사용하면 안되는 명령을 사용중인지 확인. KEYS 명령의 사용 횟수가 늘어나면 해당 명령이 문제를 일으킬 수 있다
- O(N) 계열 커맨드의 사용이 늘어나는지 확인한다.
- hgetall, hvals, smembers, zrange 계열 함수
- Monitor 명령을통해 들어오는 Key의 빈도를 체크한다.
- Monitor 명령은 해당 서버에 부하를 추가로 주게 되므로 사용하면서 서버 부하가 더 커지는지 확인한다
- Scan 명령을 통해 각 Key 의 사이즈를 확인해 특정 크기 이상의 key를 확인한다.
- info all 에서 commands stats를확인한다.
- usec_per_call 이 micro seconds 이므로 주요 호출 명령에서 해당 값이 크면 확인이 필요하다.
- key 명령 대신 scan명령으로 바꾼다.
- 실제 O(N)을 사용한 장애 사례
- spring security OAuth 는 2018년 6월까지 RedisTemplateStore를 통해 oauth access token을 관리할 경우 token개수가 많아지면 전체 인증 로직이 느려지는 버그가 존재.
- 버그의 이유
- O(N)자료 구조인 list 자료구조를 사용했다.
- 백만개의 토큰 중에서 하나의 토큰을 찾아야 하는 경우가 반복적으로 발생.
- 실제로 국내외 많은 서비스에서 해당 이슈로 인한 장애가 발생
- 해결 방법
- O(N) 명령인 list 자료구조를 O(1)을 사용하는 Set자료주고를 사용하도록 변경
- 과도한 Value의 크기
Redis 보안 관련
- 절대로 Redis의 포트를 public 에 공개하면 안된다.
- 해당 이슈로 전체 시스템의 보안 위협이 높아지는 경우가 많다.
728x90