RPS와 RFS 차이 쉽게 설명: 리눅스 멀티코어 패킷 처리의 비밀
현대의 고성능 리눅스 서버는 수십 개의 CPU 코어를 탑재하고 있습니다. 하지만 하드웨어 랜카드(NIC)가 밀려드는 대량의 네트워크 패킷을 특정 CPU 코어 하나에만 몰아서 전달한다면, 나머지 코어들이 놀고 있어도 서버가 버벅거리는 병목 현상이 발생합니다. 이를 해결하기 위해 하드웨어 차원에서는 RSS(Receive Side Scaling) 기술을 쓰지만, 하드웨어의 한계를 넘거나 소프트웨어 레벨에서 더 정교한 제어를 하기 위해 리눅스 커널은 RPS와 RFS라는 강력한 무기를 제공합니다. 본 포스팅에서는 비슷해 보이는 두 기술의 결정적인 차이점을 아주 쉽게 풀어드리겠습니다.
1. RPS (Receive Packet Steering) 란?
1.1 개념: “소프트웨어로 구현한 패킷 분산 장치”
RPS는 랜카드가 멀티 큐(Multi-queue) 기능을 지원하지 않거나 한계가 있을 때, 리눅스 커널(소프트웨어) 레벨에서 패킷 수신 부하를 여러 CPU 코어로 강제 분산시키는 기술입니다.
1.2 동작 원리
패킷이 도착하면 특정 코어(예: CPU 0)가 하드웨어 인터럽트를 받습니다. RPS는 패킷의 연결 정보(IP, 포트 번호)를 해시(Hash) 계산하여, 커널이 지정한 CPU 코어 목록(RPS Map) 중 하나를 골라 그 코어의 백로그 큐로 패킷을 휙 던져버립니다. 실제 패킷을 해독하고 처리하는 무거운 작업(SoftIRQ)은 분산된 다른 코어가 나누어 맡게 됩니다.
한 줄 요약: 패킷이 들어오는 대로 여러 CPU 코어에 균등하게 나누어 주는 일꾼입니다.
2. RFS (Receive Flow Steering) 란?
1.1 개념: “애플리케이션의 위치를 고려한 지능형 분산”
RFS는 RPS에서 한 단계 더 진화한 기술입니다. 단순히 패킷을 여러 코어에 똑같이 나누어 주는 것을 넘어, “그 데이터를 실제로 가져다 쓰는 애플리케이션(프로세스)이 구동 중인 CPU 코어”로 패킷을 보내주는 기술입니다.
1.2 동작 원리
만약 웹 서버 애플리케이션(예: Nginx 부모/자식 프로세스)이 CPU 2번 코어에서 돌고 있다고 가정해 봅시다. RPS는 기계적으로 계산하여 패킷을 CPU 1번으로 보낼 수도 있습니다. 이 경우 CPU 1번이 패킷을 가공한 뒤, 실제 데이터를 쓰기 위해 CPU 2번의 메모리로 데이터를 복사해야 하는 비효율(캐시 미스, Cache Miss)이 발생합니다. RFS는 응용 프로그램의 소켓 호출(레퍼런스)을 모니터링하여, 애플리케이션이 있는 CPU 2번 코어로 패킷을 직접 배달해 줍니다.
한 줄 요약: 데이터를 소비하는 주인이 있는 방(코어)으로 패킷을 똑똑하게 배달해 주는 비서입니다.
3. RPS vs RFS 한눈에 보는 결정적 차이점
두 기술의 매커니즘과 장단점을 직관적으로 비교해 보았습니다.
| 구분 | RPS (Receive Packet Steering) | RFS (Receive Flow Steering) |
|---|---|---|
| 분산 기준 | 패킷 헤더 정보의 수학적 해시(Hash) 값 | 데이터를 사용하는 애플리케이션의 현재 코어 위치 |
| 가장 큰 장점 | 단일 코어의 인터럽트 폭주(과부하) 차단 | CPU 캐시 적중률(Cache Hit) 극대화, 지연 시간 최소화 |
| 단점/비용 | 애플리케이션 위치와 다를 경우 캐시 미스 발생 | 소켓 흐름 테이블을 실시간 관리하므로 약간의 CPU 오버헤드 |
| 구현 계층 | 리눅스 커널 네트워크 스택 (하부) | 커널 네트워크 스택 + 소켓 레이어 연동 (상부) |
| 추천 환경 | 단순 트래픽 분산이 최우선일 때 | 초저지연(Low Latency)과 연산 최적화가 중요할 때 |
4. 쉬운 비유로 이해하는 두 기술의 본질
이해를 돕기 위해 회사 물류창고에 비유해 보겠습니다.
- RPS는 ‘공평한 분배 팀장’입니다. 택배 상자(패킷)가 들어오면 1번 직원이 혼자 포장을 다 못 하니, 2번, 3번, 4번 직원에게 수량을 똑같이 나누어 줍니다. 그런데 알고 보니 그 상자는 4번 직원이 기획한 프로젝트 물품이었습니다. 2번 직원이 포장을 뜯고 내용을 확인한 뒤, 결국 4번 직원에게 다시 가져다줘야 합니다. 똑같이 나누긴 했지만 동선 낭비가 생깁니다.
- RFS는 ‘센스 있는 배달 팀장’입니다. 택배 상자가 들어왔을 때, 내용을 보고 “어? 이거 4번 대리가 담당하는 업무 물품이네!” 하고 곧바로 4번 대리의 책상(코어)으로 상자를 보냅니다. 4번 대리는 자기가 하던 일 흐름 그대로 상자를 열어 즉시 처리하므로 동선 낭비(캐시 미스)가 전혀 없습니다.
5. 실무 적용 시 고려사항
리눅스 엔지니어라면 두 기술을 적용할 때 반드시 기억해야 할 규칙이 있습니다.
“RFS는 독립적으로 작동할 수 없으며, 반드시 RPS가 먼저 활성화되어 있어야 구동됩니다.”
RFS는 RPS가 다져놓은 분산 구조 위에서 ‘애플리케이션 위치 추적 데이터’를 얹어서 조향(Steering)하는 기술이기 때문입니다. 따라서 최적화를 원한다면 커널 파라미터에서 각 네트워크 인터페이스의 rps_cpus를 지정한 후, rps_flow_cnt와 커널 전역 변수인 netdev_rx_keys를 함께 튜닝해 주어야 진정한 고성능 네트워크 스택을 완성할 수 있습니다.
결론: 인프라 성격에 맞는 영리한 선택
리눅스 커널의 RPS와 RFS는 멀티코어 환경에서 네트워크 병목을 해결하는 가장 세련된 소프트웨어 기법들입니다. 무조건 RFS가 진화된 기술이라 해서 정답인 것은 아닙니다. 소켓의 연결과 끊김이 극도로 잦은 환경에서는 RFS의 테이블 관리 비용이 더 커질 수 있으므로, 서비스의 트래픽 패턴을 명확히 분석한 뒤 두 기술을 적절히 조합하는 방법이 필요합니다.
클라우드 가상화(VM) 환경에서는 가상 랜카드(vNIC)의 한계로 하드웨어 RSS가 제 기능을 못 하는 경우가 많습니다. 이때 리눅스 게스트 OS 레벨에서 RPS와 RFS 조합을 튜닝해 주는 것은 인프라 비용을 아끼는 최고의 꿀팁입니다