지나공 : 지식을 나누는 공간

Redis 점검 : 전체 Key TTL 추출하기 / shell operator 활용 본문

지식 간단 정리!

Redis 점검 : 전체 Key TTL 추출하기 / shell operator 활용

해리리_ 2023. 3. 24. 12:05

최근 우리 팀 서비스 중 이미지가 업데이트되지 않는 문제가 있었다. Redis에 올라간 데이터인데 TTL 이 없어서 그동안 업데이트가 되지 않은 게 원인이었다. TTL 이 없다고? 라는 충격과 함께 이번 기회에 우리팀 Redis가 어떻게 쓰이고 있는지 현황을 파악하는 시간을 가졌다.

 

1. key 추출

2. TTL 추출을 어떻게 할지에 대한 고민 : 결국 노가다 살짝ㅠㅠ

3. 히트율 계산

4. 결론. redis를 캐시의 관점에서 사용하자. 

5. 파생 가능한 주제 : 로컬 캐시와 글로벌 캐시 활용, 적절한 TTL이 뭘까?

 

 

1. key 추출


일단 전체 key를 추출해야했다. 약 180만개 정도 있어서... 이게 과연 될까 싶었지만 추출되긴 했다.

redis-cli --raw -p [포트번호] -h [레디스서버주소(회사거라 가림ㅠㅠ)] keys '*' > redis-all-key.txt
  • redis-cli : redis command line을 의미. 
  • --raw : raw 데이터 출력을 위해 넣은 옵션이다. 회사 상용환경에서는 인코딩이 안 맞아서 한글이 깨질 때가 많다. 한글 깨짐 없이 실제 저장했던 데이터를 raw하게 보려면 이 옵션이 필요하다.
  • keys '*'는 패턴을 찾는 redis 명령어다. keys '*hello*' 또는 keys 'hello*' 이런 식으로 문자열을 탐색할 수 있다.
  • overwirte(>) 와 append (>>)
    • > : 파일에 덮어쓰기
    • >> : 없으면 새로 만들고, 있는 파일이면 거기에 더하기
  • 난 txt로 뽑았으나, csv 확장자를 사용하면 엑셀로 추출할 수도 있다. 
    • 우리 키는 180만 개인데 엑셀 2016 버전의 최대 row 수가 10만 건이어서 txt로 바꿔서 추출하게 됐다.
    • 한 줄에 여러 키를 넣어서 csv로 가져와도 되지만 한 줄에 한 키를 넣어야 나중에 DB 테이블에 import하기 편해서 그냥 txt로 했다.

 

다음으로는 txt로 추출한 이 key들을 분석하기 편하게 DB 테이블로 옮겼다. 대부분의 Database IDE들이 txt나 csv 파일을 테이블로 import하는 기능을 제공할텐데 나는 DataGrip을 쓰고 있어서 이걸로 했다.

 

key를 담을 테이블을 하나 만들고 txt 파일을 포맷 설정해서 import하면 끝임! 

 

 

2. TTL 추출을 어떻게 할지에 대한 고민 : 결국 노가다 살짝ㅠㅠ


redis key가 적다면 shell 문법을 활용해서 txt 파일로 key 별 TTL을 추출할 수 있다.

# 전체 key에 대해 key 별 TTL을 추출
redis-cli --raw -p 포트번호 -h 서버주소 keys  "*" | 
while read LINE ; do 
	TTL=`redis-cli --raw -p 6379 -h apptour-redis-v2.qxuodi.ng.0001.apn2.cache.amazonaws.com ttl "$LINE"`; 
 	echo -e "$LINE $TTL\n" >> redis_all_key_with_ttl.txt
done; 



# 전체 key에 대해 TTL 이 없는 것만 추출
redis-cli --raw -p 포트번호 -h 서버주소 keys  "*" | 
while read LINE ; do 
	TTL=`redis-cli --raw -p 6379 -h apptour-redis-v2.qxuodi.ng.0001.apn2.cache.amazonaws.com ttl "$LINE"`; 
	if [ "$TTL" -eq -1 ]; then 
 		echo -e "$LINE $TTL" >> redis_key_without_ttl.txt
 	fi
done;
  • (|) 버티컬바 : 왼쪽의 결과물을 오른쪽의 입력값으로 넘긴다. 즉 LINE이라는 변수로 keys의 항목을 하나씩 받고 있다.
  • 변수 사용 : TTL이라는 변수에 ttl 명령어의 결과값을 담음.
  • echo : shell에서 출력하는 명령어인데 이 출력값을 바로 txt 파일에 append(뒷줄에 추가)하고 있다.
  • if문 : shell 에서 if 문 쓰는 방법으로 작성했다. -eq는 == 와 같은 의미다.
  • ttl : redis ttl 명령어는 해당 키의 ttl을 알아보는 명령언데 -1이면 ttl 이 없는 거고, -2 이면 key가 없는 것이다.

 

