리눅스 I/O 스케줄러 - NOOP, CFQ, Deadline, BFQ

핵심 인사이트 (3줄 요약)

  1. 본질: 리눅스 I/O 스케줄러는 수십 개의 유저 앱들이 하드디스크나 SSD에 읽고 쓰겠다고 마구잡이로 던진 1차원적인 요청(Queue)들을 가로채, 하드웨어의 물리적 한계(Seek Time)를 덮어주고 프로세스 간의 공평성을 보장하도록 순서와 타이밍을 재배치(Sorting & Merging)하는 커널 내부의 관제탑이다.
  2. 가치: 쇳덩어리 모터(HDD)의 동선을 아껴주는 CFQ(엘리베이터), 1초 안에 무조건 응답을 빼주는 Deadline(실시간 보장), 그리고 바늘이 없는 최신 반도체(SSD/NVMe) 환경에서 오버헤드 0으로 직진하는 NOOP(None) 등 하드웨어 맞춤형 튜닝을 통해 디스크 스루풋을 극대화한다.
  3. 융합(진화): 단일 큐(Single Queue) 시절의 병목을 부수고 멀티코어 64만 개의 큐를 뚫어버린 blk-mq 아키텍처 위에서, 모바일/데스크탑의 체감 반응성을 극한으로 끌어올린 BFQ(예산 공평 큐잉)로 융합 진화하며 현대 블록 I/O 생태계를 완벽하게 평정했다.

Ⅰ. 개요 및 필요성 (Context & Necessity)

  • 개념: 운영체제의 파일 시스템(EXT4) 아래, 그리고 진짜 하드웨어(디바이스 드라이버) 위에 샌드위치처럼 껴있는 '블록 I/O 계층(Block Layer)'의 심장부다. read/write 시스템 콜로 쏟아지는 요청 블록(Sector 100번지, 5000번지)들을 모아서, 합칠 건 합치고(Merge), 순서 바꿀 건 바꾸는(Sort) 4가지 대표적 알고리즘(NOOP, CFQ, Deadline, BFQ)의 집합체다.

  • 필요성: 1990년대 리눅스 서버에 접속자가 10명만 넘어가도 하드디스크가 "드르륵 드르륵" 비명을 지르며 서버가 멈췄다(I/O 스래싱). 1번 앱이 10번지 찌르고, 2번 앱이 9000번지를 찌르는 랜덤 I/O 앞에서 기계식 바늘(Head)은 와이퍼처럼 널뛰다 모터가 타버렸다. 이 물리적 파국을 막기 위해 커널은 "야, 디스크로 보내기 전에 내 큐(Queue)에 잠시 다 대기시켜봐. 내가 바늘 동선 제일 짧게, 그리고 아무도 안 굶어 죽게 줄(스케줄) 다시 예쁘게 세워줄게!"라며 교통정리에 총대를 메고 나선 것이다.

  • 💡 비유: I/O 스케줄러는 대형 놀이공원의 놀이기구 탑승 줄 세우기 알바생과 같다.

    • NOOP (없음): "나 알 바 아님. 온 순서대로 막 타!(FCFS)" (손님이 순간 이동하는 SSD 포탈 환경에서만 가능).
    • CFQ (완전 공평): "A 학교, B 학교, C 학교 학생 1명씩 번갈아 가며 한 줄로 예쁘게 타세요!" (서버 전체의 앱들이 골고루 디스크를 쪼개 쓰는 낭만).
    • Deadline (시간제한): "VIP 손님은 무조건 0.5초 안에 태워줘야 하니까, 일반 줄 무시하고 VIP부터 냅다 꽂아!" (구석에 처박힌 파일 렉 방지).
    • BFQ (예산 할당): "너네 학교 덩치 제일 크니까 이번 턴에 10명 태워주고, 저 학교는 2명 태워줄게(대역폭 분배)." (현대 스마트폰의 렉 없는 터치감의 비밀).
  • 등장 배경 및 저장매체의 진화에 따른 멸망과 부활:

    1. HDD의 암흑기: Seek Time 8ms를 줄이기 위해 영혼을 갈아 넣은 CFQ(엘리베이터)가 리눅스 천하를 지배함.
    2. SSD의 파괴적 등장: 바늘이 없어져 정렬(Sorting)이 오히려 렉이 됨. CPU만 처먹는 CFQ가 버려지고 NOOP(무지성)이 왕좌에 오름.
    3. Multi-Queue (blk-mq)의 혁명: 코어 64개가 SSD에 100만 IOPS를 쏠 때 큐 1개(Single Queue)에서 락(Lock)이 걸리자, 큐를 수만 개로 찢어버리며 스케줄러 생태계를 완전히 물갈이함.
