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