-
Notifications
You must be signed in to change notification settings - Fork 2
Redis on kubernetes
RDBMS만큼의 정합성과 영속성을 보장할 필요가 없는 데이터들을 빠르게 처리하거나 일정 기간동안만 보관하고 있기 위한 용도로 레디스(Redis), memcached 등의 in-memory 기반 저장소가 많이 사용
- 기본적으로 단일인스턴스도 high availability 을 보장한다.
- 레디스는 마스터에서 슬레이브로 단방향 비동기 복제(unidirectional asynchronous replication)를 사용한다.
- 센티넬(Sentinel)
: 서버가 분할되지 않은 단일 데이터베이스를 관리하는 목적으로 redis 를 쓸때 적합함
: 안정적 운영을 위해서는 최소 3개 이상의 sentinel instance 필요
: redis와 별도의 process 를 가지고,
: 지속적으로 master/slave 가 제대로 동작을 하고있는지 모니터링
: redis 연결시 Sentinel 에 연결해서 master 조회해야함.
- 클러스터(Cluster)
: 여러 인스턴스 간에 데이터가 분할되고, 자체적으로 관리하고, 별도의 구성요소가 필요없는 서비스 구성시 사용
: 클러스터 안에서 내부 상호 연결을 통해서 자체적으로 오류 감지
: 기본인스턴스 실패시 복제본중 하나가 자동 승격
: Redis Cluster 기능을 지원하는 client를 써야만 데이터 액세스 시에 올바른 노드로 redirect가 가능
- 참고 [개발 언어별 유명 redis client 비교 분석(https://www.compose.com/articles/a-tour-of-the-redis-stars-2/)]
- jedis 를 사용하는 이유
a) 가장 많은 Contributor 를 보유하고 있는 오픈소스 프로젝트이며 가장 오래된 클라이언트이다.
- 컨트리뷰터 수가 다른 프로젝트와 많은 차이가 날 만큼 많다.
Jedis : 108 / lettuce : 12 / redisson : 26
또한 국내에서 Redis 로 유명하고 책도 많이 쓰신 카카오 강대명씨가 커미터로 활동하고 계신 프로젝트가 바로 Jedis 다.
b) jedis는 이슈와 피드백이 많다.
다른 클라이언트에 비해서 Jedis는 사용자가 많고, 커밋 시점이 오래되었고 지금도 활발한 편이여서 이슈나 피드백이 많다.
따라서, 예제소스 찾기가 쉬우며 그만큼 레퍼런스가 많은 편이다.
c) Jedis는 사용이 간편하다.
처음 접근하기에 사용이 간편하고 버그에 대한 피드백도 빠른편, 그리고 여러가지 기능을 붙이지 않는 것도 장점이다
(출처: http://blessldk.blogspot.com/2016/05/redis-java.html)
- 스냅샷(RDB file 포함), 로그 변경( AOF 사용 - append only file )
- 스냅샷
: 일정시간별로 특정 시점 복구를 위한 스냅샷을 찎는다.
: RDB file 은 압축된 사용자 데이터 덤프를 의미함
: restart 시간이 빠르다
: 멈췄을때 데이터 유실 가능성이 더 높다.
: 몇 분 정도의 데이터 유실 가능성을 감내 할 수 있다면 RDB를 쓰는것을 추천
- 로그 변경
: 매초 또는 변경될때마다 AOF 파일의 변경사항을 flush 하도록 설정 가능
: AOF가 변경되어 크기가 커지면 데이터 집합을 복구하는 데 시간이 오래 걸림
: 읽기 쉬운 포멧이지만 RDB보다 용량이 크다
: 어느 시점에 server가 down되더라도 데이타 유실이 발생하지 않는다
- RDB와 AOF 방식의 장단점을 상쇠하기 위해서 두가지 방식을 혼용해서 사용하는 것이 바람직한데
주기적으로 snapshot으로 백업하고, 다음 snapshot까지의 저장을 AOF 방식으로 수행한다.
이렇게 하면 서버가 restart될 때 백업된 snapshot을 reload하고, 소량의 AOF 로그만 replay하면 되기 때문에, restart 시간을 절약하고 데이타의 유실을 방지할 수 있다.
> 참고: http://bcho.tistory.com/654
> https://redis.io/topics/persistence
https://github.com/helm/charts/tree/master/stable/redis
## redis password 를 secretpassword 로 사용
## master.disableCommands는 기본적으로 FLUSHALL, FLUSHDB 가 설정되어있는 상태이다. 해당 명령어를 사용하려면
## master.disableCommands='' 으로 설정을 해줘야 한다.
## redis cluster 는 default 로 RDB 로 설정이 되어있음
## configmap='appendonly yes' 설정시 AOF 파일을 설정하고, AOF 파일이 없을 경우 RDB를 바라본다.
helm install --name my-redis \
--set password=secretpassword \
--set master.disableCommands='' \
--set configmap='appendonly yes' \
stable/redis
--set persistence.existingClaim=PVC_NAME
--set configmap='appendonly yes'
# Cli 접근
kubectl exec -it my-redis-master-0 -- redis-cli -a secretpassword
## 키 확인
> keys *
## 전체 삭제 (기본 설치시에는 전체삭제 커맨드는 막혀있는 상태이다. master.disableCommands='' 옵션을 주어야 삭제가 가능하다)
> FLUSHALL
# bash 접근
kubectl exec -it my-redis-master-0 /bin/bash
## Redis 는 마스터 노드는 1개이고 slave 에 마스터 노드의 데이터를 복제하는 구조이다.
## 마스터 노드가 죽으면 slave는 master로 승격을 하는 구조여서
## 안전한 운영을 위하여 1 master, 2 slave 를 사용한다.
kubectl scale --replicas 2 deployment my-redis-slave
kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES
STORAGECLASS AGE
redis-data-my-redis-master-0 Bound pvc-d5f71590-364b-11e9-a568-02910c21b398 8Gi RWO
gp2 3d
설치후 데이터 저장장소는 /data 로 PV 와 연결이 된다.
레디스 강제로 데이터 저장 명령어 SAVE
해당 명령어를 사용하면 /data 폴더에 dump.rdb 파일이 생성된다.
파일명은 변경이 불가능함
주기적으로 데이터를 SAVE 하는 스크립트를 작성하려면
redis.conf 파일에
save 900 1 900초(15분) 동안 1번 이상 key 변경이 발생하면 저장
save 300 10 300초(5분) 동안 10번 이상 key 변경이 발생하면 저장
save 60 10000 60초(1분) 동안 10000번 이상 key 변경이 발생하면 저장
기본으로 redis 설치 후 master pod 를 삭제하면 replicas 에 의하여 master pod 가 다시 생성된다.
이때 정상적으로 기존에 저장되어있는 값을 가져오는지 test 한다.
- Redis 설치
➜ ~ helm install --name my-redis \
--set password=secretpassword \
--set master.disableCommands='' \
stable/redis
➜ ~ kubectl get po -l app="redis"
NAME READY STATUS RESTARTS AGE
my-redis-master-0 1/1 Running 0 2d
my-redis-slave-5c4755c6b6-ntzj6 1/1 Running 0 2d
- Redis 에 데이터 주입
~ kubectl exec -it my-redis-master-0 -- redis-cli -a secretpassword
127.0.0.1:6379> set key2 data1
127.0.0.1:6379> set key3 data2
- 데이터 확인
127.0.0.1:6379> keys *
1) "key2"
2) "key3"
- pod 삭제
➜ ~ kubectl delete po my-redis-master-0
- my-redis-master 재시작 후 데이터 확인
127.0.0.1:6379> keys *
(empty list or set)
결과 >> 데이터가 모두 삭제 되는 것을 볼 수있다.
이는 RDB 로 데이터를 저장시 SAVE 명령어가 호출된적이 없기때문에,
메모리 상에서만 데이터가 존재하고, 재시작시 모든 데이터는 날라간다.
시나리오 1번에서 SAVE 명령어가 실행이 안되서 모든 데이터가 날라갔으니
key 생성 후 SAVE 명령어를 호출 한 후, 생성되는 rdb 파일을 확인 한 후,
pod 삭제 후 다시 설치시 data 가 load 되는지를 확인한다.
- rdb data 확인
~ kubectl exec -it my-redis-master-0 /bin/bash
I have no name!@my-redis-master-0:/$ df -h
Filesystem Size Used Avail Use% Mounted on
....
/dev/xvdbg 7.9G 36M 7.8G 1% /data
....
I have no name!@my-redis-master-0:/$ cd /data
I have no name!@my-redis-master-0:/data$ ls -al
total 32
drwxrwsr-x 3 root 1001 4096 Feb 25 04:49 .
drwxr-xr-x 1 root root 4096 Feb 25 04:48 ..
-rw-r--r-- 1 1001 1001 176 Feb 25 04:49 dump.rdb
drwxrwS--- 2 root 1001 16384 Feb 22 02:45 lost+found
I have no name!@my-redis-master-0:/data$
- key 생성 후 SAVE 명령어를 실행하여 데이터 저장
~ kubectl exec -it my-redis-master-0 -- redis-cli -a secretpassword
127.0.0.1:6379> set key2 data1
127.0.0.1:6379> set key3 data2
127.0.0.1:6379> SAVE
OK
~ kubectl exec -it my-redis-master-0 /bin/bash
I have no name!@my-redis-master-0:/$ cd /data
I have no name!@my-redis-master-0:/data$ ls -al
## 176 > 206 으로 데이터가 늘어났음 (저장 확인)
-rw-r--r-- 1 1001 1001 206 Feb 25 05:21 dump.rdb
- pod 삭제
➜ ~ kubectl delete po my-redis-master-0
- my-redis-master 재시작 후 데이터 확인
127.0.0.1:6379> keys *
1) "key2"
2) "key3"
결과 >> 데이터를 저장 후 pod 가 삭제되어도 pod 가 재 실행시 같은 PV 를 바라보고 있기때문에
정상적으로 데이터가 나오는 것을 확인 할 수있다.
3번 시나리오는 redis 를 완전히 삭제 후, 같은 이름으로 재 설치를 하는 case 이다.
같은 이름으로 재설치를 하게되면 PV 의 이름이 같기때문에 같은 데이터 경로를 바라보기 때문에
재설치 후 key 값을 조회시 2번시나리오에서 테스트 했던 데이터가 그대로 보여질 것으로 예측된다.
- my-redis 제거 및 재설치
➜ ~ helm delete my-redis --purge
➜ ~ helm install --name my-redis \
--set password=secretpassword \
--set master.disableCommands='' \
stable/redis
- rdb data 확인
~ kubectl exec -it my-redis-master-0 /bin/bash
I have no name!@my-redis-master-0:/$ cd /data
I have no name!@my-redis-master-0:/data$ ls -al
-rw-rw-r-- 1 1001 1001 206 Feb 25 05:21 dump.rdb
- 실제 데이터 확인
➜ ~ kubectl exec -it my-redis-master-0 -- redis-cli -a secretpassword
127.0.0.1:6379> keys *
1) "key2"
2) "key3"
설치시 AOF 옵션을 주어서 AOF 와 RDB 를 혼용해서 사용하는 경우이다.
이럴때 데이터는 AOF 를 먼저 읽어서 가져와서 data 를 load 하고, 필요시 snapshot 을 떠서 rdb 로 저장을 해서 사용 가능하다.
시나리오 3번과 같은 결과값을 가진다.
여기서는 생성되는 파일을 확인 해 보고, 파일의 내용을 읽는 test 를 진행할 것이다.
- AOF 옵션을 주어서 redis 설치
➜ ~ helm delete my-redis --purge
release "my-redis" deleted
➜ ~ helm install --name my-redis \
--set password=secretpassword \
--set master.disableCommands='' \
--set configmap='appendonly yes' \
stable/redis
- 생성 파일 확인
➜ ~ kubectl exec -it my-redis-master-0 /bin/bash
I have no name!@my-redis-master-0:/$ cd /data
I have no name!@my-redis-master-0:/data$ ls -al
total 28
drwxrwsr-x 3 root 1001 4096 Feb 25 05:37 .
drwxr-xr-x 1 root root 4096 Feb 25 05:36 ..
-rw-r--r-- 1 1001 1001 0 Feb 25 05:36 appendonly.aof
-rw-r--r-- 1 1001 1001 176 Feb 25 05:37 dump.rdb
drwxrwS--- 2 root 1001 16384 Feb 22 02:45 lost+found
** !! configmap 에 데이터를 설정하게 되면 기존의 데이터는 초기화 된다. ** ** appendonly.aof 파일이 생성된 것을 확인 할 수있다. (파일명은 설정을 통하여 변경 가능하다) **
- 데이터 생성
~ kubectl exec -it my-redis-master-0 -- redis-cli -a secretpassword
127.0.0.1:6379> set key2 data1
127.0.0.1:6379> set key3 data2
- 파일에 데이터 확인
I have no name!@my-redis-master-0:/data$ ls -al
total 32
drwxrwsr-x 3 root 1001 4096 Feb 25 05:37 .
drwxr-xr-x 1 root root 4096 Feb 25 05:36 ..
-rw-r--r-- 1 1001 1001 91 Feb 25 05:44 appendonly.aof
-rw-r--r-- 1 1001 1001 176 Feb 25 05:37 dump.rdb
I have no name!@my-redis-master-0:/data$ cat appendonly.aof
$3
set
$4
key2
$5
data1
*3
$3
set
$4
key3
$5
data2
- No persistence
Redis pub sub은 지속적이지 않습니다.
메시지는 Subscriber에게 직접 전달된 후 삭제되며, 메모리 또는 디스크에 기록이 남지 않습니다.
pub sub은 오직 새로운 메시지 전달만 용이하게 한다는 점에서 live stream과 같습니다.
- No delivery guarantees
pub sub 모델에서 Subscriber가 메시지 받는 것을 보장하지는 않습니다.
예를 들어 Subscriber의 네트워크에 문제가 생기면, 메시지를 읽는데 실패할 것입니다.
즉, Subscriber가 만약 메시지를 놓쳤다면, 메시지를 받을 수 없습니다.
출처: https://victorydntmd.tistory.com/249 [victolee]