Redis 동시성 처리
동시성 이슈
- 데이터 불일치
- 여러 스레드가 동시에 동일한 데이터를 수정
- 데드락 (Deadlock)
- 두 개 이상의 스레드가 서로의 자원을 기다리다가 멈추는 상태
- 라이브락 (Livelock)
- 스레드가 락을 반복적으로 획득하려다 아무런 진전이 없는 상태
- 경쟁 조건
- 동시에 자원에 접근하여 예상하지 못한 결과가 발생하는 상태
=> 동시성 제어(: 멀티스레드 환경에서 일관된 데이터 처리를 보장하는 방법) 필요
동시성 제어 기법
- 락(Lock)
- 한 스레드가 자원을 사용하는 동안 다른 스레드가 해당 자원에 접근하지 못하도록 막는 기법
- Mutex (Mutual Exclusion): 가장 기본적인 락/ 하나의 스레드만 자원에 접근할 수 있도록 보장
- Reentrant Lock: 동일한 스레드가 여러 번 락을 획득할 수 있는 락
- 세마포어(Semaphore)
- 제한된 개수의 스레드만 자원에 접근할 수 있도록 제한하는 제어 기법
- 락: 한 스레드만 자원에 접근세마포어: 여러 개의 스레드 동시에 자원 접근
- 모니터(Moniter)
- 특정 코드 블록이나 메서드에 한 번에 한 스레드만 접근할 수 있도록 하는 방식
- ex. Java의 synchronized 키워드
- 원자적 연산 (Atomic Operation)
- 중단 없이 한 번에 실행되는 연산
- Volatile 키워드
- 변수 값이 스레드 간에 일관성을 유지할 수 있도록 함
- 주로 간단한 플래그 변수에서 사용, 캐시를 사용 X 모든 스레드가 메인 메모리에서 값을 읽도록 보장
- 트랜잭션 메모리 (Transactional Memory)
- 메모리 접근을 트랜잭션으로 관리 → 모든 연산이 성공적으로 완료 or 전혀 적용되지 않도록 보장하는 방식
- 비동기 프로그래밍
- 스레드가 자원에 접근하는 방식 자체를 설계적으로 피함
Redis는 기본적으로 싱글 스레드로 동작
이벤트 루프 기반의 싱글 스레드 모델 사용
→ 하나의 명령어를 처리하는 동안 다른 명령어가 끼어들지 못함
=> 동시성 문제가 발생할 가능성 ↓ 데이터 일관성 유지

- 싱글 스레드 모델
- 하나의 명령 처리할 때 다른 명령 처리 X → 명령어가 순차적으로 실행
= 같은 자원에 대해 동시에 여러 명령이 처리 X → 데이터 충돌이나 레이스 컨디션 문제를 자연스럽게 방지
- 하나의 명령 처리할 때 다른 명령 처리 X → 명령어가 순차적으로 실행
- 빠른 속도
- 싱글 스레드로 동작 But, 인메모리 데이터베이스→ 매우 빠른 응답 시간 제공
동시성 보완 방법
- I/O 멀티플렉싱
- I/O 작업 처리할 때 비동기 I/O 멀티플렉싱 기술 사용→ 여러 클라이언트의 요청을 동시에 비동기적으로 처리
- `epoll`, `select`, `kqueue`
- I/O 작업 처리할 때 비동기 I/O 멀티플렉싱 기술 사용→ 여러 클라이언트의 요청을 동시에 비동기적으로 처리
- 파이프라이닝(Pipelineing)
- 여러 명령을 한 번에 서버로 보내고 응답을 비동기적으로 받을 수 있음 → 성능 향상시킬 수 있음
=> 싱글 스레드 모델로 동시성 문제 해결 + 데이터 일관성 유지, 빠른 성능을 제공
But, Redis 6.0 이후
네트워크 I/O 작업에서 멀티스레드 활용 → 성능 추가적으로 개선

