학습 목표
버퍼링이 CPU·장치 속도 차이를 완화하는 이유와 싱글·더블 버퍼 차이를 설명할 수 있다.
페이지 캐시(page cache) 가 파일 블록을 RAM에 두는 방식과 cache hit/miss를 설명할 수 있다.
write-back 쓰기와 fsync/sync 로 디스크 반영 시점을 구분할 수 있다.
블록 I/O 요청이 캐시·디스크 스케줄러를 거치는 흐름을 설명할 수 있다.
문제 상황
- 같은 로그 파일을 두 번
cat하면 두 번째가 훨씬 빠르다- 디스크를 안 갔을 가능성
write()직후 전원이 꺼지면 데이터가 사라진다fsync를 안 했을 때
- DB는
O_DIRECT로 페이지 캐시를 우회하기도 한다- 이중 캐싱·일관성 이슈
free -h에서 buff/cache가 수 GB- OS가 남는 RAM을 I/O 캐시에 씀
I/O 스택에서 page cache가 언급됐다. 이번엔 OS가 읽기·쓰기를 어떻게 버퍼링·캐싱하는지 — 디스크 왕복을 줄이는 계층이다.
1. 왜 버퍼링·캐싱인가
CPU(나노초~마이크로초)와 디스크(밀리초) 속도 차이가 크다. 매 바이트마다 장치를 기다리면 CPU가 낭비된다.
| 기법 | 아이디어 |
|---|---|
| 버퍼링 | 데이터를 중간 저장소에 모았다가 한꺼번에 이동 |
| 캐싱 | 자주 쓰는 데이터 복사본을 빠른 매체(RAM)에 유지 |
- 블록 단위(보통 4KB)로 다루면 syscall·DMA 횟수 감소
- Linux는 파일 데이터용 page cache, 메타데이터·일부 경로는 별도 구조 — 개념적으로 “파일 블록 = 캐시된 페이지”
2. 싱글 버퍼 vs 더블 버퍼
스트리밍 I/O(오디오, 파이프, 네트워크)에서 생산자(장치) 와 소비자(CPU) 속도가 다를 때.

| 방식 | 동작 | 단점 |
|---|---|---|
| 싱글 버퍼 | 버퍼 하나 — 채우는 동안 CPU 대기, 처리하는 동안 장치 대기 | 양쪽이 번갈아 유휴 |
| 더블 버퍼 | A 채우는 동안 CPU는 B 처리, 역할 교대 | 메모리 2배, 동기화 필요 |
- 디스크 이중 버퍼링: OS가 한 블록을 사용자에게 넘기는 동안 다음 블록을 미리 읽기 — readahead
- 링 버퍼: 고정 크기 순환 버퍼 — NIC·시리얼에서 흔함
3. 페이지 캐시와 읽기
파일 read()는 대개 page cache를 먼저 본다. 캐시 엔트리는 (inode, offset) 등으로 파일 블록과 대응된다.

Cache hit
- VFS가 요청 범위가 캐시에 있는지 확인
- 있으면 RAM에서 사용자 버퍼로 복사 후 return
- 디스크 I/O 없음
Cache miss
- 캐시에 없는 페이지 할당
- 블록 I/O로 디스크에서 읽어 캐시에 채움
- 사용자 버퍼로 복사
| 개념 | 설명 |
|---|---|
| Page cache hit | 요청 블록이 이미 RAM에 있음 |
| Readahead | 순차 읽기 감지 시 다음 블록 미리 로드 |
| Buffer I/O | read가 사용자 버퍼로 직접 — 여전히 내부적으로 page cache 경유(일반 경로) |
mmap+MAP_SHARED: 파일 페이지가 주소 공간에 매핑 — 캐시와 공유 가능- 캐시 압박: RAM 부족 시 LRU 계열로 오래된 캐시 페이지 회수 — 파일 데이터도 대상
4. 쓰기: write-back과 flush
쓰기는 보통 page cache를 먼저 갱신하고, 디스크 반영은 나중에 한다 — write-back(lazy write).

| 단계 | 설명 |
|---|---|
write() |
캐시 페이지 수정, dirty 표시 — syscall은 빠르게 return |
| 백그라운드 flush | 커널 pdflush/flusher 스레드가 dirty 페이지를 디스크에 기록 |
fsync(fd) |
해당 파일의 dirty 페이지 강제 디스크 반영 후 return |
sync() |
시스템 전체 dirty 블록 flush (무거움) |
| 정책 | 동작 | 특징 |
|---|---|---|
| Write-back | 캐시만 갱신, 지연 기록 | 빠름, 전원 차단 시 손실 위험 |
| Write-through | 캐시 + 디스크 동시 갱신 | 느림, 내구성 높음 — 일부 DB·장치 |
O_SYNC/O_DSYNC:write가 디스크까지 간 뒤 return하도록 요청O_DIRECT: page cache 우회, 정렬된 버퍼로 장치와 직접 I/O — DB 엔진이 자체 캐시 관리할 때- Copy-on-write, journaling FS: 메타데이터·데이터 일관성 — 파일 시스템 구현 주제
5. 블록 I/O 경로 (복습)
캐시 miss·dirty flush 모두 결국 block layer로 내려간다.
read miss / write flush
→ bio (block I/O) 구조체
→ I/O 스케줄러 (elevator)
→ 드라이버 → DMA → 디스크
| 도구 | 보는 것 |
|---|---|
cat /proc/meminfo |
Cached, Dirty, Writeback |
vmstat 1 |
bo(blocks out) — 디스크로 나가는 블록 |
iostat -x |
디스크 utilization, await |
- Dirty 페이지가 많으면 flush 폭주로 I/O 스파이크 — DB는
fsync타이밍·WAL로 제어 - Network·DB 버퍼 풀도 같은 “빠른 계층에 복사본” 패턴 — 다른 시리즈와 연결
6. 정리
- 버퍼링·캐싱은 속도 차이를 메우고 디스크 왕복을 줄인다
- 더블 버퍼·readahead로 장치와 CPU 병렬 활용
- Page cache: read hit은 RAM만, miss는 디스크 후 캐시 적재
- Write-back + dirty flush —
fsync가 내구성 보장 시점 - 다음: 보호와 보안, 접근 제어·권한
다음에 다룰 것
- 보호와 보안
- 접근 제어, 인증, 권한 모델
해당 내용은 Operating System Concepts, 10/E (Avraham Silberschatz, Peter Baer Galvin, Greg Gagne) 의 내용을 기반으로 합니다.