코어가 남는데 하나만 쓴다

Redis의 명령 실행은 스레드 하나가 담당한다. 멀티코어 시대에 이상해 보이지만, 이 결정에는 분명한 전제가 있다.

Redis의 병목은 CPU가 아니다. 데이터가 메모리에 있으니 연산은 대부분 마이크로초 단위로 끝난다. 실제 한계는 네트워크 대역폭과 메모리 접근 속도에서 온다. CPU를 더 투입해도 얻을 게 별로 없다.

얻은 것

병목이 아닌 곳에 스레드를 늘리지 않기로 하면 많은 것이 단순해진다.

동시 접속은 스레드가 아니라 이벤트 루프로 감당한다. epoll로 준비된 소켓만 골라 처리하므로 커넥션 수만 명도 스레드 하나로 다룬다.

대가 — 하나가 막히면 전부 막힌다

명령을 하나씩 처리한다는 말은, 오래 걸리는 명령 하나가 나머지 전부를 세운다는 뜻이기도 하다.

조심해야 할 것들:

느린 쿼리 로그(slowlog)를 켜두면 이런 명령을 찾을 수 있다.

지금은 완전한 싱글 스레드가 아니다

Redis 6부터 I/O 스레드가 들어왔다. 다만 이건 소켓 읽기·쓰기와 프로토콜 파싱을 나눠 맡는 것이고, 명령 실행 자체는 여전히 한 스레드가 한다. 원자성 보장은 그대로다.

정리

싱글 스레드는 성능을 포기한 선택이 아니라, 병목이 아닌 곳을 복잡하게 만들지 않겠다는 선택이다. 대신 “한 명령이 전체를 막는다”는 성질을 항상 염두에 두어야 한다.