redis란?
레디스(Redis)는 Remote Dictionary Server
의 약자로서 (1)인 메모리 (2)”키-값” 구조 의 비정형 데이터를 저장하고 관리하기 위한 오픈 소스 기반의 비관계형 데이터베이스 관리 시스템(DBMS)입니다.
주요 특징 중 하나는 보조 기억장치가 아닌 주기억장치인 메모리에 데이터를 올려놓음으로써(인 메모리) 데이터를 조회하는 속도를 비약적으로 상승시킬 수 있다는 것입니다.
이러한 특성 덕분에 Redis는 캐싱, 세션 저장 등 다양한 용도로 활용되고 있으며, “키-값” 구조의 유연한 저장 방식 또한 여러 상황에서 사용될 수 있는 Redis의 장점입니다.
redis 설치
redis 패키지 설치하기
운영체제에 맞게 설치를 진행해줍니다. 아래는 리눅스에서 패키지 설치 예시입니다.
1
2
3
4
5
6
7
8
9
10
11
# Ubuntu
sudo curl -fsSL https://packages.redis.io/gpg | sudo gpg --dearmor -o /usr/share/keyrings/redis-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/redis-archive-keyring.gpg] https://packages.redis.io/deb $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/redis.list
sudo apt-get update
sudo apt-get install redis
# Cent OS
sudo yum install redis
# Rocky
sudo dnf install redis
리눅스 외 다른 운영체제에서 설치 방법은 공식 홈페이지를 참고해주세요.
https://redis.io/docs/install/install-redis/
설치 후에는 systemctl 명령어로 redis 서비스를 실행시키고, 서버 시동시 자동으로 실행될 수 있도록 설정해줍니다.
1
2
systemctl start redis-server
systemctl enable redis-server
혹은 redis 서버를 직접 실행할 수도 있습니다. systemctl 명령어를 사용할 수 없는 docker 등에서는 아래와 같이 redis 서비스를 실행할 수 있습니다.
1
2
redis-server # 포그라운드에서 실행
nohup redis-server & # 백그라운드에서 실행
redis 도커 이미지 이용하기
redis 패키지를 설치하지 않고, redis 서비스를 전담하는 도커 컨테이너를 구동하는 것도 하나의 방법입니다.
1
2
docker pull redis
docker run -p 6379:6379 -d redis:latest
redis 접속하고 사용해보기
redis 접속하기
redis 서비스가 잘 설치되었다면, 해당 서비스로 접속해보도록 하겠습니다.
redis-cli
명령어를 통해 redis 의 cli 화면으로 접속합니다.
1
2
redis-cli
IP주소:6379> # redis 커맨드 라인 인터페이스
6379는 redis의 기본 port 번호입니다. 이는 뒤에 살펴볼 설정에서 변경할 수 있습니다.
redis CRUD
몇 가지 redis 명령어를 살펴보겠습니다.
명령어 | 설명 | 사용례 |
---|---|---|
set [key이름] [value] | {key:value} 데이터를 추가한다. | set samplekey1 samplevalue1 |
mset [key1] [value1] [key2] [value2] | 여러 개의 {key:value} 데이터를 추가한다. | mset key2 value2 key3 value3 key4 value4 |
setex [key이름] [지속시간(초)] [value] | 데이터의 소멸 시간을 지정하여 데이터를 추가한다. (초단위) | setex key5 10 value5 |
get [key이름] | key 에 해당하는 value를 가져온다. | get key2 |
mget [key1] [key2] … | key 들에 해당하는 value 들을 가져온다. | mget key2 key3 key4 |
del [key1] [key2] … | key들에 해당하는 {key:value} 데이터를 삭제한다. | del key3 key4 |
rename [originkeyname] [changekeyname] | key 의 이름을 변경합니다. | rename key2 samplekey2 |
keys [검색어] | 키 이름에 검색어가 들어간 모든 key들을 검색한다. | keys * keys keyname |
flushall | 모든 데이터를 삭제 | flushall |
1
2
3
4
5
6
# set, mset : 데이터 추가
set samplekey1 samplevalue1
>> OK
mset key2 value2 key3 value3 key4 value4
>> OK
1
2
3
4
5
6
7
# get, mget : 데이터 조회
get key2
>> "value2"
mget key3 key4
>> 1) "value3"
>> 2) "value4"
1
2
3
4
5
6
7
8
9
10
#setex : 소멸 시간이 있는 데이터 추가
setex key5 10 value5
>> OK
get key5
>> "value5"
(..10초 후..)
get key5
>> (nil)
1
2
3
4
5
6
# del :데이터 삭제
del key3 key4
>> (integer) 2
get key3
>> (nil) # 삭제됨
1
2
3
# rename : key 이름 변경
rename key2 samplekey2
>> OK
1
2
3
4
5
6
7
# keys : key 조회
keys *
>> 1) "samplekey2"
>> 2) "samplekey1"
keys *2*
>> 1) "samplekey2"
1
2
3
4
5
6
# flushall : 모든 데이터 삭제
flushall
>> OK
get samplekey2
>> (nil)
redis 구성 설정하기
redis 서비스에 대한 설정은 redis.cnf
파일에서 할 수 있습니다. 설정 파일은 보통 etc/redis/redis.conf
에 위치해있습니다.
1
vi /etc/redis/redis.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# 기본 설정
bind <사용할ip> # redis 인스턴스가 사용할 네트워크 ip
port <사용할포트> # redis 인스턴스가 사용할 포트. 기본 6379
timeout <초> # 연결된 클라이언트와 얼마동안 송수신이 없을 경우 연결 종료.
# 0 = 타임아웃 사용하지 않음
loglevel <로그레벨> # 로그 레벨. debug / verbose / notice / warning
logfile "<경로>" # 로그를 저장하는 경로 및 파일명
# 스냅샷
save <초> <키변경 횟수> # 스냅샷을 저장하는 규칙. 지정 초마다 or 키 변경 횟수마다
dbfilename <파일명> # 스냅샷 파일명 지정. 기본은 dump.rdb
dir <경로> # 스냅샷 등이 저장되는 레디스 폴더
# AOF 설정 (레디스에서 발생한 데이터 변경 이력)
appendonly <yes/no> # AOF 기능을 사용할 것인지 여부 설정
appendfilename "<경로>" # AOF 파일 저장 경로를 지정
# 복제 설정
masterauth <패스워드> # 슬레이브가 마스터에 접근하기 위한 암호 (master에서 설정)
slaveof <마스터IP> <마스터포트> # 마스터 노드의 위치를 지정한다. (slave에서 설정)
masterauth <패스워드> # masterauth가 있을 경우 입력 (slave에서 설정)
slave-read-only <yes/no> # Slave 를 읽기 전용으로 설정 (slave에서 설정)
repl-ping-slave-period <초> # 마스터와 슬레이브 간 ping 메세지 간격 설정 (slave에서 설정)
# 보안
requirepass <패스워드> # redis 서버에 접근하기 위한 암호를 설정
redis-cli -h <ip주소> -p <포트> -a <비밀번호> # 암호가 설정된 경우 왼쪽과 같이 접속
# 제한
maxclients <연결갯수> # redis에 최대로 유지할 수 있는 연결 개수를 설정
maxmemory <용량> # redis가 사용할 수 있는 최대 메모리 양을 설정. ex.2GB
maxmemory-policy <정책> # 데이터가 maxmemory 를 넘어설 경우 어떻게 데이터를 삭제할지
# - noeviction : 새로 들어오는 데이터를 막는다.
# - allkeys-lru : Least Recently Used 가장 최근에 사용되지 않은 데이터를 제거
# - allkeys-lfu : Least Frequently Used 가장 적게 사용된 데이터를 제거
# - allkeys-random : 랜덤으로 제거
# - volatile-lru : 만료시간이 설정된 키 중 LRU로 삭제
프로그래밍에서 redis 이용하기
python
! 앞서 살펴본 redis 가 설치되어있고, 실행중이어야 합니다.
우선 redis 라이브러리를 설치해줍니다.
1
pip install redis
파이썬 코드에서는 redis 라이브러리를 import 한 다음 사용할 수 있습니다.
import 후 redis.StrictRedis
로 redis 객체를 만들어줍니다.
1
2
3
4
5
6
import redis
rd = redis.StrictRedis(host='서버ip 혹은 로컬은 127.0.0.1', port=포트번호, db=0)
# host : 서버 ip가 있을 경우는 서버 ip
# 로컬 머신에서 돌리는 거라면 127.0.0.1
# requirepass 가 설정된 경우 password 파라미터가 추가되어야 함
이후 사용법은 redis-cli와 동일합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# set, mset : 데이터 추가
rd.set('key1', 'value1')
rd.mset({'key2':'value2', 'key3':'value3'})
# get, mget : 데이터 조회
rd.get('key1')
>> b'value1'
rd.mget('key2', 'key3')
>> [b'value2', b'value3']
# setex : 소멸 시간이 있는 데이터 추가
rd.setex('key4', 10, 'value4')
rd.get('key4')
>> b'value4'
..10초 후..
rd.get('key4')
>>
# delete : 데이터 삭제
rd.delete('key2', 'key3')
rd.keys('*')
>> [b'key1']
# rename : key 이름 변경
rd.rename('key1', 'only_key')
rd.get('only_key')
>> b'value1'
# keys : 저장중인 키 조회
rd.keys('*')
>> [b'only_key']
# flushall : 모든 데이터 삭제
rd.flushall()
rd.keys('*')
>> []
다른 프로그래밍 언어에서 redis 이용하기(redis 클라이언트)
– python : redis-py (redis)
– Java : Jedis
– JavaScript(Node.js) : ioredis
– ruby : redis-rb (redis)
– C# : StackExchange.Redis
http 통신으로 redis에 접근하기(WAS)
서버 외부에서 HTTP 요청을 통해 redis에 접근하고, 제어할 수 있게 해보겠습니다. 외부와 redis 사이에 WAS를 구축할 것이며, 빠른 구현을 위해 python의 flask 프레임워크를 사용해보겠습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
from flask import Flask, request
from flask_restx import Api, Resource
import redis
app = Flask(__name__)
api = Api(app)
rd = redis.StrictRedis(host='127.0.0.1', port=6379)
# 모든 키 가져오기
@api.route('/keys', methods=['POST'])
class get_keys(Resource):
def post(self):
return [item.decode('utf-8') for item in rd.keys('*')]
## redis keys 는 반환 데이터타입이 bytes 타입의 값들을 가진 list 형태입니다.
## bytes 객체는 Json 화 할 수 없습니다.
## 때문에 각 원소를 decoding 한 뒤 반환합니다. (=> Json 으로 전송 가능)
# 데이터 추가하기
@api.route('/mset', methods=['POST'])
class mset(Resource):
def post(self):
result = rd.mset(request.json)
return result
# 소멸 시간이 있는 데이터 추가하기
@api.route('/setex', methods=['POST'])
class setex(Resource):
def post(self):
param = request.json
return rd.setex(param["key"], param["extime"], param["value"])
# 데이터 조회하기
@api.route('/get', methods=['POST'])
class get(Resource):
def post(self):
return rd.get(request.json.get("key")).decode('utf-8')
# 데이터 다중 조회하기
@api.route('/mget', methods=['POST'])
class mget(Resource):
def post(self):
mget_list = request.json["mget_list"]
return [item.decode('utf-8') for item in rd.mget(mget_list)]
# 데이터 삭제하기
@api.route('/del', methods=['POST'])
class delete(Resource):
def post(self):
delete_list = request.json["delete_list"]
for item in delete_list:
result = rd.delete(item)
return result
# 데이터 초기화(flushall)
@api.route('/flushall', methods=['POST'])
class flushall(Resource):
def flushall(self):
return rd.flushall()
# flask run
app.run(host='0.0.0.0', port=5000)
redis 테스트
pymysql을 통해 데이터를 조회한 시간과 redis를 통해 데이터를 조회한 시간을 비교해본 결과 아래와 같습니다. (단, DB는 실험을 진행한 서버와 다른 컨테이너에 존재함.)
– 총 10회 반복 시행
– 단위 : ms (1/1000 초)
회차 | pymysql | redis |
---|---|---|
1 | 7.29 | 3.44 |
2 | 3.55 | 0.21 |
3 | 4.68 | 0.17 |
4 | 3.41 | 0.23 |
5 | 3.83 | 0.19 |
6 | 4.9 | 0.28 |
7 | 3.8 | 0.26 |
8 | 5.29 | 0.24 |
9 | 5.95 | 0.33 |
10 | 5.6 | 0.28 |
평균 | 4.83 | 0.56 |
Reference
redis 소개 : https://ko.wikipedia.org/wiki/%EB%A0%88%EB%94%94%EC%8A%A4
redis 소개 : https://aws.amazon.com/ko/elasticache/what-is-redis/
install redis on linux : https://redis.io/docs/install/install-redis/install-redis-on-linux/
rocky linux redis 설치 : https://ko.linux-console.net/?p=3145
redis CRUD : https://freeblogger.tistory.com/10
redis config : https://bstar36.tistory.com/349
redis config : https://ossian.tistory.com/37