Redis 4.0 부터는 기본적으로 4개의 스레드로 동작
But, 일반 명령어 처리하는 메인스레드 1개 + 별도의 시스템 명령어 사용하는 전용 sub 스레드 3개
Redis 6.0부터 ThreadedIO가 추가 → 사용자 명령 멀티스레드 지원
But, 명령어를 실행하는 코어 부분 여전히 single thread로 동작
I/O Socket read/write할 때 멀티스레드로 동작 => 전반적인 성능 향상
아키텍처 종류
Replication
: 단순한 복제 연결
- replicaof 커맨드를 이용해 간단하게 복제 연결
- 비동기식 복제
- HA 기능 X → 장애 상황 시 수동 복구
- 고가용성(High Availability): 시스템이 장애 발생 시에도 지속적으로 서비스가 가능하도록 하는 기술적 개념
/ 특정 노드나 서비스가 다운되더라도, 다른 노드가 이를 대체
→ 서비스 중단 시간을 최소화, 데이터 접근이 가능한 상태를 유지하는 것을 목표 - replicaof no one
- 애플리케이션에서 연결 정보 변경
- 고가용성(High Availability): 시스템이 장애 발생 시에도 지속적으로 서비스가 가능하도록 하는 기술적 개념
- (+) 설정이 간단하고 읽기 성능 향상을 기대
- (-) 마스터 장애 시 수동 복구가 필요하며, 쓰기 성능은 제한적
Sentinel
: 자동 페일오버 가능한 HA 구성
- sentinel 노드가 다른 노드 감시
- 마스터가 비정상 상태일 때 자동으로 페일오버
- 연결 정보 변경 필요 없음
- sentinel 노드는 항상 3대 이상의 홀수로 존재해야 함
- 과반수 이상의 sentinel이 동의해야 페일오버 진행
- (+) 자동 장애 조치 및 고가용성을 제공, 읽기 작업을 슬레이브로 분산할 수 있음
- (-) 설정이 복잡하고 수평 확장이 불가
Cluster 구성
: 스케일 아웃과 HA 구성
- 키를 여러 노드에 자동으로 분할해서 저장(샤딩)
- 샤딩(Sharding): 데이터를 여러 서버나 노드에 분산하여 저장하는 방법/ 데이터베이스 확장성/ 클러스터 내에서 각 노드는 전체 데이터의 일부만 저장, 데이터를 요청할 때 요청이 해당 노드로 라우팅
- 모든 노드가 서로를 감시하며, 마스터 비정상 상태일 때 자동 페일오버
- 최소 3대의 마스터 노드가 필요
- (+) 수평 확장성과 고가용성을 제공, 대규모 시스템에 적합
- (-) 설정과 관리가 복잡하고 일부 명령어가 제한


출처
'💻 > 데이터베이스' 카테고리의 다른 글
Memcached vs. Redis (0) | 2025.02.24 |
---|---|
Pessimistic Lock(비관적 락) vs. Optimistic Lock(낙관적 락) (0) | 2025.02.23 |
Trigger & Procedure (0) | 2025.02.23 |
[Real MySQL 8.0 1] 0.7 데이터 암호화 (0) | 2025.01.27 |
[Real MySQL 8.0 1] 0.6. 데이터 압축 (0) | 2025.01.27 |
Redis 동시성 처리
동시성 이슈
- 데이터 불일치
- 여러 스레드가 동시에 동일한 데이터를 수정
- 데드락 (Deadlock)
- 두 개 이상의 스레드가 서로의 자원을 기다리다가 멈추는 상태
- 라이브락 (Livelock)
- 스레드가 락을 반복적으로 획득하려다 아무런 진전이 없는 상태
- 경쟁 조건
- 동시에 자원에 접근하여 예상하지 못한 결과가 발생하는 상태
=> 동시성 제어(: 멀티스레드 환경에서 일관된 데이터 처리를 보장하는 방법) 필요
동시성 제어 기법
- 락(Lock)
- 한 스레드가 자원을 사용하는 동안 다른 스레드가 해당 자원에 접근하지 못하도록 막는 기법
- Mutex (Mutual Exclusion): 가장 기본적인 락/ 하나의 스레드만 자원에 접근할 수 있도록 보장
- Reentrant Lock: 동일한 스레드가 여러 번 락을 획득할 수 있는 락
- 세마포어(Semaphore)
- 제한된 개수의 스레드만 자원에 접근할 수 있도록 제한하는 제어 기법
- 락: 한 스레드만 자원에 접근세마포어: 여러 개의 스레드 동시에 자원 접근
- 모니터(Moniter)
- 특정 코드 블록이나 메서드에 한 번에 한 스레드만 접근할 수 있도록 하는 방식
- ex. Java의 synchronized 키워드
- 원자적 연산 (Atomic Operation)
- 중단 없이 한 번에 실행되는 연산
- Volatile 키워드
- 변수 값이 스레드 간에 일관성을 유지할 수 있도록 함
- 주로 간단한 플래그 변수에서 사용, 캐시를 사용 X 모든 스레드가 메인 메모리에서 값을 읽도록 보장
- 트랜잭션 메모리 (Transactional Memory)
- 메모리 접근을 트랜잭션으로 관리 → 모든 연산이 성공적으로 완료 or 전혀 적용되지 않도록 보장하는 방식
- 비동기 프로그래밍
- 스레드가 자원에 접근하는 방식 자체를 설계적으로 피함
Redis는 기본적으로 싱글 스레드로 동작
이벤트 루프 기반의 싱글 스레드 모델 사용
→ 하나의 명령어를 처리하는 동안 다른 명령어가 끼어들지 못함
=> 동시성 문제가 발생할 가능성 ↓ 데이터 일관성 유지

