ReadIOPS는 절대값이 아니라 프로비저닝 IOPS 대비 사용률과 read-write 비율로 판단한다
요약
- ReadIOPS에 보편적 "정상값"은 없다. 워크로드마다 다르므로 절대 숫자로 높다/낮다를 말할 수 없다.
- 두 축으로 판단한다: (1) 스토리지가 낼 수 있는 IOPS 상한 대비 사용률, (2) read/write 비율 — 쓰기보다 읽기가 훨씬 낮으면 읽기 경로가 캐시(버퍼 풀)로 거의 다 흡수되고 있다는 신호.
- 평균이 낮아도 cold 데이터를 긁는 스파이크는 따로 본다. 캐시를 줄였을 때 위험해지는 건 평균이 아니라 이 스파이크다.
본문
"ReadIOPS가 100이면 높은가 낮은가?"에는 답이 없다. 같은 100이라도 baseline 3,000짜리 볼륨에선 한가한 거고, 다른 환경에선 빠듯할 수 있다. 그래서 절대값이 아니라 상대 기준 두 개로 본다.
1축 — 프로비저닝 IOPS 대비 사용률. 먼저 스토리지가 낼 수 있는 IOPS 상한을 안다. gp3라면 프로비저닝한 IOPS(또는 baseline), io1/io2면 프로비저닝값, gp2면 용량×3. 여기에 인스턴스의 EBS 대역폭 한계(인스턴스 클래스별 max IOPS)도 겹쳐서 둘 중 작은 값이 실질 상한이다. 그 다음 측정 IOPS를 상한으로 나눈다. 통상 피크가 상한의 70~80% 미만이면 건강, 평소에 한 자릿수 %면 여유가 큰 상태다.
실질 IOPS 상한 = min(볼륨 프로비저닝 IOPS, 인스턴스 EBS max IOPS)
사용률 = 측정 IOPS / 실질 상한
예) gp3 12,000 IOPS, 정상 피크 합계(read+write) ~850 → 사용률 7%. 극단 저활용. 단 저활용이 곧 IOPS 비용 절감 가능을 뜻하진 않는다 — RDS gp3 과금은 baseline 초과분만 받기 때문이다. RDS gp3(MySQL)는 스토리지 400GiB 미만이면 baseline 3,000 IOPS/125MBps(프로비저닝 불가), 400GiB 이상이면 volume striping으로 baseline이 12,000 IOPS/500MBps로 점프하고 그 이상(12,00064,000)만 프로비저닝·과금된다. 따라서 12,000에 딱 맞춰져 있으면 이미 무료 baseline이라 더 못 내리고 절감액도 없다. 저활용은 "인스턴스/메모리를 줄일 여지"의 신호일 뿐, IOPS 과금 자체는 baseline 구조부터 확인해야 판단할 수 있다.
2축 — read/write 비율. 이게 캐시 효율을 드러낸다. 쓰기는 캐시로 못 줄인다 — 변경은 디스크/redo log에 반드시 내려가야 하므로 WriteIOPS는 실제 쓰기 워크로드를 그대로 반영한다. 반면 읽기는 버퍼 풀에 있으면 물리 IO가 안 생긴다. 따라서:
- ReadIOPS ≪ WriteIOPS (예: read 50 vs write 210) → 읽기 요청이 거의 다 메모리에서 해결되고 디스크까지 내려오는 건 극소수 = 읽기 경로가 잘 캐시되고 있음. 데이터셋이 버퍼 풀보다 훨씬 커도 이 패턴이면 핫셋이 작다는 뜻.
- ReadIOPS가 WriteIOPS와 비슷하거나 더 큼 → 캐시 미스가 잦아 디스크를 자주 읽는 중. 메모리가 빠듯하거나 풀스캔성 쿼리가 많은 신호.
스파이크는 평균과 분리해서 본다. 평균 ReadIOPS가 낮아도 특정 시점(야간 배치, cold 데이터 스캔)에 수백~수천으로 튀는 경우가 있다. 평균이 아니라 이 스파이크가 진짜 리스크 표면이다 — 버퍼 풀을 줄이거나 인스턴스를 다운사이징할 때 깨지는 건 이 순간이다. 그래서 용량 검증은 max(시간당) 통계와 배치 시간대를 반드시 관찰 창에 포함해야 한다.
관련 노트
- ReadIOPS는 논리 읽기 요청이 아니라 디스크 물리 읽기를 센다
- RDS 메모리 다운사이징 가능 여부는 데이터가 커도 ReadIOPS가 낮은지로 판별한다
- RDS 다운사이징 전에 buffer pool을 점진적으로 낮춰 핫셋이 작은 pool에 맞는지 실측한다
- AWS storage gp2, gp3 차이