2025 01 03
2025-01-03¶
Redis¶
참고: https://devocean.sk.com/search/techBoardDetail.do?ID=165057
- 개요
- 오픈소스, 인메모리 데이터 저장소
- 용도 : DB, 캐시, 스트리밍엔진, 메세지 브로커
- 구성에 따른 구분
- 단일 모드(standalone)
- 간단한 설치 및 개발
- 어플리케이션이 하나의 Redis에 데이터 읽고 씀

- Master-Slave 복제모드
- 읽기 성능 확장 필요 시
- 데이터 쓸 때엔 Master, 읽을 땐 Slave
- 읽기 성능 늘리기 위해서 Slave 노드 추가하기도 함

- Cluster 모드
- 대규모 데이터 운용하기 위함
- 기본 6개의 노드 (클러스터 구성 위한 최소 단위는 6개)
- 3개의 Master, 3개의 Slave로 구성
- 단일 모드(standalone)
-
Multi Key Operation
- 한번의 명령에 여러 키 동시 전달 처리
- 단일 노드 문제 없음
- 클러스터에서는 키들이 서로 다른 노드에 있으면 한번에 처리 어려움
- Redis Cluster는 키들을 슬롯 단위로 나눠 각 노드에 분산 저장
- 명령어
pexpire: 키 만료시간을 밀리초 단위로 설정. (Expire는 초 기준)lpush: 리스트의 왼쪽에 값 추가lrange: 리스트의 지정된 범위의 요소 반환lpop: 리스트의 왼쪽 요소 제거하고 반환blpop: lpop의 블로킹 버전. 리스트가 비어있다면 지정된 시간동안 대기하다가 요소 추가시 그 요소 제거하고 반환sadd: Set에 하나 이상 멤버 추가, 없다면 새로운 Set 생성srem: Set에 지정된 멤버 제거zadd: Sorted Set에 하나 이상의 멤버와 그에 해당하는 점수 추가
Redis Cluster¶
참고: https://co-de.tistory.com/24
참고: https://jaehoney.tistory.com/328
- 샤딩의 문제점
- key % 3 이런식으로 연산 때려버리면... 샤드 늘어날 때 마다 데이터 전혀 다른곳으로 이동해야 함
- Redis는 16384개의 해시 슬롯으로 키 공간 나눠서 관리
- CRC16 해싱 % 16384 -> 해시 슬롯 매핑
- 개요
- Redis Cluster 특징 : master 여러개 두어 분산 저장 가능하며, Sharding/Scale out 가능
- Master 하나 이상의 Slave 둘 수 있음
- Slave가 죽어서 복제 노드가 없는 마스터가 생긴다면, 다른 마스터 노드에 여유분이 있다면 해당 노드로 빈자리 채울 수 있음
- Master가 죽으면 Slave가 Master로 자동 failover
- 여러 노드에 자동적인 데이터 분산
- 일부 노드의 실패나 통신 단절에도 계속 작동하는 가용성
- 고성능 보장, 선형 확장성 제공

- 특징
- full-mesh 구조 통신
- cluster bus 추가 채널 사용
- gossip protocol : 근처 노드 통신
- Multi key 명령어가 제한됨
- 클라이언트는 모든 노드에 접속?
- 데이터 분산
- hash slot (각 키 해싱 후 모듈러 연산해 매핑)
- CRC16 해싱 후 모듈러 연산으로 16384개의 해시 슬롯 중 하나로 매핑
- 클라이언트 데이터 접근
- hash slot (각 키 해싱 후 모듈러 연산해 매핑)
- 클러스터 제약 사항
- 클러스터는 DB 0 만 사용 가능
- Redis는 한 인스턴스에 여러 데이터베이스를 가질 수 있으며 디폴트는 16
- 이는 용도별로 분리하여 관리를 용이하게 하기 위한 목적
- 하지만, 클러스터에서는 해당 기능 사용 못하고 DB 0으로 고정
- Multi key operation 사용 제약
- key들이 각각 다른 노드에 저장 -> MSET 등 multi-key operation 사용 X
- 클러스터는 DB 0 만 사용 가능
redisclient.debasishg.net > RedisClient¶
참고: https://github.com/debasishg/scala-redis
- 레디스 클러스터 환경에 연결/명령 실행하자
- 특징
- 클러스터 노드 정보 관리 : Redis 클러스터에 여러 노드(호스트/포트)를 등록
- 키 태그 설정 : 키-슬롯 매핑 효율적으로 제어하기 위함
- 클러스터 명령 라우팅
Redis Pub/Sub¶
참고: https://lucas-owner.tistory.com/60
참고: https://oliveyoung.tech/2023-08-07/async-process-of-coupon-issuance-using-redis/
참고: https://medium.com/frientrip/pub-sub-%EC%9E%98-%EC%95%8C%EA%B3%A0-%EC%93%B0%EC%9E%90-de9dc1b9f739
- 개요
- Message Queue 패턴 중에 하나
- 채팅/푸시/구독 시스템에 사용
- 수신 확인, 메시지 저장이 필요하지 않다면, 사용하기 좋다. (In-memory라 속도 빠름)
- vs Kafka
- Kafka는 Topic에 publish 되는 메시지를 저장하지만, Redis는 publish 메시지 저장하지 않음
- Redis에 subscriber 존재하지 않으면 메시지 사라짐
- pub/sub


