Redis 스레딩 모델: 단일 스레드 신화 깨기

발행: (2025년 12월 25일 오전 08:41 GMT+9)
9 min read
원문: Dev.to

I’m happy to help translate the article, but I’ll need the full text you’d like translated. Could you please paste the content (excluding the source line you’ve already provided) here? Once I have it, I’ll translate it into Korean while preserving the original formatting, markdown, and code blocks.

Redis는 “Single‑Threaded”. Or Is It?

  • EventStreamMonitor 프로젝트를 구축하면서 배운 점 (≈5 년 전).*

TL;DR

  • Command execution(SET, GET 등)의 핵심 작업은 single thread에서 실행됩니다.
  • Everything else – 디스크 I/O, lazy freeing, 네트워크 I/O, RDB 스냅샷 – 은 background threads를 사용할 수 있습니다.
  • 이러한 설계 선택 덕분에 Redis는 전설적인 속도, 단순성, 그리고 예측 가능성을 갖게 됩니다.

1. 단일 스레드무엇인가?

영역무슨 일이 일어나는가단일 스레드가 유지되는 이유
명령 실행실제 Redis 명령(SET, GET, LPUSH, …)을 실행원자성을 보장하고 락 경쟁을 없앱니다.
메인 이벤트 루프연결을 수락하고, 요청을 파싱하며, 명령을 디스패치합니다전체 서버를 하나의 코어에서 실행시켜 컨텍스트 스위치를 방지합니다.
데이터 구조 접근메모리 내 객체(해시, 리스트, 정렬된 집합, …)를 읽고 씁니다락이 없으므로 경쟁 조건이 없고, CPU 캐시 지역성이 향상됩니다.

2. 멀티‑스레드란 무엇인가?

하위 시스템스레드 사용시작 시점
디스크 백그라운드 I/O (fsync, 파일 닫기)전용 “bio” 스레드초기 Redis 버전 (bio.c 사용).
지연 해제 (메모리 회수)백그라운드 스레드가 큰 객체를 해제Redis 4.0.
네트워크 I/O (소켓 읽기/쓰기)선택적 I/O 스레드 풀Redis 6.0.
RDB 스냅샷 (포크 기반 백업)자식 프로세스가 무거운 작업을 수행하고, 부모는 정리 작업을 위해 백그라운드 스레드를 사용할 수 있음항상 (포크) + 백그라운드 I/O.

핵심 요점: Redis는 가장 중요한 부분(명령 실행)에 대해 대부분 단일 스레드이지만, 명확한 이점이 있는 경우 스레드를 생성합니다.

3. 단일 스레드가 실제로 더 빠른 이유

  1. 잠금 오버헤드 없음

    • 경쟁이 없는 잠금은 약 100‑1 000 CPU 사이클이 소요됩니다.
    • 경쟁이 있는 잠금은 >10 000 사이클이 될 수 있습니다.
    • 잠금을 피함으로써 Redis는 이 비용을 완전히 없앱니다.
  2. CPU‑캐시 활용도 향상

    • L1‑캐시 접근 ≈ 1 ns vs. 메인‑메모리 60‑100 ns.
    • 단일 스레드는 핫 데이터를 캐시 안에 오래 유지해 메모리 지연을 줄입니다.
  3. 컨텍스트‑스위칭 없음

    • 스레드 전환 시 OS가 레지스터, 스택 등을 저장/복원해야 합니다.
    • 단일 스레드는 지속적으로 실행되어 그 오버헤드를 피합니다.

4. “Race conditions can’t happen with Redis” – 무엇이 사실인가?

  • 개별 명령은 원자적이다.
    단일 SET, GET, INCR, … 은 다른 명령이 실행되기 전에 완전히 끝난다.

  • 명령 시퀀스는 원자적이지 않다.
    MULTI/EXEC 를 사용하거나 여러 명령을 연속으로 실행하면, 다른 클라이언트가 그 사이에 명령을 끼어들 수 있다. 공식 문서에서도 이를 경고하고 있다.

  • 블로킹 명령(예: BLPOP)은 서버를 멈추게 하지 않는다.
    해당 명령을 실행한 클라이언트 연결만 블로킹되며, 이벤트 루프는 다른 클라이언트를 계속 서비스한다.

