-
■Redis란?
- Remote Dictionary Server의 약자
- 비 관계형 DB인 NoSql에 속하는 In-Memory DB 형태의 시스템
In-Memory DB : Memory에서 데이터를 다루며 read, write 속도가 빠르다.
- Memory에 데이터가 저장되기 때문에 시스템이 꺼지면 모든 데이터가 삭제됨
따라서 데이터를 지속적으로 유지하기 위해
모든 작업을 로그에 기록해서 Disk에 저장한 후
시스템을 구동할 때 로그를 기반으로 데이터를 다시 메모리에 올리는 방식으로
데이터를 Backup (아래에 자세한 Backup 방식 정리)
- key-value 구조로 데이터를 저장하고 조회
- 주로 RDBMS의 부하를 줄이기 위한 캐시 솔루션으로 사용
■Redis의 사용 사례
- 캐싱
- 세션 관리(유저의 정보 관리 등)
- 실시간 순위표(sorted set 데이터 사용)
- 대기열(List)
- 채팅(메세지)
■Memcached와 비교한 Redis의 장단점
Redis는 Memcached와 자주 비교된다.
왜냐하면 캐시 솔루션으로써 Memcached가 먼저 등장했고 그 이후에
Memcached의 단점이 보완된 캐시 솔루션으로 Redis가 등장했기 때문이다.
Memcached는 2003년 Brad Fitzpatrick에 의해,
Redis는 2009년 Salvatore Sanfilippo에 의해 만들어졌다고 한다
Memcached
Redis
다양한 프로그래밍 언어 지원(c, ptyhon, java, etc)
In Memory Storage
명료하고 단순
복잡하고 다양한 활용 가능
멀티 스레드
싱글 스레드
String value 타입 지원
다양한 value 타입 지원
Memory에만 데이터 저장 가능
Memory와 Disk에 데이터 저장 가능
LRU 알고리즘을 이용하여 Eviction
6가지 방법을 통해 Eviction
읽기 전용 데이터 캐싱에 사용
값이 변경되는 데이터 캐싱에 사용
대부분 Redis가 더 우수해 보인다.
하지만 Redis 사용시 주의할 점이 있다.
Redis는 싱글 스레드이기 때문에 1번에 1개의 명령어만 실행할 수 있다.
이는 Memchached보다 데이터 처리 속도가 떨어지는 이유가 되기도 한다.
또한 Redis의 데이터 백업 방식인 Snapshotting(RDB)는 처리 속도가 느리다.
■Redis의 6가지 Eviction 방법
- noeviction : 메모리 제한에 도달하여 클라이언트가 더 많은 메모리를
사용하려 할 때 오류를 리턴
- allkeys-lru : 가장 최근에 사용되지 않은 (LRU) 키를 먼저 제거하여,
새 데이터를 위한 공간을 추가
- volatile-lru : 가장 최근에 사용되지 않은 (LRU) 키와 만료 집합이있는 키를
먼저 제거하여, 새 데이터 공간을 추가
- Allkeys-random : 새 데이터를 추가 할 수 있도록 임의의 키를 제거
- volatile-random : 새 데이터를 추가 할 공간을 만들기 위해 만료된 키를 무작위로 제거
- volatile-ttl : 새 데이터를 저장할 공간을 만들기 위해 만료 집합이있는 키만 제거하고
TTL (Short Time to Live) 키를 먼저 제거
■value 타입
String
일반적인 문자열로 최대 512Mbyte 길이까지 지원.
Text 문자열뿐만 아니라 Integer와 같은 숫자나 JPEG와 같은 Binary 파일까지 저장 가능Set
String의 집합으로 여러 개의 값을 하나의 Value 내에 넣을 수 있음.
정렬되지 않은 집합형으로, 한 Key에 중복된 데이터는 존재하지 않음.
Set에 포함된 요소의 수와 관계없이 일정한 시간으로 체크 가능
Sorted Sets
Set에 Score라는 필드가 추가된 데이터형으로, Score는 일종의 가중치.
데이터는 오름차순으로 내부 정렬되며, 정렬하는 기준이 Score.
Score 값은 중복될 수 없음.
Lists
String의 집합으로 Set과 유사하지만 일종의 양방향 Linked List.
List 앞과 뒤에서 push/pop 연산을 사용해 데이터를 추가 및 삭제가 가능.
Hashes
value에 field와 string value 쌍으로 이루어진 테이블을 저장.
형태는 List와 비슷하나 필드명, 필드값의 연속으로 이루어짐.
■데이터 조작 방법(Redis-cli)
value 할당
SET [KEY] [VALUE]
value 조회
GET [KEY]
key, value 제거
DEL [KEY1]
key 존재 확인
EXISTS [KEY]
key의 time to live 시간을 초단위로 확인
TTL [KEY]
key의 time to live 시간을 밀리초단위로 확인
EXPIRE [KEY] [SECONDS]
key의 time to live 시간을 초단위로 설정
PTTL [KEY]
key의 time to live 시간을 밀리초단위로 설정
PEXPIRE [KEY] [MICRO_SECONDS] key의 time to live 시간 제거
PERSISTS [KEY]
key중 랜덤으로 하나를 반환
RANDOMKEY
■Disk Backup 방식 2가지 :: SnapShotting & AOF (Append on file)
SnapShotting(RDB)
순간적으로 메모리에 있는 내용 전체를 DISK에 옮겨 담는 방식.
출처에 따르면 RDB는 Redis Database file의 약자라고 한다.
- SAVE와 BGSAVE 두가지 방식으로 나뉜다
- SAVE는 bloking 방식이다.
순간적으로 Redis의 모든 동작을 정지시키고
그 때의 Snapshot을 Disk에 저장한다.
- BGSAVE는 non-bloking 방식이다.
별도의 background process를 띄운 후, 명령어 수행 당시의
메모리 Snapshot을 Disk에 저장한다.
저장 순간에 Redis는 동작을 멈추지 않고 정상적으로 동작한다.
- SnapShotting은 기본적으로 save 방식으로 설정되어있다.
redis.conf 파일을 수정하여 방식을 변경하거나 주석처리하여 실행되지 않도록 할 수 있다.
- SnapShotting 방식의 장점
메모리의 Snapshot을 그대로 뜬 것이기 때문에 서버 restart할 때 Snapshot만
load하면 된다. 따라서 빠르게 시작 환경을 구성할 수 있다.
- SnapShotting 방식의 단점
Snapshot을 추출하는 시간이 오래 걸린다.
Snapshot 추출 후 서버가 down되면 Snapshot 추출 이후의 데이터는 유실된다.
백업 시점의 데이터만 유지되는 것이다.
AOF(Append On File)
- AOF는 Redis의 write/update 연산 모두를 log 파일에 기록하는 방식이다.
- 서버가 restart될 때, 기록된 write/update log 파일을
순차적으로 재 실행하여 데이터를 복구한다. - 연산이 발생할 때 마다 매번 기록하기 때문에 RDB 방식과는 달리
특정 시점이 아닌 실시간 로그를 기록할 수 있다. - non-blocking 방식으로 실행된다.
- AOF 방식의 장점
log 파일에 append만 하기 때문에 write 속도가 빠르다.
그리고 어느 시점에 서버가 down 되더라도 데이터 유실이 발생하지 않는다
- AOF 방식의 단점
모든 write/update 연산을 log 파일에 기록하기 때문에
RDB 방식에 비해 로그 파일이 과대하게 크다.
또한 복구할 때, 저장된 write/update 연산을 다시 수행하기 때문에
restart 속도가 느리다.
Redis는 두 방식을 혼용한다.
AOF를 default로 하고 Snapshot을 option으로 한다.
주기적으로 Snapshot 방식으로 Backup하고
다음 Snapshot까지의 저장을 AOF 방식으로 수행하는 것이다.
서버가 restart될 때 우선 Backup된 Snapshot을 reload 시키고
Snapshot이 미처 담지 못한 나머지 소량의 데이터를 AOF 로그 파일을 통해 복구하면
서버 restart 시간을 절약하고 데이터의 유실도 방지할 수 있다.
■Expriation
Redis는 만료된 데이터를 삭제시키는 두가지 정책을 가지고 있다.
Active 방식과 Passive 방식이다.
- Active 방식은 Client가 만료된 데이터에 접근할 때 그 때 삭제한다.
- Passive 방식은 key를 random으로 스캔해서 삭제한다.
아래를 참조해보면, Passive 방식은 초당 10번씩 랜덤으로 20개의 키를 검사한다.
그리고 만료된 키는 삭제한다. 만약 25% 이상의 키가 삭제됐다면
다시 위 과정을 반복한다.
How Redis expires keys
Redis keys are expired in two ways: a passive way, and an active way.
A key is passively expired simply when some client tries to access it, and the key is found to be timed out.
Of course this is not enough as there are expired keys that will never be accessed again. These keys should be expired anyway, so periodically Redis tests a few keys at random among keys with an expire set. All the keys that are already expired are deleted from the keyspace.
Specifically this is what Redis does 10 times per second:
- Test 20 random keys from the set of keys with an associated expire.
- Delete all the keys found expired.
- If more than 25% of keys were expired, start again from step 1.
This is a trivial probabilistic algorithm, basically the assumption is that our sample is representative of the whole key space, and we continue to expire until the percentage of keys that are likely to be expired is under 25%
This means that at any given moment the maximum amount of keys already expired that are using memory is at max equal to max amount of write operations per second divided by 4.
만료 시간(expired time)이 지난 후 클라이언트에 의해서 접근되지 않은 데이터는
Active 방식으로는 지워지지 않고 Passive 방식으로 지워지게 된다.
Passive 방식은 전체 데이터를 스캔하지 않기 때문에
Redis에는 '만료되었으나 지워지지 않은 garbage 데이터'가 존재할 수 있다.
■PUB/SUB
Redis는 메시지 중개자로서 JMS(Java Message Service)나 IBM MQ 같은
'네트워크를 통해 데이터를 송수신 하는 api'에 활용될 수 있다.
1:1 형태의 Queue 뿐만 아니라 1:N 형태의 Publish/Subscribe 메세징도 지원한다.
Pub/Sub 구조에서 사용되는 Queue를 일반적으로 Topic 이라고 한다
하나의 클라이언트가 한 채널(key)를 Publish하면
이 Topic을 구독(Subscribe)하고 있는 다수의 클라이언트가 메세지를 받을 수 있다.
그리고 구독을 하는 클라이언트는 Publish를 하는 클라이언트를 명확히 알지는 못한다.
한편 Redis에서는 Pattern matching을 통해 다수의 Topic을 Subscribe 할 수 있다.
예를 들어 Topic 이름이 music.pop, music.classic 이라는 두 개의 Topic이 있을 때
PSUBSCRIBE music.* 라고 하면 두 Topic 모두를 Subscribe하여 message를 받을 수 있다.
'Infra' 카테고리의 다른 글
Rabbit MQ란? (0) 2021.07.08 서버 확장 방법(스케일 아웃 vs 스케일 업) (0) 2021.02.09 댓글