- 특정 주제를 구독한 구독자에게 메시지를 발행하는 방식
- 레디스는 인메모리라서 웹 소켓을 사용하는 네트워크 방식보다 매우 빠름
- Redis Pub/Sub 순서
- Redis는 Topic 따로 생성하지 않고, Subscribe가 Topic을 구독하면 Topic이 생성
- Pub/Sub 순서
- Subscriber가 특정 Topic 구독
- 클라이언트가 특정 Topic에 pub
- Topic을 구독하는 Subscriber 들이 메시지 수신
- 명령어
- Subscriber는 계속 커넥션을 잡고 있어야 하나?
- Redis Pub/Sub에서도 Redis 클라/서버 간 사용되는 RESP(Redis Serialization Protocol) 사용
- Subscriber 입장에서 지속적으로 Redis 서버와 TCP 연결을 유지해야 실시간 수신 가능
- 이는 Pub/Sub에서 자연스러운 동작
- 프로토콜
- RESP(버전에 따라 RESP2/RESP3) 텍스트 기반의 경량 프로토콜
- 별도 MQTT, AMQP와 같은 복잡한 메시징 프로토콜이 아니라, Redis 고유 프로토콜
- Redis 서버나 클라이언트 사용에 특별한 설정 X
- 성능/부하
- 지속 연결로 인한 과부하 X
- 매우 가벼운 오버헤드를 가지고 수많은 구독자 연결
- 메시지 처리량 이슈
- Redis Pub/Sub은 브로커 역할이라, Redis에서 메시지 받아서 바로 모든 Subscriber에게 전송
- 매우 빈번하거나 대량이라면, Redis 서버의 네트워크 대역폭, CPU 부하가 문제될 수 있음
- 일반적인 규모로는 Redis 단일로도 충분
- Scale Out
- 트래픽 기하급수적으로 늘어나면 Redis 클러스터 구성을 통해 분산 처리 가능
- Pub/Sub보다 고급 기능 (메시지, ack, reprocessing)에서는 Redis Stream, Kafka 등의 메시징 시스템 고려도 함
- 지속 연결로 인한 과부하 X
Scala 2.11 라이브러리를 Scala 2.13에서 쓰면 안 되는 이유¶
- 개요
- 스칼라는 마이너 버전(2.11, 2.12, 2.13)간의 바이너리 호환성을 보장하지 않음
- 스칼라 2.11로 컴파일된 라이브러리는 내부적으로 스칼라 2.11 표준 라이브러리와 컴파일러 구현 디테일에 의존
- 스칼라 2.13에서 이거 그대로 쓰면 런타임 시점에 충돌
- 구체적인 이유
- 표준 라이브러리 변경됨
- 스칼라 2.11에서 사용되던 컬렉션/메서드/API가 스칼라 2.13에서 삭제/시그니처 변경되었을 수 있음
- NoSuchMethodError, ClassNotFoundError 등장하기 좋음
- 매크로/컴파일러 내부 구현 차이
- 컴파일러 내부 구조, 트리 구조가 바뀌어 호환되지 않는 경우가 많음
- 바이너리 호환성 미보장
- 자바는 메이저 버전간 바이너리 호환성이 깨져?
- SBT나 Maven, Gradle 등에서 충돌
- 표준 라이브러리 변경됨