┌─────────────────────────────────────────────────────────────────────────┐
│        리눅스 4대 I/O 스케줄러의 아키텍처 및 철학 비교 시각화           │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│ ▶ 1. NOOP (No Operation / none) - SSD의 영원한 단짝                     │
│   [앱 요청] ─▶ [단순 FIFO 큐] ─(정렬 없이 즉시)─▶ [SSD/NVMe]            │
│   🚀 장점: CPU 오버헤드 0%. 순간 이동하는 SSD에 가장 미친 속도 뿜어냄.  │
│                                                                         │
│ ▶ 2. Deadline (데드라인) - 기아(Starvation) 박멸자                      │
│   [읽기 큐: 500ms 제한] + [쓰기 큐: 5초 제한] ──▶ [엘리베이터 큐]       │
│   ⏱️ 장점: 500ms 다 된 똥줄 타는 요청이 생기면 엘리베이터 동선 다       │
│           무시하고 즉시 그쪽으로 바늘 꺾어버림. (DB 서버의 구원자)      │
│                                                                         │
│ ▶ 3. CFQ (Completely Fair Queuing) - 옛날 HDD의 제왕                    │
│   [크롬 큐] [엑셀 큐] [카톡 큐] -> 각자 100ms씩 공평하게 디스크 줌      │
│   ⚖️ 장점: 한 앱이 디스크 100% 독점해 서버 뻗는 걸 완벽 차단.           │
│                                                                         │
│ ▶ 4. BFQ (Budget Fair Queuing) - 현대 모바일/데스크탑의 패자            │
│   CFQ 진화형. "디스크 시간"이 아닌 "데이터 예산(Byte)" 단위로 공평 배분.│
│   📱 장점: 뒤에서 10GB 다운받아도 내 마우스 커서와 영상은 절대 안 끊김! │
└─────────────────────────────────────────────────────────────────────────┘

[다이어그램 해설] 리눅스 서버를 깔고 아무 세팅도 안 하면 서버의 잠재력을 50%도 못 쓴다. 하드디스크가 달린 옛날 서버에 NOOP을 주면 바늘이 널뛰다 모터가 타버리고, 최신 NVMe SSD가 꽂힌 AWS 클라우드에 CFQ를 켜두면 CPU 코어가 정렬 헛수고를 하느라 IOPS가 1/10로 박살 난다. 하드웨어의 물리적 쌩얼을 정확히 파악하고 echo none > /sys/block/sda/queue/scheduler를 때려 넣는 자가 진정한 데브옵스(DevOps) 엔지니어다.

  • 📢 섹션 요약 비유: 식당(서버)에서 주문을 쳐내는 4명의 매니저입니다. NOOP은 "들어온 대로 당장 주방에 찔러(SSD 최적)!" CFQ는 "1번 테이블 한 개, 2번 테이블 한 개 공평하게 나가!(하드디스크 최적)" Deadline은 "효율이고 뭐고 30분 넘게 화난 손님 1순위로 빼!(DB 최적)" BFQ는 "비싼 코스 요리 시킨 VIP석 팍팍 밀어줘(체감 성능 최적)!"입니다. 식당의 메뉴판(하드웨어)에 따라 매니저를 갈아 끼워야 안 망합니다.

Ⅱ. 아키텍처 및 핵심 원리 (Deep Dive)

