Programming Language/Python

[PYTHON] Python에서 Redis를 사용 + 인메모리 캐시(Ubuntu 18.04)

new_challenge 2020. 7. 27. 23:22
반응형

이번 포스팅은 파이썬에서 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 부분을 확인하면 현재 사용중인 메모리와 전체 메모리를 확인 할 수 있다.

 

htop 화면

 

레디스 메모리 설정

$ 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를 사용하여 파이썬에서 레디스를 사용할 수 있도록 패키지 설치

- 아래는 파이썬 공식 레디스 패키지 링크

 

redis

Python client for Redis key-value store

pypi.org

 

포트오픈 확인

$ 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 [특정문자]*

- 특정 문자를 포함하는 키값을 가져오고 싶을 때는 위와 같이 한다.

 

예시 화면

 

 

반응형