[PYTHON] Python에서 Redis를 사용 + 인메모리 캐시(Ubuntu 18.04)
이번 포스팅은 파이썬에서 redis를 사용하여
인메모리 캐시 로직을 간단하게 구현하는 것에 대한
포스팅입니다.
Redis란,
NoSQL(Not Only SQL, 비관계형 데이터베이스)의 한 종류로써 키-값 기반의 인-메모리 저장소이다.
또한 레디스는 메모리 기반으로, 모든 데이터를 메모리에 저장한다. 따라서 빠른 속도를 보장한다.
지원하는 데이터 타입으로 Hash, Set, Sorted Set, String, List를 지원한다.
지원하는 데이터 타입
> String : key-value mapping (단일 키)
- 이번 포스팅에서는 String 타입에 대한 레디스 사용법만 포스팅 예정
> Sets : 순서가 없으며, 중복이 없는 String data (중복된 데이터를 넣으면 하나만 저장된다)
> Sorted Sets: Set과 동일하나, 순서를 정할 수 있음 (Score로 정렬)
> Hashes : key-value의 구조를 가진 객체 타입
> List : Array 형식 (앞, 뒤의 데이터 삽입은 빠르나 중간 데이터 삽입은 느림)
레디스의 특징
> Single thread로써 한 번에 하나의 명령어만 실행
> 데이터가 유실되지 않는다.
> 서버 측 복제와 클라이언트 측 샤딩을 지원함
> Collection을 지원 함 (맴캐쉬는 지원하지 않는다)
레디스를 사용하는 경우
> 여러 서버에서 데이터를 공유할 떄
> 인증 토큰 저장 용(String : key-value)
> Ranking 서버 (Sorted Set)
> 캐싱용도
> 좌표 저장
사용목적
광고 배너 생성 요청시, RDBMS의 요청 부하를 줄이기 위해 인메모리 캐시 용도로 사용하기 위해 Redis 적용
배너 생성 요청 시,
> 해당 키 값에 대한 값이 레디스에 존재하는 지 확인. 없으면 광고 배너 생성을 위한 로직 진행 후 레디스에 결과 저장.
> 해당 키 값에 대한 값이 레디스에 존재할 경우, 저장 된 값을 가지고 배너 생성
Redis 설치 및 설정 (Ubuntu 18.04)
레디스 설치 전
$ sudo apt-get update
$ sudo apt-get upgrade
redis-server 설치
$ sudo apt-get install redis-server
레디스 설치 확인
$ redis-server --version
- 버전을 확인 하면, 아래와 같이 레디스의 버전을 확인 할 수 있다.
현재 서버의 총 메모리 확인
$ vmstat -s
- 아래 이미지를 확인해보면 총 메모리는 15G 정도 되는 것을 확인 할 수 있다
$ htop
- 위와 같은 방법으로도 확인이 가능하다.
- 아래 화면이 보이는 때, 이때 Mem 부분을 확인하면 현재 사용중인 메모리와 전체 메모리를 확인 할 수 있다.
레디스 메모리 설정
$ vi /etc/redis/redis.conf
[ maxmemory ]
- 레디스가 사용할수 있는 최대 메모리를 정의
- maxmemory 4g
- 개별적으로 서버 사양에 맞게 maxmemory를 정의
[ maxmemory-policy ]
- 최대 사용량 초과 시, 데이터 처리 방식 정의
- default는 noeviction이다
- 공식 문서에 따르면 아래와 같은 선택지들이 존재함
[ redis.conf ]
maxmemory 4g
maxmemory-policy noeviction
레디스 재시작 및 상태 확인
# 재시작
$ sudo systemctl restart redis-server.service
# 상태 확인
$ sudo systemctl status redis-server.service
- 설정 파일 변경 후, 반영을 위해 redis-server를 재시작 한 뒤 정상 작동하는 지 확인 한다.
python에서 Redis사용
pip로 레디스 설치
$ pip install redis
- pip를 사용하여 파이썬에서 레디스를 사용할 수 있도록 패키지 설치
- 아래는 파이썬 공식 레디스 패키지 링크
포트오픈 확인
$ netstat -nlpt | grep 6379
- 위 명령어를 사용하여 redis가 사용하는 6379 포트가 열려있는 지 확인 한다.
- 127.0.0.1:6379 로 열려있는 걸로 보아, 내부에서만 접속 가능하도록 설정이 되어있다.
레디스 연결
import redis
# 레디스 연결
rd = redis.StrictRedis(host='localhost', port=6379, db=0)
- 로컬에 레디스를 설치 했다면 host = 'localhost'로 설정, 다른 서버에 설치 한 경우는 해당 IP를 작성
- 레디스 default port = 6379
데이터 set
- 레디스에서는 데이터를 저장할 때 set 을 사용
import redis
# 레디스 연결
rd = redis.StrictRedis(host='localhost', port=6379, db=0)
# 레디스에 키-값 저장
rd.set("[키]", "[값]")
데이터 get
- 레디스에서는 데이터를 가져올 때 get 을 사용
import redis
# 레디스 연결
rd = redis.StrictRedis(host='localhost', port=6379, db=0)
# 레디스에서 키를 사용해서 값 가져오기
rd.get("[키]")
데이터 delete
- 레디스에서는 데이터를 삭제할 때 delete 을 사용
import redis
# 레디스 연결
rd = redis.StrictRedis(host='localhost', port=6379, db=0)
# 레디스에서 키를 사용해서 값 가져오기
rd.delete("[키]")
데이터 flushdb
- 레디스에서는 DB의 데이터를 전체 삭제 할 때 flushdb 을 사용
import redis
# 레디스 연결
rd = redis.StrictRedis(host='localhost', port=6379, db=0)
# 레디스 DB 데이터 전체 삭제
rd.flushdb()
Trouble Shooting
인코딩 / 디코딩 문제 (dict타입)
- Redis에 ASCII 문자열이 아닌 UTF-8 타입의 문자열을 저장하고 조회하면, decoding이 되지 않는 문제 발생
- 따라서 json의 dumps(), loads()를 사용해서, 데이터를 저장하고 읽어야한다.
> 레디스 연결
import json
import redis
# 레디스 연결
rd = redis.StrictRedis(host='localhost', port=6379, db=0)
> 데이터 선언
# dict 데이터 선언
dataDict = {
"key1": "테스트값1",
"key2": "테스트값2",
"key3": "테스트값3"
}
> json dumps & redis set
# json dumps
jsonDataDict = json.dumps(dataDict, ensure_ascii=False).encode('utf-8')
# 데이터 set
rd.set("dict", jsonDataDict)
> json loads & redis get
# 데이터 get
resultData = rd.get("dict")
resultData = resultData.decode('utf-8')
# json loads
result = dict(json.loads(resultData))
redis-cli 에서 사용
redis-cli 접속
# 레디스가 설치된 서버에서 아래와 같이 명령어 입력
$ redis-cli
- 위 명령어 입력하면, redis-server로 접속해서 직접 데이터를 조회/삭제/추가 등을 할 수 있다.
- 아래 이미지와 같이 입력 창이 생성된다.
레디스 설정 정보
# redis-cli 접속 된 상태
127.0.0.1:6379> info
데이터 set
[ set ]
# redis-cli 접속 된 상태
127.0.0.1:6379> set [key] [value]
- "set 키 값" 명령을 통해 쉽게 데이터를 redis에 넣을 수 있다.
[ mset ]
# redis-cli 접속 된 상태
127.0.0.1:6379> mset [key] [value] [key2] [value2] [key3] [value3] ...
- mset을 활용하면 여러개의 키와 값을 저장 할 수 있다.
데이터 get
[ get ]
# redis-cli 접속 된 상태
127.0.0.1:6379> get [키]
- "get 키" 명령을 통해 해당 키에 대한 값을 가져 올 수 있다.
[ mget ]
# redis-cli 접속 된 상태
127.0.0.1:6379> mget [key] [value] [key2] [value2] [key3] [value3] ...
- mget을 활용하면 여러개의 키와 값을 가져올 수 있다.
데이터 삭제
# redis-cli 접속 된 상태
127.0.0.1:6379> del [키]
- 특정 키와 값을 지울 떄 사용하는 명령어
카운터 생성
# redis-cli 접속 된 상태
# 레디스에 해당 키에 대한 값을 저장
127.0.0.1:6379> SET [KEY] [VALUE:INT]
# 특정 키의 값을 가져온다
127.0.0.1:6379> GET [KEY]
# incr을 사용하여 값에 +1 을 한다
127.0.0.1:6379> INCR [key]
# 값이 잘 변경되었는지 확인
127.0.0.1:6379> GET [key]
- 카운터의 역할로써, 특정 키에 대해 위의 요청을 수행하면 누적으로 +1 이 된다.
저장된 키 확인
[모든 키]
# redis-cli 접속 된 상태
127.0.0.1:6379> keys *
- 저장 된 모든 키를 가져오고 싶을 떄
[특정 문자를 가진 키]
# redis-cli 접속 된 상태
127.0.0.1:6379> keys [특정문자]*
- 특정 문자를 포함하는 키값을 가져오고 싶을 때는 위와 같이 한다.