1. Deadline 스케줄러의 타임아웃 흑마술

디스크는 '쓰기(Write)'보다 **'읽기(Read)'**가 수만 배 더 시급하다.

  • 앱이 파일에 값을 덮어쓰는(Write) 건, 램 버퍼에 대충 던져놓고 딴일 하러 가면 된다(지연 쓰기).
  • 하지만 파일을 읽을(Read) 때는? 디스크에서 파일이 올라올 때까지 앱 스레드가 꼼짝없이 기절(Blocked)해서 기다려야 한다.
  • Deadline의 철학:
    1. 엘리베이터(C-LOOK)처럼 거리를 계산해 큐를 정렬한다.
    2. 근데 큐 옆에 **'타이머 큐'**를 두 개 더 판다. (Read 큐 = 500ms 제한, Write 큐 = 5초 제한). 읽기에 극단적 특혜를 줬다.
    3. 평소엔 엘리베이터 큐대로 예쁘게 긁다가, 타임아웃 500ms가 임박한 Read 요청이 터지면?
    4. 엘리베이터 스케줄을 박살 내고, 바늘을 휙 꺾어서 그 불쌍한 Read 데이터부터 구출해 온다.
    5. 결과: 특정 데이터가 디스크 구석에 박혀 영원히 굶어 죽는(Starvation) 것을 막아내며, DB 서버의 응답 기복(Variance)을 환상적으로 플랫하게 잡아준다. (오라클 DB의 추천 1순위 튜닝).

2. CFQ (Completely Fair Queuing)의 낭만과 멸망

CFQ는 리눅스 2.6 시절을 씹어 먹던 제왕이었다.

  • 동작 원리: 64개의 프로세스가 돌고 있으면, OS 안에 64개의 내부 I/O 큐를 따로 판다.

  • 그리고 디스크(HDD)라는 거대한 피자를 64개의 프로세스에게 돌아가면서 '시간 조각(Time Slice)'으로 떼어준다.

  • "크롬아, 네가 100ms 동안 디스크 혼자 독점해서 다 긁어! 그다음은 엑셀, 네가 100ms 독점해!"

  • 장점: 어떤 미친 프로세스(바이러스)가 1초에 1억 번 디스크를 긁어대도, 걔한테 허락된 시간은 100ms뿐이라 다른 프로세스들이 절대 렉이 안 걸린다. 궁극의 공평성(Fairness)이다.

  • 멸망의 이유 (SSD): SSD 시대가 오자 이 100ms 시간 배분이 최악의 족쇄가 되었다. SSD는 동시에 10만 개를 꽂아도 다 처리하는 괴물인데, CFQ가 "잠깐! 엑셀 1명만 들어가서 100ms 써라!" 하고 입구 컷을 해버리니 SSD의 스피드가 1%도 발휘되지 못했다. 결국 커널 블록 레이어에서 불명예 퇴출당했다.

  • 📢 섹션 요약 비유: 놀이공원 화장실(디스크) 앞입니다. Deadline 매니저는 배가 너무 아파서 쓰러지기 일보 직전인 사람(500ms 임박)을 줄 다 무시하고 무조건 1순위로 화장실에 밀어 넣습니다. CFQ 매니저는 배가 아프든 말든, 어른/아이/할아버지(프로세스별) 줄을 따로 세워놓고 "어른 1명 싸고, 그다음 아이 1명 싸라"며 평등에 목숨을 걸다가 화장실 칸(SSD 다중 처리) 100개가 비어있는데도 줄을 안 풀어줘서 폭동이 나는 꼴입니다.


Ⅲ. 융합 비교 및 다각도 분석

비교 1: Single-Queue(구형) vs Multi-Queue(최신 blk-mq)

리눅스 I/O 스케줄러 역사의 가장 거대한 대지진(Paradigm Shift)이다.

