728x90
반응형

Redis 동시성 처리

동시성 이슈

  • 데이터 불일치
    • 여러 스레드가 동시에 동일한 데이터를 수정
  • 데드락 (Deadlock)
    • 두 개 이상의 스레드가 서로의 자원을 기다리다가 멈추는 상태
  • 라이브락 (Livelock)
    • 스레드가 락을 반복적으로 획득하려다 아무런 진전이 없는 상태
  • 경쟁 조건
    • 동시에 자원에 접근하여 예상하지 못한 결과가 발생하는 상태

=> 동시성 제어(: 멀티스레드 환경에서 일관된 데이터 처리를 보장하는 방법) 필요


동시성 제어 기법

  • 락(Lock)
    • 한 스레드가 자원을 사용하는 동안 다른 스레드가 해당 자원에 접근하지 못하도록 막는 기법
    • Mutex (Mutual Exclusion): 가장 기본적인 락/ 하나의 스레드만 자원에 접근할 수 있도록 보장
    • Reentrant Lock: 동일한 스레드가 여러 번 락을 획득할 수 있는 락
  • 세마포어(Semaphore)
    • 제한된 개수의 스레드만 자원에 접근할 수 있도록 제한하는 제어 기법
    • 락: 한 스레드만 자원에 접근세마포어: 여러 개의 스레드 동시에 자원 접근
  • 모니터(Moniter)
    • 특정 코드 블록이나 메서드에 한 번에 한 스레드만 접근할 수 있도록 하는 방식
    • ex. Java의 synchronized 키워드
  • 원자적 연산 (Atomic Operation)
    • 중단 없이 한 번에 실행되는 연산
  • Volatile 키워드
    • 변수 값이 스레드 간에 일관성을 유지할 수 있도록 함
    • 주로 간단한 플래그 변수에서 사용, 캐시를 사용 X 모든 스레드가 메인 메모리에서 값을 읽도록 보장
  • 트랜잭션 메모리 (Transactional Memory)
    • 메모리 접근을 트랜잭션으로 관리 → 모든 연산이 성공적으로 완료 or 전혀 적용되지 않도록 보장하는 방식
  • 비동기 프로그래밍
    • 스레드가 자원에 접근하는 방식 자체를 설계적으로 피함

Redis는 기본적으로 싱글 스레드로 동작

이벤트 루프 기반의 싱글 스레드 모델 사용

→ 하나의 명령어를 처리하는 동안 다른 명령어가 끼어들지 못함

=> 동시성 문제가 발생할 가능성 ↓ 데이터 일관성 유지

  • 싱글 스레드 모델
    • 하나의 명령 처리할 때 다른 명령 처리 X → 명령어가 순차적으로 실행
      = 같은 자원에 대해 동시에 여러 명령이 처리 X → 데이터 충돌이나 레이스 컨디션 문제를 자연스럽게 방지
  • 빠른 속도
    • 싱글 스레드로 동작 But, 인메모리 데이터베이스→ 매우 빠른 응답 시간 제공

동시성 보완 방법

  • I/O 멀티플렉싱
    • I/O 작업 처리할 때 비동기 I/O 멀티플렉싱 기술 사용→ 여러 클라이언트의 요청을 동시에 비동기적으로 처리
      • epoll, select, kqueue
  • 파이프라이닝(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
    • 애플리케이션에서 연결 정보 변경
  • (+) 설정이 간단하고 읽기 성능 향상을 기대
  • (-) 마스터 장애 시 수동 복구가 필요하며, 쓰기 성능은 제한적

Sentinel

: 자동 페일오버 가능한 HA 구성

  • sentinel 노드가 다른 노드 감시
  • 마스터가 비정상 상태일 때 자동으로 페일오버
  • 연결 정보 변경 필요 없음
  • sentinel 노드는 항상 3대 이상의 홀수로 존재해야 함
    • 과반수 이상의 sentinel이 동의해야 페일오버 진행
  • (+) 자동 장애 조치 및 고가용성을 제공, 읽기 작업을 슬레이브로 분산할 수 있음
  • (-) 설정이 복잡하고 수평 확장이 불가

Cluster 구성

: 스케일 아웃과 HA 구성

  • 키를 여러 노드에 자동으로 분할해서 저장(샤딩)
    • 샤딩(Sharding): 데이터를 여러 서버나 노드에 분산하여 저장하는 방법/ 데이터베이스 확장성/ 클러스터 내에서 각 노드는 전체 데이터의 일부만 저장, 데이터를 요청할 때 요청이 해당 노드로 라우팅
  • 모든 노드가 서로를 감시하며, 마스터 비정상 상태일 때 자동 페일오버
  • 최소 3대의 마스터 노드가 필요
  • (+) 수평 확장성과 고가용성을 제공, 대규모 시스템에 적합
  • (-) 설정과 관리가 복잡하고 일부 명령어가 제한


출처

 

728x90
반응형
김앩옹