보통 데이터베이스는 하드 디스크나 SSD에 저장한다. 하지만 Redis는 메모리(RAM)에 저장해서 디스크 스캐닝이 필요없어 매우 빠른 장점이 존재함
캐싱도 가능해 실시간 채팅에 적합하며 세션 공유를 위해 세션 클러스터링에도 활용된다.
RAM은 휘발성 아닌가요? 껐다키면 다 날아가는데..
이를 막기위한 백업 과정이 존재한다.
snapshot : 특정 지점을 설정하고 디스크에 백업
AOF(Append Only File) : 명령(쿼리)들을 저장해두고, 서버가 셧다운되면 재실행해서 다시 만들어 놓는 것
데이터 구조는 key/value 값으로 이루어져 있다. (따라서 Redis는 비정형 데이터를 저장하는 비관계형 데이터베이스 관리 시스템이다)
String (text, binary data) - 512MB까지 저장이 가능함
set (String 집합)
sorted set (set을 정렬해둔 상태)
Hash
List (양방향 연결리스트도 가능)
In-Memory Storage
저장장치를 쓰는 RDB에 비해 빠르다
다양한 기능 제공
Key-Value, 위치 기반 검색, 랭킹, Queue-Stack
Transaction 지원, TTL 지원
Snapshot
지속적으로 무중단 저장장치에 저장 가능
Replication
다른 노드에 복제가 가능
Redis Cluster
여러대의 Redis로 분산 저장및 처리가 가능
Thread Model
Node.js Thread Model과 유사하다
Redis vs MemcacheD
개인적으로는 Redis의 사용빈도가 높은것으로 보임
Redis Client가 요청하려는 Key를 해시 함수를 돌려 나온 값으로 노드를 찾아서 저장함
데이터 복제본을 Replica에 저장함
다른 프로젝트 경우
Replica없이 다른 노드에 복제본을 저장하기도 함
대부분의 명령어들은 Single Thread로 동작함
암호화 관련, File I/O 관련 작업은 별도의 쓰레드에서 작업 됨
반드시 명령어를 받은 순서대로 처리됨
Atomic Operation이 맞음
https://redis.io/docs/getting-started/faq/
Master 노드에 장애가 생긴경우
Replica가 있는 경우
Replica Node가 Master로 승격됨
Replica가 없는 경우
장애가 생긴 노드를 복구하거나 새로운 노드를 추가해야됨
그전까지는 해당 노드에서 다루던 데이타들 접근 불가
트랜잭션 지원함
CAS 방식과 유사함
WATCH로 데이타를 Observing 함
MULTI로 트랜잭션 시작
Commit은 EXEC
RollBack은 DISCARD
Commit이 실패하면?
유저에게 다시 실행하세요 하고 에러 리턴함
제일 구현이 간편하고 UX상으로는 조금 불편
서버에서 성공 할때 까지 재시도
Timeout 구현해야 되니 코드가 복잡
Timeout이 발생할 만큼 계속 실패 한다면
설계부터 다시 하는게 맞음
UX 상으로는 좀더 나음
Master에 있는 데이터가 특정 순간에 Replica와 다를수도 있다는 얘기
Master 노드에 장애가 발생하여 Replica가 Master로 승격 됐을때 Replica는 오래된 데이터 일수 있음
Master에 쓰기를 한 Request는 변경된 값을 Return하기 위해 Replica에서 Read해서 리턴해주면 안됨
변경된 값을 Redis가 리턴해주면 그걸 쓰셔야 됨
Success 리턴만 있다면 변경한 값을 쓰셔야 됨
완전히 복제되기까지 단순 Read Request는 오래된 데이타를 읽을수 있다는걸 인정 함
비동기 시스템이 많아지면서 유저들도 오래된 데이타가 나오면 Refresh 연타 하는 습관이 들어서 괜찮을수 있음
무조건 최신 데이터를 Replica에서 읽어야 한다면?
Master에서 읽음
Replica에서 무조건 최신 데이터를 읽도록 구현 하려면 구현 방법이 복잡해지고 느릴수 밖에 없음
Subscribe 명령어로 특정 채널을 구독함
Publish 명령어로 특정 채널을 구독한 Connection에 메세지를 보냄
이전 메세지 가져올수 없음
메세지를 받아서 어떤 처리를 해야 하는데 실패함
다시 시도하고 싶은데 이 메세지를 어딘가에 저장하지 않음
영원히 재시도 불가능
못 받을수도 있다 라고 생각하고 쓰는게 좋음
내 웹서버는 서버가 뜰때 한번 Redis에서 DB의 IP와 Port를 가져옴
Redis에 있는 DB의 IP와 Port를 변경하면 현재 실행중인 서버에 알려주고 싶음
실행 중인 서버들은 새로운 IP와 Port를 적용하여 Connection을 재 생성