Open Source(BSD3 License)
- 수정과 배포가 자유롭다.
지원하는 자료 구조
- Redis Collections : Strings, set, sorted-set, hashes, list
- Hyperloglog, bitmap, getspatial Index
- Stream
Only 1 Committer
- Redis는 Single Thread 기반으로 동작하기에 Atomicity를 보장한다고 한다.
redis collection 중 string, set, hash, list 등은 어느 정도 알고 있다고 가정한다.
sorted set은 자료의 중복을 허용하지 않는 set의 형태를 지님과 동시에 정렬되어 있다는 특성이 있다. sorted set은 redis를 사용하는 개발자에게 특히나 자주 사용되는 녀석이다.
기본 사용법으로는 다음과 같다.
ZADD <KEY><SCORE> <VALUE>
- Value가 이미 key에 있으면 해당 Score로 변경된다.
ZRANGE <KEY> <StartIndex> <EndIndex>
- 해당 Index 범위 값을 모두 조회한다.
- Zrange testkey 0 -1
: 모든 범위를 가져온다.
유저 랭킹 보드로 사용할 수 있다.
Sorted set의 score는 정수형이 아닌 double(실수) 타입이기 때문에, 값이 정확하지 않을 수 있다. (실수를 할 수 있다) -> 컴퓨터에는 실수가 표현할 수 없는 정수값들이 존재한다.
정렬이 필요한 값이 필요하거나, Score 기준으로 뽑을 수도 있다. 자세한 사용법으로는 찾아보자...🙇♂️
Cache의 Write Through와 Write back에 대해 간단하게 짚고 넘어가자.
Write Through는 데이터를 캐시에 저장함과 동시에 memory 혹은 disk에 동시에 update하는 방식이며, 데이터의 일관성을 유지할 수 있다는 장점이 있다.
하지만, 속도가 느린 memory 혹은 disk에 데이터를 기록할 때, CPU가 대기하는 시간이 필요하기에 성능이 떨어진다.
Write back은 캐시로부터 해제되는 때(캐시안에 있는 내용을 버릴시) 에만 memory 혹은 disk에 기록되는 방식이다. write through보다 훨씬 빠르다는 장점이 있지만, 데이터의 일관성을 항상 보장 못한다.
개발의 편의성이 상승하고 개발의 난이도가 낮아진다.
개발의 편의성
- 예를 들어, 랭킹 서버를 구현한다고 해보자. 기존 관계형 데이터베이스를 사용할 경우, DB에 유저의 Score를 저장하고, Score를 order by를 사용하여 정렬 후 읽어올 것이다.
- 개수가 많아진다면 결국 속도가 느린 디스크 I/O가 일어나기에 퍼포먼스에 영향을 주게 될 것이다.
- In-Memory DB를 이용한다면 조금 더 쉽게 만들 수 있다.
- Redis의 Sorted Set을 이용하면, 랭킹을 구현 할 수 있다.
개발의 난이도
Redis는 자료구조가 Atomic 하기 때문에, Race Condition을 피할 수 있으나, 잘못 짤 경우 에러가 발생할 수도 있다.
외부의 Collection을 잘 이용하는 것으로 여러가지 개발 시간을 단축시키고 문제를 줄여줄 수 있기 때문에 Collection이 중요하다.
하나의 컬렉션에 너무 많은 아이템을 담으면 좋지 않다.
- 10000개 이하의 몇천개 수준으로 유지하는게 좋다.
Expire는 Collection의 Item 개별로 걸리지 않고 전체 collection에 대해서만 걸린다.
- 즉 해당 10000개의 아이템을 가진 collection에 expire가 걸려있다면 그 시간 후에 10000개의 아이템이 모두 삭제된다.
- 개별로 걸 수 있는 방법도 존재하지만, 효율상 좋지 못하다고 한다.
Remote Data Store
- 서버 A, 서버 B, 서버 C에서 데이터를 공유하고 싶을 때
한 대에서만 필요하다면, 전역 변수를 쓰면 되지 않을까?
- Redis 자체가 싱글 스레드이기에 Atomic을 보장해준다.
주로 많이 쓰는 곳들
- 인증 토큰 등을 저장(Strings 또는 hash)
- Ranking 보드로 사용(Sorted Set)
- 유저 API Limit
- 잡 큐(list)
Redis는 In-Memory Data Store이다. 이에 유의하여 읽어보자.
Physical Memory 이상을 사용하면 문제가 발생한다.
- 예를 들어, Swap이 있다면 Swap 사용으로 해당 메모리 Page 접근시 마다 늦어진다. Swap이 한번 이상이라도 일어난 page는 지속적으로 swap이 일어난다.
- 즉, In-memory의 장점을 살리지 못하고 disk i/o가 지속적으로 일어나는 것이다.
Maxmemory를 설정하더라도 이보다 더 사용할 가능성이 크다.
- jemalloc에 대해서 알아두자.
RSS 값을 모니터링 해야한다.
RSS?
RSS(Really Simple Syndication, Rich Site Summary)란 블로그처럼 컨텐츠 업데이트가 자주 일어나는 웹사이트에서, 업데이트된 정보를 쉽게 구독자들에게 제공하기 위해 XML을 기초로 만들어진 데이터 형식
많은 업체가 현재 메모리를 사용해서 Swap을 쓰고 있다는 것을 모를 때가 많다.
큰 메모리를 사용하는 instance 하나보다는 적은 메모리를 사용하는 instance 여러 개가 안전하다.
- 예를 들어, 24GB의 instance를 하나 사용하는 것보다 8GB Instance를 3개 사용하는 것이 낫다.
- read 연산에는 문제가 없지만, write가 무거울 경우 메모리를 더 사용 할 경우가 있다.
다양한 사이즈를 가지는 데이터 보다는 유사한 크기의 데이터를 가지는 경우가 더욱 유리하다.
기본적으로 Collection 들은 다음과 같은 자료구조를 사용한다.
Ziplist를 이용해야 한다.
Redis는 single thread이다. 즉, 한번에 하나의 명령을 수행한다는 것인데, packet으로 하나의 command가 완성되면 processCommand에서 실제로 실행된다.
그렇다면, Redis가 동시에 여러 개의 명령이나 긴 시간이 필요한 명령을 처리할 수 있을까? 참고로 단순한 get/set의 경우, 이는 CPU 속도에향을 받기에 초당 10만 TPS(transaction per second) 이상이 가능하다고 한다.
정답으로는, 사용할 수는 있지만 지양한다고 한다. 대표적인 O(N) 명령어들은 다음과 같다.
대표적인 실수 사례로는 다음과 같다.
Key가 백만개 이상인데 확인을 위해 KEYS 명령을 사용하는 경우
- KEYS는 한번에 모든 데이터를 다 가져온다.
- scan 명령을 권장한다. scan 명령을 사용하는 것으로 하나의 긴 명령을 짧은 여러번의 명령으로 바꿀 수 있다.
아이템이 몇 만개 든 hash, sorted set, set에서 모든 데이터를 가져오는 경우
- Sorted set을 이용하여 Collection의 일부만 가져오거나, 큰 Collection을 작은 여러 개의 Collection으로 나눠서 관리해야 한다.
복제를 의미하는 Replication은 master server와 slave server를 필요로 한다. 여기서 master server는 주로 read/write 용이고, slave server는 master의 데이터를 미러링 하는 read 전용이다.
서비스를 제공하던 master server가 다운되더라도, slave server에서 서비스를 계속해서 진행할 수 있다. (failover)
redis replication은 async replication으로 replication lag이 발생할 수 있다.
DBMS로 보면 statement replication과 유사하다.
replicaof
or slaveof
명령을 전달한다.redis-cli --rdb
명령은 현재 상태의 메모리 스냅샷을 가져오므로 메모리 부족이 발생한다.데이터의 특성에 따라서 선택할 수 있는 방법이 달라진다.
Cache일 때는 이상적인 Redis이지만, 저장하는 데이터가 영속적이라면 효율성이 좋지 않은 redis가 된다.
Application에서 나눌 것이냐 Redis Cluster에서 나눌 것이냐에 따라 다르다.
Redis Cluster는 Hash 기반으로 16384개의 Slot으로 구분된다.
장점
- 자체적인 Primary, Secondary Failover
- Slot 단위의 데이터 관리
단점
- 메모리 사용량이 더 많음
- Migration 자체는 관리자가 시점을 결정해야 함
- Library 구현이 필요함
Redis에서 장애를 극복하는 방법들은 다음과 같다.
자세한 동작 방법은 찾아보자...!
Coordinator 기반으로 설정을 관리한다면 동일한 방식으로 관리가 가능하며, 해당 기능을 이용하도록 개발이 필요하다.
Zookeeper, etcd, consul 등의 Coordinator을 사용한다.
특징은 다음과 같다.
TTL(Time to live)
TTL은 다음 레코드 변경사항이 적용될 때까지 걸리는 시간(초)을 결정하는 DNS 레코드 값입니다.
REF.