리눅스에서 free 명령을 치면 buff/cache 항목이 있습니다. 이 메모리는 낭비가 아니라, 디스크 I/O를 줄이기 위한 캐시입니다. 이 구조를 이해하면 시스템 성능 튜닝의 기본이 보입니다.


리눅스 I/O 캐싱 구조

PLAINTEXT
애플리케이션

    │ read() / write()

VFS (Virtual File System)


페이지 캐시 (Page Cache)

    │ 캐시 미스 시

파일 시스템 (ext4, xfs 등)


블록 I/O 레이어


디바이스 드라이버


디스크 (HDD/SSD)

페이지 캐시 구조


페이지 캐시 (Page Cache)

디스크에서 읽은 파일 데이터를 메모리에 캐싱 합니다. 페이지(4KB) 단위로 관리합니다.

읽기 과정

PLAINTEXT
read() 호출


페이지 캐시에 있나? ──── Yes ──→ 캐시에서 바로 반환 (캐시 히트)

    No (캐시 미스)


디스크에서 읽기 → 페이지 캐시에 저장 → 애플리케이션에 반환

쓰기 과정

PLAINTEXT
write() 호출


페이지 캐시에 쓰기 (Dirty Page로 표시)

    │ write()는 여기서 반환 (빠름!)


커널의 pdflush/writeback 스레드가
나중에 디스크에 비동기 기록
  • Write-Back 방식: 쓰기 시 캐시에만 쓰고, 나중에 디스크에 반영
  • dirty_expire_centisecs: dirty 페이지가 디스크에 기록되기까지의 최대 대기 시간 (기본 3000 = 30초)
  • fsync()를 호출하면 즉시 디스크에 기록

버퍼 캐시 (Buffer Cache)

블록 디바이스의 메타데이터를 캐싱 합니다. 현대 리눅스에서는 페이지 캐시에 통합되었습니다.

PLAINTEXT
과거 (2.4 이전):
페이지 캐시: 파일 데이터 캐싱
버퍼 캐시: 블록 디바이스 메타데이터 캐싱 (별도 관리)

현재 (2.4 이후):
페이지 캐시에 통합 — 버퍼는 페이지 캐시의 일부로 관리
BASH
# free 명령에서 확인
$ free -h
              total        used        free      shared  buff/cache   available
Mem:          16Gi        8Gi        2Gi        500Mi       6Gi        7Gi

# buff/cache 6GB: 디스크 캐시로 사용 중
# available 7GB: 실제로 사용 가능한 메모리 (캐시는 필요 시 해제됨)

캐시 관련 커널 파라미터

BASH
# 더티 페이지 비율 (전체 메모리의 %)
cat /proc/sys/vm/dirty_ratio          # 동기 쓰기 전환 임계값 (기본 20%)
cat /proc/sys/vm/dirty_background_ratio  # 백그라운드 기록 시작 임계값 (기본 10%)

# 캐시 수동 비우기 (운영 중에는 사용하지 않는 것이 좋음)
echo 1 > /proc/sys/vm/drop_caches    # 페이지 캐시 비우기
echo 2 > /proc/sys/vm/drop_caches    # 슬랩 캐시(dentry, inode) 비우기
echo 3 > /proc/sys/vm/drop_caches    # 둘 다 비우기

Readahead (미리 읽기)

순차 읽기 패턴을 감지하면 커널이 미리 다음 데이터를 읽어 캐시에 올립니다.

BASH
# readahead 크기 확인 (섹터 단위, 512바이트)
cat /sys/block/sda/queue/read_ahead_kb  # 기본 128KB

# 대용량 순차 읽기 시 증가
echo 2048 > /sys/block/sda/queue/read_ahead_kb

Direct I/O

페이지 캐시를 우회하여 디스크에 직접 I/O합니다.

C
int fd = open("file", O_RDWR | O_DIRECT);
// 캐시 없이 디스크 직접 접근
// 데이터베이스가 자체 캐시를 관리할 때 사용 (MySQL InnoDB 등)
  • 데이터베이스는 자체 버퍼 풀이 있으므로 OS 페이지 캐시와 이중 캐싱을 피하기 위해 Direct I/O 사용

핵심 포인트

  • free 명령의 buff/cache: 낭비가 아니라 캐시 — available을 봐야 실제 여유 메모리
  • Write-Back vs Write-Through: 리눅스는 Write-Back — 성능은 좋지만 정전 시 데이터 손실 가능
  • DB가 Direct I/O 쓰는 이유: 자체 캐시와 OS 캐시의 이중 캐싱 방지
  • fsync()의 중요성: WAL이나 트랜잭션 로그는 반드시 fsync()로 디스크 기록 보장

정리

리눅스 페이지 캐시는 디스크 I/O 성능의 핵심입니다. 남는 메모리를 자동으로 캐시로 활용하고, 필요하면 해제합니다. 시스템 모니터링에서 "메모리가 다 찼다"고 당황하기 전에 buff/cache를 확인하는 것이 기본입니다.

댓글 로딩 중...