- 싱글 스레드 모델
- 하나의 명령 처리할 때 다른 명령 처리 X → 명령어가 순차적으로 실행
= 같은 자원에 대해 동시에 여러 명령이 처리 X → 데이터 충돌이나 레이스 컨디션 문제를 자연스럽게 방지
- 하나의 명령 처리할 때 다른 명령 처리 X → 명령어가 순차적으로 실행
- 빠른 속도
- 싱글 스레드로 동작 But, 인메모리 데이터베이스→ 매우 빠른 응답 시간 제공
동시성 보완 방법
- I/O 멀티플렉싱
- I/O 작업 처리할 때 비동기 I/O 멀티플렉싱 기술 사용→ 여러 클라이언트의 요청을 동시에 비동기적으로 처리
epoll
,select
,kqueue
- I/O 작업 처리할 때 비동기 I/O 멀티플렉싱 기술 사용→ 여러 클라이언트의 요청을 동시에 비동기적으로 처리
- 파이프라이닝(Pipelineing)
- 여러 명령을 한 번에 서버로 보내고 응답을 비동기적으로 받을 수 있음 → 성능 향상시킬 수 있음
=> 싱글 스레드 모델로 동시성 문제 해결 + 데이터 일관성 유지, 빠른 성능을 제공
But, Redis 6.0 이후
네트워크 I/O 작업에서 멀티스레드 활용 → 성능 추가적으로 개선

Redis 4.0 부터는 기본적으로 4개의 스레드로 동작
But, 일반 명령어 처리하는 메인스레드 1개 + 별도의 시스템 명령어 사용하는 전용 sub 스레드 3개
Redis 6.0부터 ThreadedIO가 추가 → 사용자 명령 멀티스레드 지원
But, 명령어를 실행하는 코어 부분 여전히 single thread로 동작
I/O Socket read/write할 때 멀티스레드로 동작 => 전반적인 성능 향상
아키텍처 종류
Replication
: 단순한 복제 연결
- replicaof 커맨드를 이용해 간단하게 복제 연결
- 비동기식 복제
- HA 기능 X → 장애 상황 시 수동 복구
- 고가용성(High Availability): 시스템이 장애 발생 시에도 지속적으로 서비스가 가능하도록 하는 기술적 개념
/ 특정 노드나 서비스가 다운되더라도, 다른 노드가 이를 대체
→ 서비스 중단 시간을 최소화, 데이터 접근이 가능한 상태를 유지하는 것을 목표 - replicaof no one
- 애플리케이션에서 연결 정보 변경
- 고가용성(High Availability): 시스템이 장애 발생 시에도 지속적으로 서비스가 가능하도록 하는 기술적 개념
- (+) 설정이 간단하고 읽기 성능 향상을 기대
- (-) 마스터 장애 시 수동 복구가 필요하며, 쓰기 성능은 제한적
Sentinel
: 자동 페일오버 가능한 HA 구성
- sentinel 노드가 다른 노드 감시
- 마스터가 비정상 상태일 때 자동으로 페일오버
- 연결 정보 변경 필요 없음
- sentinel 노드는 항상 3대 이상의 홀수로 존재해야 함
- 과반수 이상의 sentinel이 동의해야 페일오버 진행
- (+) 자동 장애 조치 및 고가용성을 제공, 읽기 작업을 슬레이브로 분산할 수 있음
- (-) 설정이 복잡하고 수평 확장이 불가
Cluster 구성
: 스케일 아웃과 HA 구성
- 키를 여러 노드에 자동으로 분할해서 저장(샤딩)
- 샤딩(Sharding): 데이터를 여러 서버나 노드에 분산하여 저장하는 방법/ 데이터베이스 확장성/ 클러스터 내에서 각 노드는 전체 데이터의 일부만 저장, 데이터를 요청할 때 요청이 해당 노드로 라우팅
- 모든 노드가 서로를 감시하며, 마스터 비정상 상태일 때 자동 페일오버
- 최소 3대의 마스터 노드가 필요
- (+) 수평 확장성과 고가용성을 제공, 대규모 시스템에 적합
- (-) 설정과 관리가 복잡하고 일부 명령어가 제한


출처
'💻 > 데이터베이스' 카테고리의 다른 글
Memcached vs. Redis (0) | 2025.02.24 |
---|---|
Pessimistic Lock(비관적 락) vs. Optimistic Lock(낙관적 락) (0) | 2025.02.23 |
Trigger & Procedure (0) | 2025.02.23 |
[Real MySQL 8.0 1] 0.7 데이터 암호화 (0) | 2025.01.27 |
[Real MySQL 8.0 1] 0.6. 데이터 압축 (0) | 2025.01.27 |