척도구형 블록 레이어 (Single Queue)최신 blk-mq (Multi-Queue)
큐(Queue) 개수시스템 전체에 딱 1개의 디스크 큐CPU 코어 개수만큼 큐를 뚫음 (예: 128개)
멀티코어 락(Lock)64코어가 1개 큐에 쑤셔 넣느라 Spinlock 경합 터짐각자 자기 코어 큐에 넣으면 끝 (Lock Free 🚀)
대응 스토리지느린 SATA HDD (1개 큐로도 충분함)NVMe SSD (초당 수백만 IOPS 감당)
사라진 스케줄러CFQ, 낡은 Deadline 영원히 폐기 처분됨mq-deadline, bfq, none 으로 완전 물갈이

BFQ (Budget Fair Queuing)의 스마트폰 혁명

CFQ가 SSD에서 처참히 망하자, 똑똑한 이탈리아 해커들이 BFQ라는 걸그룹 같은 이름의 스케줄러를 커널에 이식했다.

  • CFQ의 문제점: "엑셀 너 디스크 100ms(시간) 동안 써!"라고 했더니, 빠른 SSD에서 엑셀 혼자 100ms 동안 10GB를 긁어버렸다(대역폭 독식).
  • BFQ의 흑마술: "시간이 아니라 데이터 예산(Budget)을 쏜다! 엑셀 너는 딱 50MB(섹터 개수)만 긁고 나와!"
  • 휴리스틱 (가중치): BFQ는 유저가 화면에서 **터치(Touch)**하거나 마우스를 움직이는 액티브한 프로세스(GUI)를 귀신같이 알아채고 걔한테 I/O 대역폭을 왕창 몰아준다.
  • 결과: 안드로이드 폰 뒤에서 10GB짜리 원신(Genshin) 게임을 다운받는 중(디스크 100% 혹사)이라도, 유저가 카카오톡 창을 스크롤하면 **1프레임의 버벅거림(Jitter)도 없이 부드럽게 내려가는 솜털 같은 체감 성능(UX 극대화)**을 달성하며 모바일 OS 천하를 통일했다.
┌──────────┬────────────┬────────────┬─────────────────────────────┐
│ 스토리지   │ 최적의 튜닝 │ 피해야 할 독약 │ 시스템 체감 효과     │
├──────────┼────────────┼────────────┼─────────────────────────────┤
│ NVMe SSD │ `none`     │ `bfq`, `cfq`│ CPU 연산 0, 대역폭 폭발    │
│ SATA HDD │ `mq-deadline`│ `none`      │ 드르륵 소리 줄고 수명연장│
│ 스마트폰 │ `bfq`      │ `none`      │ 렉 없는 부드러운 터치감    │
└──────────┴────────────┴────────────┴─────────────────────────────┘

[매트릭스 해설] "SSD 샀으니 무조건 none(NOOP) 쓰면 되는 거 아냐?" 반은 맞고 반은 틀렸다. AWS 서버에서 DB 돌릴 땐 none이 신(God)이지만, 데스크탑이나 리눅스 노트북에서 none을 쓰면 백그라운드 윈도우 업데이트 돌 때 내 마우스 커서가 툭툭 끊기는 지옥을 맛본다. 용도(서버 스루풋 vs 유저 UX 체감)에 따라 무기를 갈아 끼우는 것이 아키텍트의 실력이다.

  • 📢 섹션 요약 비유: 톨게이트(블록 레이어)입니다. 옛날엔 표 뽑는 아저씨가 1명(Single Queue)이라 차가 수만 대 밀리면 다 박살 났습니다. 하이패스 차로를 128개(Multi-Queue)로 뚫어버리니 차가 날아다닙니다. 여기서 빈 화물차 100대 뒤에 서 있는 구급차(사용자 터치 GUI)를 하이패스 1순위로 확 빼주는 AI 시스템이 바로 BFQ입니다. 체감 속도가 우주를 뚫죠.

Ⅳ. 실무 적용 및 기술사적 판단 (Strategy & Decision)

