Redis에 대해서 -1
Redis Architecture
Redis는 Event-Driven Architecture (EDA)를 따르는 고성능 인메모리 데이터베이스로, 버전 6부터는 기존의 단일 스레드 구조를 확장하여 I/O 멀티스레딩 기능을 도입했습니다.
Context Switching의 제거
이를 통해 네트워크 처리 병목을 줄이고, 수십만 개의 동시 연결을 보다 효율적으로 처리할 수 있게 되었습니다. 이 구조는 내부적으로 I/O Multiplexing 기술(epoll, kqueue 등)과 Non-blocking socket 그리고 이벤트 루프(Event Loop) 기반의 구조로 운영됩니다.
Redis는 클라이언트 연결과 I/O 처리를 비동기적으로 처리하기 위해 epoll (Linux) 혹은 kqueue (BSD/macOS)와 같은 고성능 커널 이벤트 감시 인터페이스를 사용합니다. epoll은 활성화된 파일 디스크립터만을 반환하며, 대기 중인 수십만 개의 연결 중 실제로 이벤트가 발생한 소켓만을 O(1)의 시간 복잡도로 탐지할 수 있습니다.
이 구조는 Redis의 처리 효율을 극대화하며, CPU 유휴 시간을 줄이고 불필요한 컨텍스트 스위칭을 제거하는 데 효과적입니다.
Redis 6의 멀티 스레딩
Redis의 소켓은 기본적으로 Non-blocking 모드로 설정되어 있어, 데이터 수신이나 송신이 가능한 경우에만 I/O 작업이 수행됩니다. Redis 6부터는 이러한 소켓에 대한 읽기/쓰기 작업을 전용 I/O 스레드에 위임할 수 있으며, 이를 통해 메인 스레드는 명령 파싱 및 실행 로직에 집중할 수 있습니다. 이 구조는 특히 수천 개 이상의 클라이언트가 연결되어 빠르게 데이터를 송수신해야 하는 환경에서 병목을 줄이고 전반적인 처리량을 크게 향상시킵니다.
이벤트 루프의 흐름은 다음과 같이 구성됩니다. Redis는 epoll_wait()를 주기적으로 호출하여 활성화된 소켓 목록을 감지하고, 해당 소켓을 처리할 준비가 된 상태일 경우 해당 요청을 I/O 스레드에 위임합니다. I/O 스레드는 클라이언트로부터의 입력을 읽고, Redis 프로토콜 형식에 맞게 파싱한 후 메인 스레드에게 전달합니다. 메인 스레드는 이 파싱된 명령을 실제 Redis 명령으로 실행하고, 결과를 다시 응답 버퍼에 기록합니다. 이 응답은 필요시 다시 I/O 스레드를 통해 클라이언트로 전송됩니다.
이러한 구조는 Redis가 수십만 개의 연결을 효율적으로 유지하면서도 낮은 지연(latency)과 높은 처리량(throughtput)을 달성할 수 있게 해줍니다. 실제로 Redis 6 이후의 벤치마크에서는 I/O 멀티스레딩 사용 시 최대 2~3배 이상의 성능 향상이 보고되고 있으며, 이는 대규모 트래픽 환경에서의 캐시 미들웨어, 실시간 메시지 브로커, 또는 스트리밍 플랫폼 등에서 큰 이점을 제공합니다.
결론적으로, Redis 6 이상의 구조는 단일 스레드 철학을 유지하면서도 병렬성의 이점을 효과적으로 흡수한 하이브리드 아키텍처라 할 수 있습니다. 이벤트 루프 기반의 단순성과 멀티스레드 기반의 성능 확장을 동시에 갖추고 있어, 대규모 실시간 시스템에서 Redis를 핵심 구성 요소로 채택하는 이유가 여기에 있습니다.