Redis ( Remote Dictionary Server )
오픈소스로 key-value 기반의 인-메모리 데이터 저장소이다. 따라서 key-value 기반이라 쿼리를 날릴 필요 없이 결과를 바로 가져올 수 있고 디스크에 데이터를 쓰는 구조가 아니라 메모리에서 데이터를 처리하기 때문에 속도가 매우 빠르다. (DB를 조회하는 것보다 빠르다.)
유명가수의 티케팅을 웹에서 한다고 가정해보자. 티켓팅이 열리는 순간 엄청난 양의 데이터가 DB에 쓰기 위해 몰리게 된다. 이때 DB 에러가 발생하여 결제가 되지 않는다면 엄청난 손해를 발생할 수 있다. 이때 해결책으로 레디스의 캐시를 사용한다. 하나씩 로직을 보자.
Look aside cache(조회 로직)을 보면, 클라이언트가 웹서버에 요청을 하면 웹서버는 먼저 Cache에서 데이터 존재 유무를 확인하다. 이때 Cache에 데이터가 있으면 바로 꺼내주고, 없다면 DB를 확인해서 Cache에 먼저 자장한 후에 클라이언트에게 데이터를 돌려준다.
Write Back(저장 로직)을 보면 클라이언트가 웹서버에 요청을 하면, 웹서버는 DB에 바로 저장을 하는 것이 아니라 Cache에 결과를 쓰고 바로 클라이언트에게 결과 값을 리턴해 준다. 그 후에 Cache 서버에 있는 데이터들을 Worker(워커) 서버들이 데이터를 가져와서 작업을 수행하고 DB에 작성한다. 이렇게 되면 DB는 순차적으로 Transaction을 처리할 수 있게 된다. 정리하면, 데이터를 캐시에 먼저 전부 저장해 둔 후에 특정 시점마다 캐시의 데이터를 DB에 insert 하는 방식이다. insert를 1개씩 500번 하는 것보다 500개를 한 번에 insert 하는 빠르고 성능이 좋다는 것을 알 수 있을 것이다.
캐시 서버는 속도를 위해서 주로 메모리를 사용하기 때문에 서버에 장애가 나면, 메모리가 날아가서 데이터 손실이 발생할 수 있다. 그래서 replication(복제 서버)을 구성하거나 disk를 사용해서 고가용성을 확보하기도 하지만, 비용적 문제가 크게 발생하거나 속도가 어느 정도 낮아질 수 있다는 문제점이 생긴다. 아래에서부터는 Cache 서버로 널리 사용되고 있는 redis에 대해서 알아보자.
Redis 사용 이유
- 데이터베이스는 데이터를 물리 디스크에 직접 쓰기 때문에 서버에 문제가 발생하여 다운되더라도 데이터가 손실되지 않음
- 하지만 매번 디스크에 접근하기 때문에 사용자가 많아질수록 부하 증가
- 이때 Cache Server를 도입하여 사용하고, Cache Server로 Redis를 이용할 수 있음
- Cache Server 사용 시 같은 요청에 매번 데이터베이스를 거치는 것이 아닌, Cache Server에서 첫 번째 요청 이후 저장된 결과값을 바로 반환
- 데이터베이스 부하 감소 가능, 서비스 속도 향상
Redis의 특징과 장점
- Key, Value 구조이기 때문에 쿼리를 사용할 필요가 없음
- 고정되지 않은 스키마를 가지므로 키마다 원하는 내용만 저장 가능
- In-Memory 데이터베이스
- 매우 빠름
- 서버 재시작 시 모든 데이터 유실
- 복제 기능이 있지만 사람의 실수에는 복원 불가
- 백업이 필요할 수 있음 (persist option 지원)
- 다양한 자료구조를 제공
- String, List, Hash, Set, Sorted Set, Stream 등
- 사용 용이, 개발 편의성 증대
- application 단에서 필요한 로직을 DB 단에서 줄일 수 있음
- list형 데이터 입력/삭제가 MySQL에 비해 10배 빠름
- Single Thread로 동작
- 한 번에 여러 클라이언트의 요청을 수행할 수 없음
- 한 클라이언트가 오래 걸리는 작업을 요청하면 장애가 발생할 수 있음
- 여러 대의 서버 구성 가능 (Master-Slave)
- Database, Cache, Message broker로 사용됨
- Cache로 사용 시 무조건 TTL로 사용. 시간 중요
Redis 장애 포인트
- Redis가 Single Thread임을 무시한 경우
- key *, flush all 커맨드 수행 시 반환 시간동안 다른 응답 불가
- centinel이 주기적으로 ping을 보내 장애 여부를 판단하는데 이때 장애로 판단할 수 있음
- keys * 대신 scan 0 커맨드를 사용해야 함
- key *, flush all 커맨드 수행 시 반환 시간동안 다른 응답 불가
- Hash나 Sort Set에서 데이터를 많이 저장할수록 느려짐
- 하나의 key에 너무 많은 데이터를 저장하지 않도록 한다
- 너무 짧은 timeout 값 설정
- 자주 갱신 되는 값이 아니라면 갱신 시간 늘리기
- PER (Probabilistic Early Recomputation) 알고리즘 도입
'Study > 개발일지' 카테고리의 다른 글
[백엔드TIL] 세션과 토큰그리고 인증과 인가 (69일차) (0) | 2023.09.05 |
---|---|
[백엔드TIL] 시간복잡도에 대한 이해 (68일차) (0) | 2023.09.04 |
[백엔드TIL] 공간복잡도에 대한 이해 (67일차) (0) | 2023.09.01 |
[백엔드TIL] Https, SSL에 대한 이해 (66일차) (0) | 2023.08.31 |
[백엔드TIL] 객체지향 프로그래밍 (66일차) (0) | 2023.08.30 |