Redis 운영 이슈는 4가지로 정리할 수 있다.
메모리 관리를 잘하자
O(n) 관련 명령어를 주의하자 => single thread라 소요 시간이 큰 명령어가 들어오면 blocking된다.
Replication
Redis 설정
메모리 관리
* 인 메모리 스토리지이므로 메모리 관리가 중요하다. 당연히 physical memory 이상 사용할 수 없다.
- swap이 있다면 swap 사용으로 죽지는 않지만 swap이 발생한 접근시 디스크를 사용하므로 늦어짐
- swap이 없다면 죽는다.
* swap? : virtual memory (가상메모리)로 전환.
* 현재 메모리를 사용해서 swap을 쓰고 있다는 것 조차 모를 때가 많다. Redis의 가용 가능한 용량이 어느정도고, 현재 얼마 정도나 썼는지 모니터링을 안해서 그렇다. 모니터링을 하자.
* Maxmemory 설정을 하더라도 실제 Redis에서는 이보다 더 많은 용량을 사용할 가능성이 크다.
* RSS값을 모니터링 해야함
* 큰 메모리를 사용하는 instance 하나보다는 적은 메모리를 사용하는 instance 여러 개가 안전함.
* Redis는 메모리 파편화가 발생할 수 있다. 4.x 대 부터 메모리 파편화를 줄이도록 jemalloc에 힌트를 주는
기능이 추가되었으나 jemalloc버전에 따라 다르게 동작할 수 있다.
* 파편화? 를 간단하게 설명하면, 메모리를 할당하고 해제하는 과정에서 잘게 쪼개진 메모리 영역이 생기게 된다. 때문에 컴퓨터 입장에서는 실제 사용하고 있는 메모리보다 더 많은 용량의 메모리를 사용하고 있다고 여길 수 있고 프로세스가 죽게되는 원인이 되기도 한다. Redis에서도 이런 문제가 발생하니 메모리를 여유롭게 잡는 것이 좋다. 60~70% 정도 사용한다고 생각하자.
* 3.x 버전의 경우 used memory가 2GB로 보고되었으나 11GB RSS를 사용하는 등의 사례가 자주 발생한다.
* 다양한 사이즈를 가지는 데이터보다 유사한 크기의 데이터를 가지는 것이 좋다. 메모리 파편화를 조금이나마 줄일 수 있다고...
* 메모리가 부족할 때는?
- 일단, 큰 memory로 migration 해야 하는 것이 정석. 그러나 메모리를 빡빡하게 사용하고 있는 중이라면 migration 중에 문제가 발생할 수 있으니, 60~70% 정도 사용하고 있다면 migration을 진행하는 것이 좋다.
- 있는 데이터를 줄여도 된다.
* 메모리를 줄이기 위한 설정
- 기본적으로 Collection들은 다음과 같은 자료구조를 사용함.
-
hash => hashTable을 하나 더 사용
-
sorted set => skiplist와 hashTable을 이용
-
set => hashTable 사용
그런데 이 자료구조들은 메모리를 많이 사용함.
따라서, hashTable이나 skiplist를 사용하지 않고 Ziplist를 이용하게 되면 속도는 느려지지만 메모리는 훨씬 적게 사용하게 된다. 대략 20 ~ 30% 정도 차이가 난다고.
(용량과 관계 없이 속도가 더 중요하다면 Ziplist를 안 쓰면 된다. 그러나 이미 메모리라서 속도는 충분히 빠르다!)
그렇다면 Ziplist를 어떻게 쓰느냐 ? Redis 설정에 가서 해주면 된다. /etc/redis/redis-conf
어느 레벨까지 사용할지는 베스트 프랙티스가 없다. 알아서 적절히 설정해주어야 한다.
hash-max-ziplist-entries : 몇 개 까지는 ziplist를 사용하겠다
hash-max-ziplist-value : 어느 값 까지는 ziplist를 사용하겠다.
list-max-ziplist-size
list-max-ziplist-value
zset-max-ziplist-entries
zset-max-ziplist-value
O(n) 관련 명령어를 주의하자
Redis는 싱글 스레드다. 즉, 동시에 처리할 수 있는 명령 갯수는 한 번에 1개 뿐이다.
blocking이 생기면 node에서 처럼 지옥이...
따라서 긴 시간이 필요한 명령을 사용하면 안된다. => O(n) 명령어를 주의해야 하는 이유이다.
대표적인 O(n) 명령어는 다음과 같은 것들이 있다.
keys
flushall, flushdb
delete collections
get all collections
위 명령어를 오용하는 케이스는 다음과 같다.
key가 백만개인데 확인을 위해 짧은 주기마다 keys 명령을 매번 돌린다.
아이템이 몇만개 든 hash, sorted,set, set에서 모든 데이터를 가져오기
그러면 뭘 써야 하지?
- keys는 어떻게 대체할 수 있는가? scan 명령어를 사용하자
- 전체 Collection
Collection의 일부만 가져오거나 큰 Collection을 작은 여러개의 Collection으로 나눠서 저장해야 한다.
Userrank => Userrank1, Userrank2 ...
Replication
redis는 replication(복제)가 가능하다.
* redis replication은 async replication입니다. 따라서 replication lag가 발생할 수 있습니다.
* replica는 Replicaof(redis >= 5.0.0.) 혹은 slaveof 명령어로 설정 가능합니다.
Replicaof [hostname] [port]
fork 하는 과정 중에 메모리가 가득 차 있다면 복사가 안될 수 가 있다. 예전에도 언급했지만 메모리의 60~70% 까지만 쓰자.
세부적인 내용은 추후에 Replication 관련 포스트에서 다루도록 하자!
그래서 뭘 어떻게 설정해야 하는가? Redis 설정 팁
/etc/redis/redis-conf 에서 적절히 설정해주자.
redis-server를 설치한 후 conf에 들어가면 설정값들에 주석이 친절하게 달려 있으니 읽어보고 대처하면 됩니다.
- Maxclient 설정을 50000 으로 높이자. 설정창을 찾아보니 10000이 기본 값이더라 (설정한 값의 수만큼만 client 접속 가능)
- RDB/AOF 설정 off (persistance 기능을 끄는게 성능, 안정성이 높음. 혹시 persistance를 유지해야 할 경우 Master에서는 off 시켜놓고 Slave에서만 이 설정을 켜두도록 하자)
- 특정 command는 disable 시키자. 다른 건 몰라도 'Keys'를 disable 시켜야 함 aws elasticCache에서는 애초에 disable 되어 있다.
- maxmemory를 사용할만큼 지정합니다. 1g로 놓으면 1GB만 사용하게 됩니다.
- maxmemory-policy, 즉, 메모리가 꽉 찼을 때의 정책을 설정합니다. 사실 이럴 일이 없게 60~70% 정도 차면 migration을 해주는 것이 맞습니다만 사람 일이 항상 계획대로 되지는 않으니까요. allkeys-lru로 설정하면 가장 최근에 입력 받은 값을 사용하고, 전의 값은 지웁니다.
- 적절하게 ziplist 자료구조를 사용하도록 설정하자.
hash-max-ziplist-entries : 몇 개 까지는 ziplist를 사용하겠다
hash-max-ziplist-value : 어느 값 까지는 ziplist를 사용하겠다.
list-max-ziplist-size
list-max-ziplist-value
zset-max-ziplist-entries
zset-max-ziplist-value
모니터링
Redis info를 통한 정보에서 봐야할 정보들
RSS
Used Memory (내가 얼마나 쓰고 있나?)
Connction 수 (client가 몇 개나 접속하고 있나?)
초당 처리 요청 수
System에서 봐야할 정보들
CPU
Disk
Network rx/tx
운영 관련 명령어
info 관련
info : 전체
info memory : 메모리
info stats : 통계정보
info clients : client 정보
dbsize : redis 서버내 존재하는 keys 수를 출력합니다.
dbsize
flushall : 기존 키를 전부 날린다. 편해서 애용 중이다.
flushall
ping : 레디스 서버 체크. 정상이면 pong하고 답장이 온다
ping
redis tools
더 나아가 redis를 사용하기 쉽게 해주는 모니터링 도구들을 살펴보고, 사용하자.
github.com/AlexStocks/redis-tool-set#redis-monitor
참고한 글)
'DB, ORM > 🟥 Redis' 카테고리의 다른 글
Redis를 활용한 Look aside 방식의 캐싱 in node.js (0) | 2020.12.29 |
---|---|
Redis Persistence (0) | 2020.12.29 |
Redis : pub/sub model (0) | 2020.12.28 |
Redis 기초 : Redis의 특성과 Collection (0) | 2020.12.28 |