3. Redis for Python
1. Redis for Python
1) redis
설치
$(base) pip install redis
2) 포트 오픈 확인
- 다음과 같이
6379
번 포트가 열려있는지 확인한다.
$(base) netstat -nlpt | grep 6379
tcp 0 0 127.0.0.1:6379 0.0.0.0:* LISTEN 150/redis-server 12
3) Redis 연결
- 파이썬 스크립트에서 다음과 같이 Redis를 연결한다.
import redis
# 레디스 연결
rd = redis.StrictRedis(host="localhost", port=6379, db=0)
- 로컬에 Redis를 설치했다면
host="localhost"
로 지정하고, 다른 서버에 Redis를 설치했다면 해당 서버의 IP로 지정하면 된다.
- 포트 번호는 기본적으로
6379
번이기 때문에 똑같이 지정한다.
4) 데이터 저장하기
- Redis에서는 데이터를 저장할 때
set()
을 사용한다.
import redis
# 레디스 연결
rd = redis.StrictRedis(host="localhost", port=6379, db=0)
# 레디스에 키-값 저장
rd.set("[키]", "[값]")
5) 데이터 가져오기
- Redis에서는 데이터를 가져올 때
get()
을 사용한다.
import redis
# 레디스 연결
rd = redis.StrictRedis(host="localhost", port=6379, db=0)
# 레디스에 키를 사용해서 값 가져오기
rd.get("[키]")
6) 데이터 삭제하기
- Redis에서는 데이터를 삭제할 때
delete()
를 사용한다.
import redis
# 레디스 연결
rd = redis.StrictRedis(host="localhost", port=6379, db=0)
# 레디스에서 키를 사용해서 데이터 삭제하기
rd.delete("[키]")
7) 데이터 전체 삭제하기
- Redis에서는 DB의 데이터를 전체 삭제할 때
flushdb()
를 사용한다.
import redis
# 레디스 연결
rd = redis.StrictRedis(host="localhost", port=6379, db=0)
# 레디스 DB 데이터 전체 삭제하기
rd.flushdb()
8) dict
타입 인코딩 / 디코딩 문제
- Redis에 ASCII 형식의 문자열이 아닌 UTF-8 형식의 문자열을 저장하고 조회하면, 디코딩이 되지 않는 문제가 발생한다.
- 따라서 json의
dumps()
, loads()
를 사용해서 데이터를 저장하고 읽어야 한다.
import json
import redis
# 레디스 연결
rd = redis.StrictRedis(host="localhost", port=6379, db=0)
# dict 데이터 선언
data_dict = {
"key1": "value1",
"key2": "value2",
"key3": "value3",
}
# json dumps
json_data_dict = json.dumps(data_dict, ensure_ascii=False).encode("utf-8")
# 데이터 set
rd.set("dict", json_data_dict)
# 데이터 get
result_data = rd.get("dict").decode("utf-8")
# json loads
result = dict(json.loads(result_data))
9) 전체 데이터 가져오기
keys()
와 mget()
메서드로 전체 데이터를 가져온다.
import json
import redis
# 레디스 연결
rd = redis.StrictRedis(host="localhost", port=6379, db=0)
# 전체 키 가져오기
keys = rd.keys()
keys = [key.decode("utf-8") for key in keys]
# 전체 값 가져오기
vals = rd.mget(keys)
vals = [val.decode("utf-8") for val in vals]
# 키-값 형식으로 만들기
kv = dict(zip(keys, vals))
9) 카운터
- 특정 키가 저장될 때 횟수를 올려주는 카운터를 다음과 같이 작성한다.
- 사용하지 않아도 된다.
class RedisCounter:
"""레디스를 이용한 카운터"""
def __init__(self, conn_redis, key, is_counter_reset=True, init_num=0):
"""
:param conn_redis:Redis<ConnectionPool<Connection>>: 레디스연결객체
:param key:str: 카운터를 저장할 Redis Key
:param is_counter_reset:bool: 카운터를 초기화하고 시작할지 여부
:param init_num:int: 카운터 초기화할 숫자
"""
self.conn_redis = conn_redis
self.key = key
if isinstance(init_num, int) is False:
raise Exception("init_num must be integer data type")
self.init_num = init_num
if is_counter_reset is True:
self.conn_redis.set(name=self.key, value=init_num)
def plus(self, int_plus_num=1, is_error_reset=True):
"""
카운터에 정수형 숫자(기본:1)를 더한 숫자를 리턴한다
:param int_plus_num:int: 정수형 숫자
:param is_error_reset:bool: 오류발생시 카운터를 초기값으로 리셋여부
:return counter_number:int: 더해진 최종 카운터 값
"""
if isinstance(int_plus_num, int) is False:
raise Exception("int_plus_num must be integer data type")
try:
# INCR COMMAND: Time complexity: O(1)
return int(self.conn_redis.incr(name=self.key, amount=int_plus_num))
except redis.ResponseError: # 값이 숫자가 아니거나 64비트 부호정수형 범위를 넘어간 경우
if is_error_reset is True:
self.conn_redis.set(name=self.key, value=self.init_num) # 초기값으로 설정한다
return self.init_num # 초기값을 반환한다
else:
pass
def get(self):
""" :return counter_number:int: 현재 카운터 값"""
return int(self.conn_redis.get(name=self.key))
References