이 연재글은 Redis 알아보기의 7번째 글입니다.

이번 실습에서는 Redis key 일부를 입력받아 연관된 캐시를 찾아 삭제해주는 프로그램을 작성해 보겠습니다.

개요

현업에서 Redis는 DB 캐시로 사용하는 경우가 많습니다. Redis를 사용하면 DB 부하를 많이 감소시켜주는 효과가 있지만 사용하다보면 실제 데이터를 확인하기 위해 캐시 key를 계속 삭제해야 하는 경우가 종종 발생합니다. 물론 redis-cli로 접속하여 해당 키를 삭제해도 됩니다. 하지만 캐시 key가 다음과 같이 그룹핑된 데이터들일 경우 일괄 삭제해야 하는데 손이 많이들게 됩니다.

  • 회원ID::user_info
  • 회원ID::comment
  • 회원ID::favorite
  • 회원ID::like

위와 같은 경우 각각의 Key를 삭제해야 하면 번거롭습니다. 위에서는 4개만 나열하였지만 프로그램을 만들다보면 한 회원에게서 파생되는 캐시가 수십개 이상 생성될수도 있습니다. 일일히 삭제하면서 개발한다면 그것은 시간낭비가 될 것입니다.

python을 이용하면 shell에서 간단하게 실행할 수 있는 캐시 삭제 프로그램을 만들수 있습니다.

Python으로 redis 삭제 프로그램 만들기

실습에서는 python이 설치된 linux 환경에서 해당 프로그램을 실행하는것을 간주하고 실습을 진행하겠습니다. 대부분 linux서버에 python은 기본으로 설치되어 있고 pip명령을 통해 사용할 package를 설치할 수 있습니다.

redis 패키지 설치

python에서 redis를 쉽게 사용할 수 있도록 도와주는 패키지를 설치합니다.

$ pip install redis

python 코드 작성

아래는 python2.7 환경에서 작성된 코드입니다. 소스자체는 간략하며 주요 로직은 다음과 같습니다.

캐시키 조회시 keys는 redis에 많은 부하를 주어 금기시되는 명령어이므로 사용하지 않습니다. 대신 순차조회가 가능한 scan을 이용하여 key를 부분 검색합니다.

  • scan 명령어(scan_iter)로 캐시를 처음부터 순회하면서 삭제할 key를 10개씩 찾는다.
  • 찾은 key를 모아서 일괄 삭제한다.
  • scan 결과가 10개가 안될경우 keys.next()에서 에러가 발생하여 loop가 종료되는데 잔여 캐시는 loop 종료후에 삭제 처리한다.
$ vi clearCache.py
#!/usr/bin/python
import redis
import sys
from collections import OrderedDict

# 각 환경에 따른 REDIS 서버 주소
servers = OrderedDict()
servers['dev'] = 'REDIS DEV 서버 주소'
servers['qa'] = 'REDIS QA 서버 주소'
servers['production'] = 'REDIS 실서버 주소'

# 연결할 REDIS 서버 선택
keys = servers.keys()
for idx, key in enumerate(keys):
    print("{} - {}".format(idx, key))
choiceServer = raw_input('select server :')
if choiceServer == '':
   exit()

# REDIS 서버 접속
conn = redis.Redis(
    host=servers.get(keys[eval(choiceServer)]), port=6379, db=0)

# 삭제할 캐시 key입력(전체 or 일부만 입력)
delKey = raw_input('Enter part of the key to delete({}) :'.format(keys[eval(choiceServer)]))
if delKey == '':
   exit()
# SCAN 명령어로 순회하며 삭제할 키를 10개씩 조회
keys = conn.scan_iter(match='*'+delKey+'*', count=10)
delKeys = []
while True:
    try: # 10개 모아진 key를 삭제한다. 10개가 안될경우 keys.next()시 에러가 발생하여 loop가 종료된다.
        while len(delKeys) < 10:
            key = keys.next()
            delKeys.append(key)
            print('Deleted... {}'.format(key))

        conn.delete(*delKeys)
        delKeys = []
    except StopIteration:
        break
# loop 종료후 잔여 key를 삭제한다.
if len(delKeys) > 0:
    conn.delete(*delKeys)

실행권한 부여 및 실행

shell에서 실행할 수 있도록 다음과 같이 실행권한을 추가하고 실행합니다.

$ sudo chmod +x ./clearCache.py
$ ./clearCache.py
0 - dev
1 - qa
2 - production
select server :0
Enter part of the key to delete(dev) : happydaddy@gmail.com
Deleted... happydaddy@gmail.com::user_info
Deleted... happydaddy@gmail.com::comment
Deleted... happydaddy@gmail.com::favorite
Deleted... happydaddy@gmail.com::like

아래와 같이 심볼릭 링크(윈도우로 치면 바로가기)를 만들어두면 shell 어디에서나 실행 가능하고 “./”도 생략 가능합니다.
ln -s [원본파일Path] [대상파일Path]

$ ln -s /home/ec2-user/clearCache.py /usr/bin/clearCache
$ clearCache
0 - dev
1 - qa
2 - production
// 이하 생략

실습을 통해 redis 캐시삭제를 도와주는 프로그램을 작성해 보았습니다. 별거 아닌 프로그램이지만 단순 반복작업을 없애준다는 것에서 본다면 의미있는 프로그램이라고 생각합니다.

연재글 이동[이전글] Redis – Reactive redis