실무 시나리오: AWS EBS 볼륨과 echo none의 마법

  1. 문제 상황: 클라우드(AWS EC2)에서 비싼 돈을 주고 IOPS 64,000짜리 io2 볼륨(NVMe 기반)을 붙여 MySQL을 켰는데, IOPS가 10,000밖에 안 나오고 CPU sy(커널 로드)가 치솟는다.
  2. 원인 분석:
    • AWS에서 제공한 기본 리눅스 이미지가 I/O 스케줄러를 mq-deadline이나 bfq로 세팅해 둔 것이다.
    • 디스크가 너무 빠르다 보니, OS 커널이 쿼리를 예쁘게 정렬하고 시간제한 재고(Deadline 연산) 예산 배분(BFQ 연산)하느라 오히려 CPU가 발목을 잡혀 트래픽을 못 쏴주고 있었다.
  3. 신의 튜닝 (1초 컷):
    • cat /sys/block/nvme0n1/queue/scheduler 로 확인해 본다. [mq-deadline] none bfq
    • 루트 권한으로 echo none > /sys/block/nvme0n1/queue/scheduler 를 때려 넣는다.
    • 이 명령어 한 줄이 OS 커널의 모든 I/O 참견(정렬, 타이머)을 0으로 셧다운 시키고, MySQL의 쿼리를 0.001초의 검열도 없이 NVMe 컨트롤러 다이렉트로 내리꽂게 만든다.
    • 즉시 IOPS가 64,000 풀 한계치로 폭발하며, CPU 커널 로드(sy)는 1% 미만으로 쾌적하게 떨어진다. AWS 클라우드 아키텍트의 필수 생존 팁이다.

KVM 하이퍼바이저 2중 스케줄링의 참사

가상 머신(VM) 안의 우분투(Guest)가 mq-deadline으로 I/O를 정렬해서 밑으로 보냈다. 호스트(AWS 서버)에 있는 진짜 리눅스 커널이 그걸 받아서 또 mq-deadline으로 2차 정렬을 한다. 정렬을 2번이나 하느라 CPU만 낭비되고 시간은 두 배로 늦어진다(Double Scheduling). 결론: VM(가상 머신) 내부의 게스트 OS는 하드웨어의 물리적 쌩얼을 어차피 모른다(가짜 디스크). 따라서 가상 머신 안의 리눅스는 묻지도 따지지도 않고 스케줄러를 무조건 **none (NOOP)**으로 밀어버리고, 실제 물리 하드디스크가 달린 가장 밑바닥 호스트 OS 딱 1명만 스케줄링을 돌려야 서버가 타지 않는다.

  • 📢 섹션 요약 비유: 택배(데이터)를 보낼 때, 서울 지점(VM)에서 우편번호순으로 예쁘게 박스를 정렬(스케줄링)해서 본사(호스트 OS)로 보냈는데, 본사에서 그걸 뜯어서 다시 박스 크기순으로 또 정렬(2중 스케줄링)하고 앉아있습니다. 시간만 버리는 멍청한 짓이죠. 지점은 그냥 막 박스에 던져 넣고(none), 본사 한 곳에서만 딱 한 번 정렬해야 퇴근을 빨리 할 수 있습니다.

Ⅴ. 기대효과 및 결론 (Future & Standard)

정량/정성 기대효과

구분내용
CPU-디바이스 매칭 최적화HDD(바늘 이동 최소화), NVMe(CPU 락 프리 직통), 모바일(UI 반응성 우선) 등 하드웨어의 물리적 민낯에 완벽히 동기화된 맞춤형 스루풋 달성
블록 레이어 병목 분쇄 (blk-mq)싱글 큐의 스핀락 지옥을 다중 큐로 찢어버려, 코어가 128개인 매니코어 서버에서도 성능 감소 없는 선형적 I/O 확장성(Scalability) 제공
꼬리 지연(Tail Latency) 방어Deadline 큐와 BFQ 예산 분배를 통해, 디스크 과부하 상태에서도 특정 프로세스가 무한 응답 대기에 빠지는 기아 현상(Starvation)을 100% 억제

결론 및 미래 전망