5. 왜 모든 것을 멀티‑스레드로 만들지 않을까?

LPUSH를 수행하는 스레드가 LPOP을 수행하는 다른 스레드에게 서비스를 제공해야 합니다. 얻을 수 있는 것이 적고, 추가해야 할 복잡성이 많습니다.”Antirez (Redis 창시자)

  • Redis 데이터 구조(리스트, 집합, 정렬된 집합, 스트림)는 세밀한 락킹이 필요합니다.
  • 해시 재해싱, 키 만료, 그리고 퇴출과 같은 작업은 훨씬 더 복잡하고 오류가 발생하기 쉬워집니다.
  • 단일 스레드 코어는 전체 버그 클래스를 제거하고 코드베이스를 유지 보수하기 쉽게 합니다.

6. Benchmarks & Real‑World Numbers

BenchmarkConfigurationThroughput
Pipelined SETSingle‑instance, no I/O threads1.5 M+ ops/s
Pipelined GETSame1.8 M+ ops/s
Redis 8.0 with I/O threadsio-threads = 87.4 M ops/s
Redis 6.0 I/O threading8 threads37 %–112 % improvement vs. single‑threaded
AWS ElastiCache 7.1Production node>1 M req/s
Twitter (production)10 k+ instances, 105 TB RAM39 M QPS, latency

핵심 인사이트: CPU는 Redis의 병목이 되는 경우가 드물며, 보통 메모리 대역폭이나 네트워크 I/O가 제한 요소입니다. 단일 스레드만으로도 CPU를 포화시킬 수 있기 때문에 명령 실행을 위한 스레드 수를 늘려도 수익이 감소합니다.

7. 핵심 정리 (배운 점)

  1. Command execution stays single‑threaded – 의도된 설계이며 제한이 아닙니다.
  2. Background threads exist for disk I/O, lazy freeing, and (since 6.0) network I/O. – 백그라운드 스레드는 디스크 I/O, 지연 해제, 그리고 (6.0부터) 네트워크 I/O를 위해 존재합니다.
  3. Atomicity = per‑command, not per‑transaction unless you use MULTI/EXEC. – 원자성은 명령 단위이며, MULTI/EXEC를 사용하지 않는 한 트랜잭션 단위는 아닙니다.
  4. Blocking commands block only the client, not the whole server. – 블로킹 명령은 전체 서버가 아니라 해당 클라이언트만 차단합니다.
  5. Performance is already massive; most applications never need more than a few million ops/s per instance. – 성능은 이미 매우 뛰어나며, 대부분의 애플리케이션은 인스턴스당 수백만 연산/초를 초과할 필요가 없습니다.
  6. Design simplicity = reliability – 버그가 적고, 유지보수가 쉬우며, 지연 시간이 예측 가능한 설계의 단순함은 신뢰성과 직결됩니다.

8. 추가 읽을거리

  • Redis 공식 문서https://redis.io/documentation
  • 백엔드 서비스의 연결 및 스레드 이해 – 스레드 모델에 대한 완전한 가이드.
  • 내가 직면한 6가지 일반적인 Redis 및 Kafka 문제 – EventStreamMonitor 프로젝트에서 실제로 겪은 문제들.
  • EventStreamMonitor – 내 오픈소스 모니터링 플랫폼 (공개된 경우 링크).

이 글이 “단일 스레드 vs. 다중 스레드”에 대한 혼란을 해소하고 더 나은 캐싱 전략을 설계하는 데 도움이 되길 바랍니다!

# ect – My microservices monitoring platform using Redis and Kafka
Back to Blog

관련 글

더 보기 »

C# Minimal API: 출력 캐싱

Minimal API: Output Caching은 생성된 응답을 서버에 저장하고 엔드포인트를 다시 실행하지 않고 직접 제공합니다. Microsoft Docs https://learn.m...

Go의 비밀스러운 삶: Atomic Operations

제10장: 분리될 수 없는 순간 화요일 아침, 허드슨 강에서 불어오는 날카롭고 차가운 바람이 도서관 아카이브의 오래된 sash windows를 흔들었다. Ethan은…