Zettelkasten

버퍼풀 메모리 축소로 인한 read latency 하락은 착시이다

·수정 1

요약

  • 버퍼풀을 줄이면 ReadIOPS는 늘어나는데 ReadLatency가 오히려 내려가는 현상이 관찰될 수 있다.
  • ReadLatency는 쿼리 지연이 아니라 디스크 I/O 1건당 평균 시간이라서, 싸고 빠른 read가 분모에 대량 추가되면 평균이 희석된다 (selection bias).
  • 시스템이 실제로 빨라진 게 아니므로, 성능 판단은 쿼리 레벨 지표로 해야 한다.

본문

현상: RDS 버퍼풀(innodb_buffer_pool_size)을 줄였더니 ReadIOPS는 증가했는데 CloudWatch ReadLatency는 감소했다.

핵심: ReadLatency의 분모가 바뀐 것이다

CloudWatch ReadLatency는 디스크 read I/O 1건당 평균 소요 시간이다. 평균 지표는 분모(I/O 건수)의 구성이 바뀌면 개별 I/O가 빨라지지 않아도 값이 움직인다.

  • 버퍼풀이 클 때: 디스크까지 내려가는 read는 버퍼풀이 못 잡은 어려운 read(랜덤 single-page, cold 데이터)만 남는다. 분모가 작고 비싼 read 위주 → 평균이 높게 나온다.
  • 버퍼풀을 줄이면: 이전엔 버퍼풀이 흡수하던 hot page read가 대량으로 디스크로 내려간다. 그런데 이 read들은 성격이 좋다:
    • 자주 읽히는 페이지라 스토리지 계층 캐시(EBS 캐시 등)에 거의 항상 올라가 있어 빠르다
    • 순차 스캔성이면 InnoDB read-ahead가 묶어서 가져와 건당 비용이 낮다
  • 결과: 비싼 read의 절대 개수는 그대로인데, 빠른 read가 분모에 잔뜩 추가되면서 평균이 내려간다.

즉 read latency 하락은 개선이 아니라 평균의 희석이다. (ReadLatency가 per-I/O 평균이라는 것은 문서화된 사실이고, 희석이 주원인이라는 해석은 정황 기반 추론 — 아래 검증 지표로 확인 필요)

부차적으로 가능한 요인 (환경에 따라)

  • innodb_flush_method=O_DIRECT가 아니면 버퍼풀에서 해제된 메모리가 OS 페이지 캐시로 가서 file read가 메모리에서 처리됨 (RDS 기본은 O_DIRECT라 보통 해당 없음)
  • 매우 큰 버퍼풀에서의 LRU/free list 스캔, 뮤텍스 경합 감소 — 보통은 미미함
  • 프로비저닝 IOPS 한도 내라면 IOPS가 늘어도 queue가 안 쌓여 per-op latency가 안정적일 수 있음

진짜 성능을 판단하는 지표

평균 디스크 latency 대신 다음을 본다:

  • 쿼리 단 latency: 애플리케이션 p99, slow query 추이 — 버퍼풀을 줄였으면 보통 나빠지거나 그대로
  • ReadIOPS × ReadLatency = 총 read I/O 시간: 이게 늘었다면 디스크 부담은 실제로 증가한 것
  • Performance Insights에서 io/file/innodb/innodb_data_file wait 비중 변화

일반화: 평균 기반 지표는 분모 구성이 바뀌는 변경(캐시 크기 조정, 트래픽 mix 변화) 전후 비교에 취약하다. 변경의 효과는 평균이 아니라 분포(p99)나 총량으로 판단한다.

관련 노트

참고