리눅스 I/O 스케줄러 (NOOP, CFQ, Deadline, BFQ)의 핏빛 진화사는, "소프트웨어(OS)의 낭만적인 통제가 하드웨어(SSD)의 무식한 물리적 스피드 앞에 어떻게 무너지고 타협해 왔는가"를 보여주는 가장 극적인 기술 다큐멘터리다. 쇳덩어리 바늘(HDD)을 달래보려 엘리베이터(CFQ)를 깎던 낭만파 엔지니어들은, 전자가 순간 이동을 하는 반도체(NVMe) 앞에서는 모든 간섭을 끄고 비켜서는 것(NOOP/none)만이 유일한 정답임을 인정하고 스스로 권력을 내려놓았다(blk-mq 도입). 앞으로 CXL 기술과 Storage-Class Memory(SCM)가 대중화되어 램과 디스크의 속도 차이가 사라지게 되면, 커널 블록 레이어의 복잡한 스케줄링 로직은 완전히 소멸하고 오직 가상 메모리 매핑(mmap)을 통한 하드웨어 다이렉트 접근만이 살아남는 'Zero-OS-Overhead' 시대로 천하 통일될 것이다.

  • 📢 섹션 요약 비유: 마차(HDD) 시대에는 마부가 말 채찍질(CFQ 엘리베이터)을 정교하게 해야 마차가 덜 덜컹거리고 빨리 달렸습니다. 하지만 KTX 고속철도(NVMe SSD) 시대에 마부가 앞에 서서 채찍질(스케줄러 정렬)을 하려 들면 기차에 치여 죽을 뿐입니다. KTX 시대에는 마부는 트랙 밖으로 비켜서서 스위치(none)만 올려주고, 기계가 알아서 레일 위를 폭주하게 내버려 두는 것이 최고 속도를 내는 진리입니다.

📌 관련 개념 맵 (Knowledge Graph)

  • SCAN 스케줄링 (엘리베이터) | 리눅스 블록 스케줄러의 조상님. CFQ와 Deadline이 바늘 동선을 짤 때 가장 밑바탕에 깔고 들어가는 기본 소양
  • NVMe (Non-Volatile Memory Express) | 미친 속도로 블록 큐를 64,000개나 뚫어버려, 리눅스의 낡은 단일 큐 스케줄러들을 모조리 멸종시켜버린 하드웨어 포식자
  • blk-mq (Multi-Queue Block IO) | NVMe의 폭주에 놀란 리눅스 커널이 CPU 코어마다 디스크 큐를 파주어 락(Lock) 경합을 박살 낸 21세기 I/O 혁명 아키텍처
  • Starvation (기아 현상) | 성능만 챙기다 구석 데이터를 굶겨 죽이는 병. Deadline 스케줄러가 탄생한 유일무이하고 가장 숭고한 존재 이유
  • Context Switch (문맥 교환) | 디스크 I/O가 멈칫할 때 스레드가 뻗어버리는 지연. I/O 스케줄러가 동선을 못 짜면 이 렉이 수만 번 터져 서버가 터짐

👶 어린이를 위한 3줄 비유 설명

  1. 리눅스 I/O 스케줄러가 뭔가요? 학교 급식실에서 100명의 학생이 마구잡이로 반찬을 퍼갈 때, 아주 똑똑한 영양사 선생님(운영체제)이 줄을 예쁘게 세워주는 방법들이에요.
  2. 어떤 방법들이 있나요? 밥 푸는 동선이 꼬이지 않게 엘리베이터처럼 순서대로 세우기도 하고(CFQ), 너무 배고파서 쓰러지기 일보 직전인 친구를 1순위로 확 땡겨주기도(Deadline) 한답니다.
  3. 요즘은 어떤 방법을 쓰나요? 옛날엔 식판 나르는 게 느려서 줄을 잘 섰어야 했는데, 요즘은 급식 기계(SSD)가 1초에 1만 명을 줘버릴 만큼 엄청 빨라져서, 선생님이 줄을 안 세우고 그냥 무조건 막 밀어 넣는(none) 방법이 제일 빠르답니다!