-
Redis는 싱글스레드인가?프로젝트/선착순 쿠폰 발급 시스템 2023. 6. 19. 00:01728x90
개요
대부분 Redis는 Single Thread라고 알고 있으며, 저 또한 그렇게 이해하고 있습니다.
이런 배경지식으로 병렬 프로그래밍 환경에서 원자성(Atomic)을 보장하기 위해 사용하기도 하였습니다.
하지만 종종 다음과 같은글들을 만날 수 있습니다.
https://medium.com/javarevisited/go-crazy-is-redis-single-threaded-or-multi-threaded-96fe8ff99ab9
https://charsyam.wordpress.com/2014/03/07/redis-가-멀티스레드라구요/
redis가 멀티쓰레드인가? 싱글스레드인가? 에 대한 내용들입니다.
이제 혼란이 오기 시작합니다.
redis는 싱글쓰레드 라고 알고있었는데...
Redis Documents
redis document에서 single thread로 검색해 보면 다음과 같은 글을 볼 수 있습니다.
Redis는 single thread이며 multiplexing이란 기술을 사용하여 단일 프로세스가 모든 클라이언트 요청을 처리합니다.
모든 요청이 순차적으로 처리되며, 이는 Node.js의 작동 방식과 매우 유사합니다.
Redis 2.4부터는 디스크 I/O와 관련된 느린 I/O 작업을 백그라운드에서 수행하기 위해 여러 개의 스레드를 사용하지만 Redis가 단일 스레드를 사용하여 모든 요청을 처리한다는 사실은 바뀌지 않습니다.단일 스레드의 결과는 요청이 느리게 처리될 때 다른 모든 클라이언트가 이 요청이 처리될 때까지 기다립니다.
이런 사유 때문에 Redis를 사용할 때는 명령의 알고리즘 시간복잡도가 문서화되어 있고 잘 확인하여 사용해야 합니다.
* 프로덕션 환경에서 KEYS 명령어를 사용하면 안 되는 이유
Multiplexing이란?
하나의 통신채널을 통해 다량의 데이터를 전송하는 데 사용되는 기술입니다.
매 요청마다 새로운 프로세스나 쓰레드를 생성하는 게 아니라 요청의 개수와 상관없이 한 개의 프로세스나 스레드를 이용하여 작업을 처리합니다.
모든 작업처리는 단일 콜스택에서 이루어지고 비동기 처리는 Queue를 이용하여 이벤트루프방식으로 동작합니다.
여러 개의 소켓이 동시에 연결되어 있고, 이들을 관찰하면서 들어오는 작업을 처리합니다.
1. Redis는 새로운 클라이언트 연결, 클라이언트에서 들어오는 데이터 또는 I/O 작업 완료와 같은 이벤트가 발생하기를 기다리는 단일 이벤트 루프를 사용합니다.
2. 새 클라이언트가 Redis에 연결되면 이벤트 루프에 등록되고 이벤트 루프는 들어오는 데이터에 대한 연결을 모니터링합니다.
3. 클라이언트로부터 데이터가 도착하면 이벤트 루프는 이벤트 유형을 결정하고 그에 따라 처리합니다.
4. 클라이언트의 요청에 I/O작업이 필요한 경우 이벤트 루프는 다른 클라이언트의 연결의 진행을 차단하지 않고 작업을 비동기적으로 수행합니다.
5. 이벤트 루프가 여러 클라이언트의 이벤트를 처리할 때 각 클라이언트에 대해 보류 중인 작업 대기열을 유지 관리합니다. 이를 통해 Redis는 실제 처리가 단일 스레드 내에서 발생하더라도 동시에 여러 클라이언트에 서비스를 제공할 수 있습니다.
단일 스레드 이벤트 기반 아키텍처를 사용함으로써 Redis는 스레드 동기화, 컨텍스트 스위칭로 발생하는 리로스 경합 및 오버헤드, 복잡성을 방지합니다.
Redis MultiThread?
위에서도 I/O 작업등을 백그라운드에서 처리할 때 여러 개의 쓰레드를 사용한다고 명시되어 있습니다.
실제로 redis의 스레드를 조회해 보면 여러 개가 쓰여있습니다.
하지만 하나의 쓰레드에서만 명령을 처리하고 나머지 쓰레드들은 disk를 flush하거나 파일을 닫기 위해 OS 작업이 되는것을 해당 쓰레드에서 처리하게 되면 다른 작업이 느려지기 때문에 해당 작업들을 OS레벨에서 비동기로 처리합니다.
즉, Single Thread라는 의미는 클라이언트의 요청인 Redis의 명령어를 처리하는 것에만 유의미합니다.
초반에 개요에서 게시한 글에서도 Redis 6.0에서 ThreadedIO로 Multi Thread를 지원하여 2.5배 성능을 빠르게 하였지만 여전히 명령의 실행은 Single Thread로 실행되기 때문에 Atomic이 깨지지 않습니다.
Single Thread로 빠른데 Multi Thread를 도입한 이유는?
Redis의 성능 병목 현상중 하나인 네트워크 IO 작업 때문입니다.
프로젝트에서 일부 큰 키-값 쌍을 삭제해야 하는 경우 단시간에 삭제할 수 없으면 단일 스레드의 경우 후속 작업이 차단됩니다.
참고자료
https://redis.io/docs/management/optimization/latency/
https://redis.com/blog/multiplexing-explained/
'프로젝트 > 선착순 쿠폰 발급 시스템' 카테고리의 다른 글
Spring Boot + Redis 대기열 시스템 만들어보기 - 이론편 (0) 2023.10.29 Redis 주의사항 (0) 2023.07.01 선착순 쿠폰 발급 시스템 성능테스트 (0) 2023.06.18 RedisTemplate으로 Set 자료구조 사용하기 (0) 2023.06.09 Spring Event 사용하기 (0) 2023.05.30