위와 같이 바로 진행되면 좋은데 아무래도 키 수가 워낙 많다보니 이번 케이스에서 활용할 순 없었다. 패턴을 구분해서 담든가,, 뭔가 너무 많다 보니 패턴을 구분해야만 했다. 또다시 고민고민에 빠짐.

 

redis key를 저장하는 코드를 보면 set('특정패턴_구체적인번호', expire_time 설정) 뭐 이런식으로 되어 있었다. 그래서 key별로 특정 패턴을 잡고 이 패턴이 몇개 종류가 있는지, 각 패턴 별로 동일한 expire_time으로 설정되었을테니 이에 대한 확인도 필요했다.

 

일단 DB에 옮겨놨으니 눈으로 당장 봤을 때 딱 봐도 많아보이는 한 두개 정도의 패턴을 뽑았고 query로 문자열 비교를 통해 개수를 확인했다. 그랬더니 180만개 중에 130만개가 한 로직에서 발생한 동일한 패턴의 키였다. 얘 하나만 빠져도 나머지는 위 쉘스크립트로 커버 치겠다 싶어서 몇가지 패턴 이어서 뽑고 count를 작성했다. 이 작업이 약간 노가다이긴 한데 한 패턴에 해당되는 키가 몇만개씩 되다보니 정작 패턴 뽑아보면 종류는 한 4-50개? 밖에 없었다.

 

최대 수를 차지하고 있는 키를 발견했는데 걔는 TTL이 없었다... 오마이갓ㅎ. 게다가 히스토리 인수인계 과정에서 놓쳐진 건지, 팀원들 다같이 잘 모르는 repository에서 setting하는 key 였다. 과정 중에 약간의 노가다가 있긴 했지만 그래도 개선이 필요한 redis key가 존재한다는 사실을 알았으니 현황 파악의 의의는 있는 거 같다. 이제 어떻게 개선할지에 대한 고민을 차차 하기로 했다.

 

3. 히트율 계산


현황 파악하는 김에 key만 보지 말고 전반적으로 어떻게 쓰이고 있는지도 보고 싶어졌다. redis-cli에서 info 라는 명령어를 제공한다.

회사 코드라 여기 넣을 순 없지만 hit율을 알고 싶다면 #Stats에 나오는 keyspace_hits, keyspace_misses를 보면 된다.

 

히트율 = (hits) / (hits + misses)

 

인데 1 만점을 기준으로 0.95 - 0.99 면 괜찮은 히트율이라고 한다. 우리 건 0.95였다.

 

4. 결론. redis를 캐시의 관점에서 사용하자. 


가장 큰 포인트는 DB에 있는 데이터를 빠르게 가져오기 위한 용도로 redis를 써야 한다는 것이었다. 

 

그동안 우리 팀에서 있던 문제를 떠올려보면, 이렇게 redis에 ttl이 없어서 업데이트 되지 않은 일도 있었지만, 어떤 때는 업데이트하는 배치가 너무 늦게 돌아서 그 사이 ttl 이 만료됐는데 redis에만 있는 데이터였던 탓에 상용 환경에서 데이터가 안 보인 적도 있었다. redis에 있는 데이터들은 DB에 다 있고, redis 키가 만료되면 DB에서 언제든 꺼내올 수 있어야 하는 게 기본 관점인데 이게 잘 지켜지지 않아서 생긴 문제다. redis에서만 보관하는 몇몇 데이터들이 있어서 이건 개선을 해야 할 거 같다.

 

또한, redis의 key를 모든 로직마다 최적화된 expire time을 갖는 것도 다시 검토해 보라는 조언을 받았다. 특정 로직마다 최적의 ttl을 가지는 것은 좋으나 유지 보수의 편의성도 고려해야 한다. 워낙 key가 많으니 데이터 유형 별로 key 이름과 expire을 규칙적으로 가져가는 것도 좋은 거 같다. 일부 중요한 것들은 최적화해야겠지만! 

 

+ redis key 정책 간소화는 바로 진행했다.

 

5. 파생 가능한 주제 : 로컬 캐시와 글로벌 캐시 활용, 적절한 TTL이 뭘까?


최적화된 TTL이라는 게 뭘까.. 그 판단 기준이 알고 싶다. 정답이 없는 문제이긴 하지만, 다른 회사 다른 팀들은 어떻게 관리하고 있을지 궁금하다. 로컬캐시와 글로벌 캐시에 대해서도 파생해서 다음에 알아봐야겠다.

728x90

'지식 간단 정리!' 카테고리의 다른 글

DB Index (RDBMS)  (4) 2024.03.01
RestTemplate, FeignClient / WebClient 차이, 소개  (4) 2023.02.12
Comments