레디스의 특징
싱글스레드, 인 메모리 구조, K-V 구조
싱글 스레드:
-> 싱글 스레드이기 때문에 복잡한 동시성 이슈나 락 경쟁을 피할 수 있으므로, 높은 성능을 유지할 수 있다.
-> DB 확장으로 인해 발생하는 동시성 문제를 레디스의 SETNX 명령어를 통해 락을 구현해 동시성을 제어할 수 있다.
인메모리 구조:
-> 빠른 데이터 액세스, 데이터 구조의 다양성을 만족 시킬 수 있다.
K-V 구조:
-> 간단하고 유연한 데이터 모델
캐싱 전략
1. 읽기 전략 Look-Aside(Lazy-loading)
1. 어플리케이션의 data를 요청
2. 레디스에서 조회
3. 조회 실패 시 직접 DB에 데이터를 요청
발생할 수 있는 문제점들:
- REDIS에 많은 커넥션이 몰려있는 상태라면 언제든 DB 커넥션으로 붙을 수 있기 때문에 HIT RATE를 고려해야한다.
고려해야 하는 사항들:
위의 문제 처럼 HIT RATE가 낮게 되면 빈번하게 DB 에 직접 데이터를 요청하기 때문에 캐시를 새로 투입하거나,
CACHE WARMING을 자주 해준다.
2. 쓰기 전략(Write-Around)
캐시 미스가 발생한 경우에만 캐시에 데이터를 저장한다.
3. 쓰기 전략(Write-Through)
DB에 저장할 때 캐시에도 같이 저장함.
문제점: 캐시 히트가 적은 데이터도 같이 올라가기 때문에 비효율적일 수 있다.
공통적으로 적용되는 해결법:
만료기한을 정해 데이터의 기한을 둔다.
레디스를 이용한 카운팅
- string
-> INCR, INCRBY
- bits
-> SETBIT, BITCOUNT
- HyperLogLogs
-> 대용량 데이터를 카운팅 할 때 적절
-> PFADD, PFCOUNT
메시지
- lists
-> blocking 기능을 이용해 이벤트 큐로 사용 가능하다.
-> 키가 있을 떄만 데이터 저장 가능
-> LPUSHX, RPUSHX는 키가 있을 때만 넣어줄 수 있음.
- streams
-> 로그를 저장하기 가장 적절한 자료 구조
-> append-only
-> 시간 범위로 검색 / 신규 추가 데이터 수신/ 소비자별 다른 데이터 수신(소비자 그룹)
-> XADD
카프카와 레디스의 차이점:
Apache Kafka | Redis | |
메시지 크기 | 압축 및 계층형 스토리지로 최대 1GB의 메시지 크기를 지원합니다. | 더 작은 메시지 크기를 지원합니다. |
메시지 전송 | 구독자는 대기열에서 메시지를 가져옵니다. | Redis 서버는 연결된 가입자에게 메시지를 푸시합니다. |
메시지 보존 | 검색 후 메시지를 보존합니다. | 메시지를 보관하지 않습니다. |
오류 처리 | 메시징 수준에서의 강력한 오류 처리. 배달 못한 편지 대기열, 이벤트 재시도 및 리디렉션. | 제한 시간, 클라이언트 제한 및 메모리 버퍼 용량을 사용하여 애플리케이션 수준에서 Redis 예외를 처리해야 합니다. |
병렬 처리 | Kafka는 병렬 처리를 지원합니다. 여러 소비자가 동일한 메시지를 동시에 검색할 수 있습니다. | 병렬 처리를 지원하지 않습니다. |
처리량 | 비동기 읽기/쓰기로 인해 처리량이 더 높습니다. | Redis 서버가 다른 구독자에게 메시지를 보내기 전에 회신을 기다려야 하기 때문에 처리량이 줄어듭니다. |
지연 시간 | 짧은 지연 시간. 기본적으로 데이터 복제로 인해 Redis보다 약간 느립니다. | 작은 크기의 메시지를 배포할 때 지연 시간이 매우 짧습니다. |
내결함성 | 파티션을 다른 브로커에 자동으로 백업합니다. | 기본적으로 백업되지 않습니다. 사용자는 Redis 지속성을 수동으로 활성화할 수 있습니다. 소규모 데이터 손실 위험. |
레디스 아키텍처 종류
replication 구성
단순한 복제 연결
복제본의 데이터를 넘겨준다.
HA 기능이 없으므로 장애 상황 시 수동 복구
sentinel 구성
자동 페일 오버 가능한 HA 구성(고 가용성)
- sentinel 노드가 다른 노드 감시
- 마스터가 비정상 상태일 때 자동으로 페일 오버
- 연결 정보 변경 필요 없음
- sentinel 노드는 항상 3대 이상의 홀수로 존재해야 함
- 과반수 이상의 sentinel이 동의해야 페일 오버 진행
cluster 구성
스케일 아웃과 HA 구성(고 가용성)
- 키를 여러 노드에 자동으로 분할해서 저장(샤딩)
- 모든 노드가 서로를 감시하여, 마스터 비정상 상태일 때 자동 페일오버
- 최소 3대의 마스터 노드가 필요
운영 팁
KEYS * -> SCAN으로 대체
- 키 나누기 ( 최대 100만개 )
- hgetall -> hscan
- del -> unlink (del로 키를 지우게 되면 아무것도 할 수 없기 때문에 백그라운드로 진행할 수 있게 해주는 unlink를 사용한다.)
STOP-WRTIES-ON-BGSAVE-ERROR = NO
- YES (DEFAULT)
- RDB 파일 저장 실패 시 redis로의 모든 write 불가능
MAXMEMORY-POLICY = ALLKEYS -LRU
- redis를 캐시로 사용할 때 expire time 설정 권장
- 메모리가 가득 찼을 때 MAXMEMORY-POLICY 정책에 의해 키 관리
- noeviction(default) : 삭제 안함
- volatile-lru
- allkeys-lru
++) 디폴트 값은 메모리가 가득 찼을 때 새로운 키를 저장하지 않는 것으로 되어 있어 변경해줘야 한다.
TTL을 너무 작게 설정한 경우 여러 어플리케이션에서 DB에 같은 데이터를 요청할 경우 duplicate keys가 발생한다.
MAX-MEMORY 값 설정
persistence / 복제 사용 시 MaxMemory 설정 주의
- RDB 저장 & AOF rewrite 시 fork()
- COPY-ON-WRITE로 인해 메모리를 두배로 사용하는 경우 발생 가능
- 따라서 MAX-MEMORY는 실제 메모리의 절반으로 설정해야함.
메모리 관리
USED_MEMORY: 논리적으로 REDIS가 사용하는 메모리
USED_MEMORY_RSS: OS가 REDIS에 할당하기 위해 사용한 물리적 메모리 양 -> 이걸 보는 게 더 중요하다.
-> OS가 실제로 얼마나 레디스에 메모리를 할당했는 지 보여준다.
RSS와 MEMORY의 차이가 클 때 fargmentation이 증가한다.
-> ttl로 인해 삭제되는 키가 많을 때 증가한다.
해결 방법으로는 config set activedefrag yes 를 통해 공식문서에서도 단편화가 많이 발생했을 때 켜두는 것을 권장하고 있다.
출처:
https://www.youtube.com/watch?v=92NizoBL4uA
https://aws.amazon.com/ko/compare/the-difference-between-kafka-and-redis/
'DB' 카테고리의 다른 글
[JPA] - 다양한 연관관계 매핑 (1) | 2024.01.10 |
---|---|
[JPA] - 연관관계 매핑 기초 (1) | 2024.01.09 |
[JPA] - 엔티티 매핑 (0) | 2024.01.08 |
[JPA] - 영속성 컨텍스트 (1) | 2024.01.05 |
[JPA] - JPA를 사용하는 이유 (0) | 2024.01.03 |