영구 디스크 및 로컬 SSD 성능 최적화

영구 디스크는 가격, 성능, 예측 가능성으로 인해 가장 일반적으로 사용되는 저장소 옵션입니다. 하지만 영구 디스크에 데이터 중복성 및 내구성은 없더라도 성능을 높이고 지연 시간을 낮추기 위해 로컬 SSD를 사용하여 인스턴스를 만들 수도 있습니다. 인스턴스에서 실행되는 애플리케이션의 저장소 옵션을 구성할 때는 다음 프로세스를 따르세요.

  • 필요한 공간을 결정합니다.
  • 애플리케이션에 필요한 성능 특성을 결정합니다.
  • 저장소 성능을 최적화할 수 있도록 인스턴스를 구성합니다.

이 문서에서는 Compute Engine 인스턴스에 연결할 수 있는 블록 저장소 옵션에 대해 설명합니다. Google Cloud Platform의 전체 저장소 옵션 목록을 보려면 저장소 옵션 선택을 읽어보세요.

블록 저장소 성능 비교

저장소 크기와 성능 요구 사항을 고려해서 인스턴스에 올바른 디스크 유형 및 크기를 결정해야 합니다. 특정 애플리케이션에 대한 성능 요구 사항은 일반적으로 두 가지 고유한 I/O 패턴으로 나뉩니다.

  • 작은 데이터 읽기 및 쓰기
  • 큰 데이터 읽기 및 쓰기

작은 데이터 읽기 및 쓰기의 제한 요인은 임의의 IOPS(초당 입/출력 작업 수)입니다.

큰 데이터 읽기 및 쓰기의 제한 요인은 처리량입니다.

GB당 IOPS 및 처리량 수치는 단일 인스턴스에 연결되어 있거나 여러 인스턴스에서 공유하고 있는지에 관계없이 단일 디스크의 데이터에 대한 총 집계 성능을 나타냅니다. 동일한 디스크에서 여러 인스턴스를 읽는 경우 디스크의 집계 처리량과 IOPS 용량은 인스턴스 간에 공유됩니다. 집계 성능이 더 높게 나타나는 경우 이러한 GB당 IOPS 및 처리 속도를 계획 목적으로 사용하세요.

영역
표준
영구 디스크
리전
표준
영구 디스크
영역
SSD
영구 디스크
리전
SSD
영구 디스크
로컬 SSD(SCSI) 로컬 SSD(NVMe)
최대 지속 IOPS
GB당 읽기 IOPS 0.75 0.75 30 30 266.7 453.3
GB당 쓰기 IOPS 1.5 1.5 30 30 186.7 240
인스턴스당 읽기 IOPS 3,000* 3,000* 15,000 - 60,000* 15,000 - 60,000* 400,000 680,000
인스턴스당 쓰기 IOPS 15,000* 15,000* 15,000 - 30,000* 15,000 - 30,000* 280,000 360,000
최대 지속 처리량(MB/s)
GB당 읽기 처리량 0.12 0.12 0.48 0.48 1.04 1.77
GB당 쓰기 처리량 0.12 0.12 0.48 0.48 0.73 0.94
인스턴스당 읽기 처리량 240* 240* 240 - 1200* 240 - 1200* 1,560 2,650
인스턴스당 쓰기 처리량 76-240** 38-200** 76 - 400* 38 - 200* 1,090 1,400

* 영구 디스크의 IOPS 및 처리량 성능은 인스턴스 vCPU 수 및 IO 블록 크기에 따라 달라집니다. SSD 영구 디스크에 대한 자세한 내용은 SSD 영구 디스크 성능 제한을 참조하고 표준 영구 디스크에 대한 자세한 내용은 표준 영구 디스크 성능 제한을 참조하세요.

** SSD 및 표준 영구 디스크의 경우 vCPU 수를 늘릴수록 인스턴스의 처리량 성능이 향상됩니다. 자세한 내용은 쓰기 처리량의 네트워크 이그레스 상한을 참조하세요.

영구 디스크와 물리적 하드 드라이브 비교

영구 디스크 크기를 지정할 때는 이러한 디스크가 기존의 물리적 하드 드라이브와 어떻게 다른지 고려해야 합니다. 다음 표에서는 일반적으로 75 IOPS 또는 120MB/s를 지원하는 7,200 RPM SATA 드라이브에서 예상할 수 있는 일반적인 성능에 따라 표준 영구 디스크 및 SSD 영구 디스크를 비교해서 보여줍니다.

I/O 유형 IO 패턴 7200 RPM SATA 드라이브에 상응하는 필요 크기
표준 영구 디스크 SSD 영구 디스크
작은 데이터 임의 읽기 75 작은 데이터 임의 읽기 100GB 3GB
작은 데이터 임의 쓰기 75 작은 데이터 임의 쓰기 50GB 3GB
스트리밍 큰 데이터 읽기 120MB/s 스트리밍 읽기 1000GB 250GB
스트리밍 큰 데이터 쓰기 120MB/s 스트리밍 쓰기 1000GB 250GB

크기, 가격, 성능 요약

애플리케이션에 맞는 볼륨 유형 및 크기를 선택할 때는 몇 가지 입력 조건을 고려해야 하지만, 고려할 필요가 없는 요인이 있다면 그건 볼륨 사용 가격입니다. 영구 디스크는 I/O당 비용이 없기 때문에 디스크 지출 예산을 계산하기 위해 월간 I/O를 추정할 필요가 없습니다.

다음 가격 계산 예에서는 미국 내 영구 디스크 가격이 사용됩니다. 이 예에서는 SSD 영구 디스크와 비교되는 표준 영구 디스크의 상대적 비용만 고려합니다. 표준 영구 디스크는 GB당 비용이 $0.040이고, SSD 영구 디스크는 GB당 비용이 $0.170입니다. 하지만 볼륨 크기에 따라 성능 상한이 증가하므로, IOPS 기준 작업 부하의 경우 IOPS당 가격을 살펴봐야 합니다.

표준 영구 디스크는 임의 읽기 IOPS당 비용이 약 $0.053이고 임의 쓰기 IOPS당 비용이 $0.0266입니다. SSD 영구 디스크는 임의 읽기 IOPS당 비용이 $0.0057이고 임의 쓰기 IOPS당 비용이 $0.0057입니다. SSD 영구 디스크의 IOPS당 가격은 인스턴스의 IOPS 한도 또는 해당 인스턴스의 vCPU 수에 도달하는 지점까지만 올라갑니다.

SSD 영구 디스크는 2000GB에서 임의 읽기 IOPS 한도인 60,000에 도달하고, 1000GB에서 임의 쓰기 IOPS 한도인 30,000에 도달합니다. 반면에 표준 영구 디스크는 4TB에서 임의 읽기 IOPS 한도인 3,000에 도달하고 10TB에서 임의 쓰기 IOPS 한도인 15,000에 도달합니다.

SSD 영구 디스크는 1자릿수의 밀리초 지연 시간을 위해 설계되었습니다. 지연 시간은 애플리케이션을 기준으로 관측됩니다.

표준 영구 디스크

표준 영구 디스크 성능은 VM 성능 한도까지 선형적으로 확장됩니다. 인스턴스에서 4개 이상의 vCPU 개수는 표준 영구 디스크의 성능을 제한하지 않습니다.

인스턴스의 vCPU 수가 4개 미만인 경우 vCPU 수에 비례하는 네트워크 이그레스 한도에 의해 제한되므로 특히 IOPS 측면에서 쓰기 제한이 낮아질 수 있습니다. 이 쓰기 제한은 IO의 크기에 따라서도 달라집니다(16KB IO는 동일한 IOPS 수준에서 8KB IO에 비해 더 많은 대역폭을 소비함).

표준 영구 디스크 IOPS와 처리량 성능은 다음과 같은 인스턴스별 한도에 도달할 때까지 디스크 크기에 따라 선형적으로 증가합니다.

  • 읽기 처리량: 2TB 디스크 크기에서 최대 240MB/s
  • 쓰기 처리량: 2TB 디스크 크기에서 최대 240MB/s
  • 읽기 IOPS: 4TB 디스크 크기에서 최대 3,000 IOPS
  • 쓰기 IOPS: 10TB 디스크 크기에서 최대 15,000 IOPS

기존 인스턴스에서 영구 디스크 성능 이점을 얻기 위해서는 영구 디스크 크기를 조정하여 영구 디스크당 IOPS 및 처리량을 늘려야 합니다.

볼륨 크기(GB) 지속 임의 IOPS 지속 처리량(MB/s)
읽기
(<=16KB/IO)
쓰기
(<=8KB/IO)
쓰기
(16KB/IO)
읽기 쓰기
10 * * * * *
32 24 48 48 3 3
64 48 96 96 7 7
128 96 192 192 15 15
256 192 384 384 30 30
512 384 768 768 61 61
1000 750 1500 1500 120 120
1500 1125 2250 2250 180 180
2048 1536 3072 3072 240 240
4000 3000 6000 6000 240 240
5000 3000 7500 7500 240 240
8192 3000 12288 7500 240 240
10000 3000 15000 7500 240 240
16384 3000 15000 7500 240 240
32768 3000 15000 7500 240 240
65536 3000 15000 7500 240 240

* 이 볼륨 크기는 부팅 볼륨에만 사용합니다. 중요한 작업에는 IO 버스트 기능을 사용할 수 있습니다.

SSD 영구 디스크

표준 영구 디스크와 달리 SSD 영구 디스크의 IOPS 성능은 디스크 크기 외에 인스턴스의 vCPU 수에 따라 달라집니다.

코어 VM 수가 적어지면 쓰기 처리량에 적용되는 네트워크 이그레스 한도에 따라 쓰기 IOPS 및 처리량 제한이 줄어듭니다. 자세한 내용은 쓰기 처리량의 네트워크 이그레스 상한 섹션을 참조하세요.

SSD 영구 디스크 성능은 볼륨 한도 또는 각 Compute Engine 인스턴스의 한도에 도달할 때까지 선형적으로 확장됩니다. 최대 한도에 근접한 SSD 읽기 대역폭 또는 IOPS 일관성은 주로 네트워크 인그레스 사용률에 따라 달라집니다. 특히 최대 IOPS 한도에 근접한 16KB IO의 경우 일부 변동이 발생할 수 있습니다. 자세한 내용은 아래 표를 참조하세요.

인스턴스 vCPU 수 지속 임의 IOPS 지속 처리량(MB/s)
읽기
(<=16KB/IO)
쓰기
(<=8KB/IO)
쓰기
(16KB/IO)
읽기* 쓰기
vCPU 1개 15,000 9,000 4,500 240 72
vCPU 2~3개 15,000 15,000 4,500/vCPU 240 72/vCPU
vCPU 4~7개 15,000 15,000 15,000 240 240
vCPU 8~15개 15,000 15,000 15,000 800 400
vCPU 16~31개 25,000 25,000 25,000 1,200 400
vCPU 32~63개 60,000 30,000 25,000 1,200 400
vCPU 64개 이상** 60,000 30,000 25,000 1,200 400

* IO 블록 크기 256KB 이상을 기준으로 한 최대 처리량

** CPU 사용률이 100%이면 최대 성능을 얻지 못할 수 있음

기존 인스턴스에서 SSD 영구 디스크의 성능을 향상시키려면 인스턴스의 머신 유형을 변경하여 VM당 한도를 늘리고 영구 디스크의 크기를 조절하여 영구 디스크당 IOPS와 처리량을 늘립니다.

볼륨 크기(GB) 지속 임의 IOPS 지속 처리량(MB/s)
읽기
(<=16KB/IO)
쓰기
(<=8KB/IO)
쓰기
(16KB/IO)
읽기 쓰기
10 300 300 300 4.8 4.8
32 960 960 960 15 15
64 1920 1920 1920 30 30
128 3840 3840 3840 61 61
256 7680 7680 7680 122 122
500 15000 15000 15000 240 240
834 25000 25000 25000 400 400
1000 30000 30000 25000 480 400
1334 40000 30000 25000 640 400
1667 50000 30000 25000 800 400
2048 60000 30000 25000 983 400
4096 60000 30000 25000 1200 400
8192 60000 30000 25000 1200 400
16384 60000 30000 25000 1200 400
32768 60000 30000 25000 1200 400
65536 60000 30000 25000 1200 400

C2 디스크 한도

컴퓨팅 최적화 머신 유형에는 다른 머신 유형에 대한 한도와는 다른 vCPU당 특정 영구 디스크 한도가 적용됩니다. 이러한 한도는 아래의 표를 참조하세요.

볼륨 크기별 성능은 표준 디스크 성능SSD 디스크 성능 섹션에 설명된 것과 동일하게 유지됩니다.

표준 영구 디스크
인스턴스 vCPU 수 지속 임의 IOPS 지속 처리량(MB/s)
읽기
(<=16KB/IO)
쓰기
(<=8KB/IO)
쓰기
(16KB/IO)
읽기* 쓰기
vCPU 4개 3,000 4,000 4,000 240 240
vCPU 8개 3,000 4,000 4,000 240 240
vCPU 16개 3,000 4,000 4,000 240 240
vCPU 30개 3,000 8,000 8,000 240 240
vCPU 60개 3,000 15,000 15,000 240 240
SSD 영구 디스크
인스턴스 vCPU 수 지속 임의 IOPS 지속 처리량(MB/s)
읽기
(<=16KB/IO)
쓰기
(<=8KB/IO)
쓰기
(16KB/IO)
읽기* 쓰기
vCPU 4개 4,000 4,000 4,000 240 240
vCPU 8개 4,000 4,000 4,000 240 240
vCPU 16개 8,000 4,000 4,000 320 240
vCPU 30개 15,000 8,000 8,000 600 240
vCPU 60개 30,000 15,000 15,000 1,200 400

동시 읽기 및 쓰기

표준 영구 디스크의 경우 동시 읽기 및 쓰기는 동일한 성능 한도를 공유합니다. 인스턴스에 사용되는 읽기 처리량 또는 IOPS가 많을수록 수행 가능한 쓰기 작업 수가 줄어듭니다. 사용되는 쓰기 처리량이 많은 인스턴스는 수행할 수 있는 읽기 작업 수가 줄어듭니다.

SSD 영구 디스크는 동시 읽기 및 쓰기에 대해 최대 처리량 한도를 얻을 수 있습니다. 하지만 IOPS의 경우에는 SSD 영구 디스크가 최대 읽기 및 쓰기 한도에 동시에 도달할 수 없습니다. 동시 읽기 및 쓰기 중 최대 처리량 한도를 달성하기 위해서는 볼륨이 IOPS 병목 지점에 도달하지 않고 처리량 한도를 충족시킬 수 있도록 I/O 크기를 최적화해야 합니다.

동시 읽기 및 쓰기에 대한 인스턴스 IOPS 한도:

다음 표의 IOPS 수치는 8KB IO 크기를 기반으로 합니다. 16KB와 같은 다른 IO 크기의 경우 IOPS 수치가 다를 수 있지만 읽기/쓰기 분배는 동일합니다.

표준 영구 디스크 SSD 영구 디스크(8 vCPU) SSD 영구 디스크(32개 이상 vCPU)
읽기 쓰기 읽기 쓰기 읽기 쓰기
3000 IOPS 0 IOPS 15000 IOPS 0 IOPS 60000 IOPS 0 IOPS
2250 IOPS 3750 IOPS 11250 IOPS 3750 IOPS 45000 IOPS 7500 IOPS
1500 IOPS 7500 IOPS 7500 IOPS 7500 IOPS 30000 IOPS 15000 IOPS
750 IOPS 11250 IOPS 3750 IOPS 11250 IOPS 15000 IOPS 22500 IOPS
0 IOPS 15000 IOPS 0 IOPS 15000 IOPS 0 IOPS 30000 IOPS

동시 읽기 및 쓰기에 대한 인스턴스 처리량 한도:

표준 영구 디스크 SSD 영구 디스크(vCPU 8개) SSD 영구 디스크(16개 이상 vCPU)
읽기 쓰기 읽기 쓰기 읽기 쓰기
240MB/s 0MB/s 800MB/s* 400MB/s* 1200MB/s* 400MB/s*
180MB/s 60MB/s
120MB/s 120MB/s
60MB/s 180MB/s
0MB/s 240MB/s

* SSD 영구 디스크의 경우 최대 읽기 처리량과 최대 쓰기 처리량은 서로 독립적이므로 이러한 제한은 일정합니다. 지속적인 개선에 따라 인스턴스당 SSD 영구 디스크 쓰기 처리량이 게시된 제한보다 높아질 수 있습니다.

쓰기 처리량의 네트워크 이그레스 상한

각 영구 디스크 쓰기 작업은 가상 머신 인스턴스의 누적 네트워크 이그레스 상한에 영향을 줍니다.

가상 머신 인스턴스가 지원할 수 있는 최대 영구 디스크 쓰기 트래픽을 계산하기 위해서는 해당 2Gbit/s/vCPU 네트워크 상한에서 인스턴스의 다른 네트워크 이그레스 트래픽을 차감합니다. 남은 처리량은 영구 디스크 쓰기 트래픽에 사용할 수 있는 처리량을 나타냅니다.

Compute Engine은 영구 디스크에 데이터를 저장하므로 데이터가 내장 중복성을 갖습니다. 인스턴스는 이러한 중복성을 얻기 위해 영구 디스크에 데이터를 병렬로 3회 기록합니다. 또한 각 쓰기 요청에는 이그레스 대역폭 사용에 따른 일정량의 오버헤드가 존재합니다.

각 가상 머신 인스턴스에는 가상 머신의 네트워크 이그레스 상한에 따라 영구 디스크 쓰기 한도가 적용됩니다. 영구 디스크가 네트워크 이그레스를 위해 IP 트래픽과 경합하는 경우에는 네트워크 이그레스 상한의 60%가 영구 디스크 트래픽으로 전달되고 나머지 40%는 IP 트래픽을 위해 남게 됩니다. 다음 표에는 IP 트래픽의 추가 여부에 관계없이 예상되는 영구 디스크 쓰기 대역폭이 나와 있습니다.

표준 영구 디스크 솔리드 스테이트 영구 디스크
vCPU 수 표준 영구 디스크 쓰기 한도(MB/s) 표준 영구 디스크 쓰기 할당(MB/s) 한도 도달에 필요한 표준 볼륨 크기(GB) SSD 영구 디스크 쓰기 한도(MB/s) SSD 영구 디스크 쓰기 할당(MB/s) 한도 도달에 필요한 SSD 영구 디스크 크기(GB)
1 72 43 600 72 43 150
2 144 86 1200 144 86 300
4 240 173 2000 240 173 500
8개 이상 240 240 2000 400 346 834

이 표의 값이 생성된 원리를 이해하기 위해 vCPU가 1개이고 표준 영구 디스크가 사용된 간단한 예를 사용해 보겠습니다. 이 예시에서는 모든 쓰기 요청의 대역폭 배수가 3.3이라고 가정합니다. 즉, 데이터가 3회 기록되고 총 10%의 오버헤드를 갖습니다. 이그레스 상한을 계산하기 위해서는 네트워크 이그레스 상한인 2Gbit/s(238MB/s와 동일)를 3.3으로 나눕니다.

vCPU 1개의 최대 쓰기 대역폭 = 238 / 3.3 = 표준 영구 디스크에 대해 최대 72MB/s

또한 위의 성능 차트에 제공된 표준 영구 디스크 쓰기 처리량/GB 수치를 사용하면 이러한 성능을 얻기 위해 필요한 디스크 용량을 계산할 수 있습니다.

vCPU 1개의 최대 쓰기 대역폭을 얻기 위해 필요한 디스크 용량 = 72 / 0.12 = 최대 600GB

영역 영구 디스크와 마찬가지로 리전 영구 디스크의 쓰기 트래픽은 가상 머신 인스턴스의 누적 네트워크 이그레스 상한에 영향을 줍니다. 리전 영구 디스크에서 사용 가능한 이그레스 네트워크를 계산하기 위해서는 영역 영구 디스크에 사용되는 3.3 대신 6.6을 계수로 사용합니다.

vCPU 1개의 최대 쓰기 대역폭 = 238 / 6.6 = 표준 복제된 영구 디스크에 대해 최대 36MB/s

영구 디스크 및 로컬 SSD 성능 최적화

영구 디스크 및 로컬 SSD를 최적화하여 데이터를 보다 효율적으로 처리할 수 있습니다.

영구 디스크 최적화

영구 디스크는 디스크 유형 차트에 기술된 성능을 제공하지만, 가상 머신은 성능 상한에 도달하기 위해 사용량을 충분히 늘려야 합니다. 성능 요구에 맞게 영구 디스크 볼륨 크기를 적절하게 조정한 후에는 애플리케이션 및 운영체제에 일부 조정이 필요할 수 있습니다

이 섹션에서는 성능 향상을 위해 조정할 수 있는 몇 가지 주요 요소들을 살펴보고 특정 유형의 작업 부하에 이를 적용하는 방법에 대해 설명합니다.

지연 초기화 중지 및 DISCARD 명령 사용

영구 디스크에서는 블록이 더 이상 사용되지 않을 때 운영체제가 디스크에 이를 알릴 수 있게 해주는 DISCARD 또는 TRIM 명령이 지원됩니다. DISCARD 지원을 통해서는 운영체제가 블록을 제로로 만드는 비용 없이 디스크 블록을 더 이상 필요하지 않은 것으로 표시할 수 있습니다.

대부분의 Linux 운영체제에서는 인스턴스에 영구 디스크를 마운트할 때 DISCARD를 사용하도록 설정합니다. Windows 2012 R2 인스턴스에서는 영구 디스크를 마운트할 때 기본적으로 DISCARD가 사용으로 설정됩니다. Windows 2008 R2에서는 DISCARD가 지원되지 않습니다.

DISCARD를 사용하도록 설정하면 일반적인 런타임 성능이 향상되며, 처음 마운트될 때 디스크의 성능이 크게 향상될 수 있습니다. 전체 디스크 볼륨을 포맷하기 위해서는 시간이 오래 걸릴 수 있습니다. 따라서 '지연 포맷'이라는 방식이 일반적으로 사용됩니다. 지연 포맷의 단점은 볼륨이 마운트되는 최초에 비용이 자주 지불된다는 것입니다. 지연 초기화를 중지하고 DISCARD 명령어를 사용하면 포맷 및 마운트를 빠르게 수행할 수 있습니다.

  • 다음 매개변수를 mkfs.ext4로 전달하여 포맷 중 지연 초기화를 중지하고 DISCARD를 사용합니다.

    -E lazy_itable_init=0,lazy_journal_init=0,discard
    

    lazy_journal_init=0 매개변수는 CentOS 6 또는 RHEL 6 이미지를 사용하는 인스턴스에서는 작동하지 않습니다. 이러한 인스턴스에서는 이 매개변수 없이 영구 디스크를 포맷합니다.

    -E lazy_itable_init=0,discard
    
  • 마운트 시에 DISCARD 명령어를 사용하고 다음 플래그를 마운트 명령어에 전달합니다.

    -o discard
    

영구 디스크는 discard 옵션이 사용된 상태에서 제대로 작동합니다. 하지만 discard 옵션을 사용하는 것 외에 추가로 또는 이를 사용하지 않은 상태로 선택적으로 fstrim을 주기적으로 실행할 수 있습니다. discard 옵션을 사용하지 않을 경우에는 디스크 스냅샷을 만들기 전에 fstrim을 실행합니다. 파일 시스템을 자르면 더 작은 스냅샷 이미지를 만들어서 스냅샷 저장 비용을 줄일 수 있습니다.

I/O 큐 깊이

많은 애플리케이션에는 성능 조정을 위해 해당 I/O 큐 깊이에 영향을 주는 설정이 사용됩니다. 큐가 깊을수록 IOPS가 늘어나지만 지연 시간도 늘어날 수 있습니다. 큐가 얕을수록 IO당 지연 시간이 줄어들지만 IOPS도 줄어듭니다.

미리읽기 캐시

I/O 성능 향상을 위해 운영체제에서는 파일 읽기가 요청될 때 후속 데이터도 읽기가 요청될 가능성이 있다는 가정에 따라 요청된 것보다 많은 양의 파일을 메모리로 읽어들이는 미리읽기와 같은 기법이 사용됩니다. 미리읽기 양이 늘어날수록 처리량이 향상되지만 메모리 및 IOPS 효율이 낮아집니다. 미리읽기 양이 줄어들면 IOPS가 높아지지만 처리량이 줄어듭니다.

Linux 시스템의 경우 blockdev 명령을 사용하여 미리읽기 값을 가져오고 설정할 수 있습니다.

$ sudo blockdev --getra /dev/[DEVICE_ID]
$ sudo blockdev --setra [VALUE] /dev/[DEVICE_ID]

미리읽기 값은 <desired_readahead_bytes>/512바이트입니다.

예를 들어 미리읽기를 8MB로 지정할 경우, 8MB는 8388608바이트(8 * 1024 * 1024)입니다.

8388608 bytes / 512 bytes = 16384

그런 후 다음과 같이 설정합니다.

$ sudo blockdev --setra 16384 /dev/[DEVICE_ID]

사용 가능한 CPU

영구 디스크에 대해 읽기 및 쓰기를 하려면 가상 머신에서 CPU 주기를 사용할 수 있어야 합니다. 매우 높고 일관성 있는 IOPS 수준을 달성하려면 I/O 처리를 위해 사용 가능한 CPU가 필요합니다.

IOPS 기준의 작업 부하

SQL 또는 NoSQL에 관계없이 데이터베이스는 데이터에 대한 임의 액세스 사용 패턴을 갖고 있습니다. IOPS를 기준으로 한 작업 부하에 권장되는 사항은 다음과 같습니다.

  • MongoDB, Apache Cassandra, 기타 데이터베이스 애플리케이션의 권장사항 문서에서는 일반적으로 낮은 미리읽기 값이 권장됩니다.

  • 각 400-800 IOPS당 I/O 큐 깊이 1, 대규모 볼륨에서 최대 한도 64

  • 임의 읽기 IOPS 2000당 사용 가능한 CPU 1개 및 임의 쓰기 IOPS 2500당 사용 가능한 CPU 1개

처리량 기준의 작업 부하

Hadoop 작업과 같은 스트리밍 작업은 빠른 순차적 읽기가 유용합니다. 따라서 I/O 크기가 클수록 스트리밍 성능이 향상될 수 있습니다. 처리량을 기준으로 한 작업 부하의 경우에는 256KB 이상의 I/O 크기가 권장됩니다.

SSD 영구 디스크 성능 최적화

디스크 유형별 성능 차트에서는 솔리드 스테이트 영구 디스크에서 얻을 수 있는 예상 성능 한도를 보여줍니다. 이러한 속도를 얻기 위해 애플리케이션 및 가상 머신 인스턴스를 최적화하기 위해서는 다음 권장사항을 따르세요.

  • 애플리케이션이 충분한 I/O를 실행 중인지 확인합니다.

    애플리케이션이 위 차트에 표시된 한도보다 낮은 IOPS를 실행 중이면 해당 IOPS 수준에 도달할 수 없습니다. 예를 들어 500GB 디스크에서 예상 IOPS 한도는 15,000 IOPS입니다. 하지만 실행 수치가 이보다 낮거나 실행되는 I/O 작업 크기가 8KB보다 크면 15,000 IOPS를 달성할 수 없습니다.

  • 충분한 병렬 처리를 사용해서 I/O를 실행합니다.

    운영체제의 병렬처리를 활용하기에 충분히 높은 큐 깊이를 사용합니다. 1000 IOPS를 실행하지만 큐 깊이가 1인 상태에서 동기식으로 수행할 경우, 차트에 설명된 한도보다 IOPS가 훨씬 낮아집니다. 최소한 애플리케이션의 큐 깊이가 400-800 IOPS당 최소 1 이상이어야 합니다.

  • I/O를 실행하는 가상 머신 인스턴스에서 사용 가능한 CPU가 충분한지 확인합니다.

    가상 머신 인스턴스에 CPU가 부족한 경우 애플리케이션이 위에 설명된 IOPS를 관리할 수 없습니다. 일반적으로 2,000에서 2,500개에 해당하는 예상 트래픽 IOPS 수마다 하나의 CPU를 사용할 수 있어야 합니다.

  • 큰 디스크에서 합리적인 수준의 일시적 데이터 지역성에 맞게 애플리케이션을 최적화합니다.

    애플리케이션이 장시간에 걸쳐 디스크의 여러 부분에 분산되어 있는 데이터에 액세스할 경우(vCPU당 수백 GB), 최적의 IOPS를 얻을 수 없습니다. 최상의 성능을 위해서는 디스크 단편화, 디스크에서 액세스되는 부분의 임의성과 같은 요소들을 고려해서 일시적인 데이터 지역성에 맞게 최적화해야 합니다.

  • 운영체제에서 I/O 스케줄러가 특정 요구를 충족하도록 구성되었는지 확인합니다.

    Linux 기반 시스템에서는 I/O 스케줄러를 noop로 설정하여 SSD 지원 장치에서 가장 높은 IOPS 수를 얻을 수 있습니다.

SSD 영구 디스크 성능 벤치마킹

아래 명령어는 장치가 2,500GB의 PD-SSD라고 가정합니다. 장치 크기가 이와 다를 경우에는 --filesize 인수를 수정하세요. 이 디스크 크기는 vCPU가 32개인 VM의 현재 처리량 한도를 달성하는 데 필요합니다.

    # Install dependencies
    sudo apt-get update
    sudo apt-get install -y fio
  1. 디스크에 0이 아닌 데이터를 채웁니다. 빈 블록에서의 영구 디스크 읽기는 데이터를 포함하는 블록에서의 읽기와 지연 시간 프로필이 다릅니다. 모든 읽기 지연 시간 벤치마크를 실행하기 전에 디스크를 채우는 것이 좋습니다.

    # Running this command will cause you to lose data on the second device.
    # We strongly recommend using a throwaway VM and disk.
    sudo fio --name=fill_disk \
      --filename=/dev/sdb --filesize=2500G \
      --ioengine=libaio --direct=1 --verify=0 --randrepeat=0 \
      --bs=128K --iodepth=64 --rw=randwrite
    
  2. I/O 크기가 1MB이고 I/O 깊이가 64 이상인 동시 스트림이 여러 개(8 이상)인 경우 순차적 쓰기를 사용하여 쓰기 대역폭을 테스트합니다.

    # Running this command will cause you to lose data on the second device.
    # We strongly recommend using a throwaway VM and disk.
    sudo fio --name=write_bandwidth_test \
      --filename=/dev/sdb --filesize=2500G \
      --time_based --ramp_time=2s --runtime=1m \
      --ioengine=libaio --direct=1 --verify=0 --randrepeat=0 \
      --bs=1M --iodepth=64 --rw=write --numjobs=8
    
  3. 쓰기 IOPS를 테스트합니다. PD IOPS 한도를 달성하기 위해서는 깊은 I/O 큐를 유지하는 것이 중요합니다. 예를 들어 쓰기 지연 시간이 1밀리초인 경우 VM이 처리 중인 각 I/O에 대해 최대 1,000의 IOPS를 달성할 수 있습니다. 15,000 IOPS를 달성하기 위해서는 VM이 처리 중인 I/O를 최소한 15 이상으로 유지해야 합니다. 디스크 및 VM이 30,000 IOPS를 달성할 수 있는 경우 처리되는 I/O 수는 최소 30개 이상이어야 합니다. I/O 크기가 4KB보다 큰 경우에는 IOPS 한도에 도달하기 전에 VM이 대역폭 제한에 걸릴 수 있습니다.

    # Running this command will cause you to lose data on the second device.
    # We strongly recommend using a throwaway VM and disk.
    sudo fio --name=write_iops_test \
      --filename=/dev/sdb --filesize=2500G \
      --time_based --ramp_time=2s --runtime=1m \
      --ioengine=libaio --direct=1 --verify=0 --randrepeat=0 \
      --bs=4K --iodepth=64 --rw=randwrite
    
  4. 쓰기 지연 시간을 테스트합니다. I/O 지연 시간을 테스트할 때는 VM이 대역폭 또는 IOPS 제한에 도달하지 않도록 하는 것이 중요합니다. 그렇지 않으면 지연 시간에 실제 영구 디스크 I/O 지연 시간이 반영되지 않습니다. 예를 들어 I/O 깊이 30에서 IOPS 제한에 도달하고 fio 명령어 시간이 두 배가 될 경우, 총 IOPS는 동일하게 유지되고 보고되는 I/O 지연 시간이 두 배가 됩니다.

    # Running this command will cause you to lose data on the second device.
    # We strongly recommend using a throwaway VM and disk.
    sudo fio --name=write_latency_test \
      --filename=/dev/sdb --filesize=2500G \
      --time_based --ramp_time=2s --runtime=1m \
      --ioengine=libaio --direct=1 --verify=0 --randrepeat=0 \
      --bs=4K --iodepth=4 --rw=randwrite
    
  5. I/O 크기가 1MB이고 I/O 깊이가 64 이상인 동시 스트림이 여러 개(8 이상)인 경우 순차적 읽기를 사용하여 읽기 대역폭을 테스트합니다.

    sudo fio --name=read_bandwidth_test \
      --filename=/dev/sdb --filesize=2500G \
      --time_based --ramp_time=2s --runtime=1m \
      --ioengine=libaio --direct=1 --verify=0 --randrepeat=0 \
      --bs=1M --iodepth=64 --rw=read --numjobs=8
    
  6. 읽기 IOPS를 테스트합니다. PD IOPS 한도를 달성하기 위해서는 충분히 깊은 I/O 큐를 유지하는 것이 중요합니다. IO 크기가 4KB보다 큰 경우에는 IOPS 한도에 도달하기 전에 VM이 대역폭 제한에 걸릴 수 있습니다.

    sudo fio --name=read_iops_test \
      --filename=/dev/sdb --filesize=2500G \
      --time_based --ramp_time=2s --runtime=1m \
      --ioengine=libaio --direct=1 --verify=0 --randrepeat=0 \
      --bs=4K --iodepth=64 --rw=randread
    
  7. 읽기 지연 시간을 테스트합니다. 실질적으로 지연 시간을 측정하기 위해서는 디스크에 데이터를 채우는 것이 중요합니다. 이 테스트 중에는 VM이 IOPS 또는 처리량 제한에 도달하지 않는 것이 중요합니다. 영구 디스크가 포화 제한에 도달한 다음에는 수신되는 IO를 밀어내고 이로 인해 IO 지연 시간이 인위적으로 증가합니다.

    sudo fio --name=read_latency_test \
      --filename=/dev/sdb --filesize=2500G \
      --time_based --ramp_time=2s --runtime=1m \
      --ioengine=libaio --direct=1 --verify=0 --randrepeat=0 \
      --bs=4K --iodepth=4 --rw=randread
    
  8. 순차적 읽기 대역폭을 테스트합니다.

    sudo fio --name=read_bandwidth_test \
      --filename=/dev/sdb --filesize=2500G \
      --time_based --ramp_time=2s --runtime=1m \
      --ioengine=libaio --direct=1 --verify=0 --randrepeat=0 \
      --numjobs=4 --thread --offset_increment=500G \
      --bs=1M --iodepth=64 --rw=read
    
  9. 순차적 쓰기 대역폭을 테스트합니다.

    sudo fio --name=write_bandwidth_test \
      --filename=/dev/sdb --filesize=2500G \
      --time_based --ramp_time=2s --runtime=1m \
      --ioengine=libaio --direct=1 --verify=0 --randrepeat=0 \
      --numjobs=4 --thread --offset_increment=500G \
      --bs=1M --iodepth=64 --rw=write
    

로컬 SSD 최적화

디스크 유형별 성능 차트에서는 로컬 SSD 장치에서 달성할 수 있는 예상 성능 제한을 설명합니다. 이러한 속도를 얻기 위해 애플리케이션 및 가상 머신 인스턴스를 최적화하기 위해서는 다음 권장사항을 따르세요.

로컬 SSD에 게스트 환경 최적화 사용

기본적으로 대부분의 Compute Engine에서 제공되는 Linux 이미지는 최대 로컬 SSD 성능에 맞게 인스턴스를 구성하는 최적화 스크립트를 자동으로 실행합니다. 이 스크립트는 특정 큐 sysfs 파일 설정을 사용하여 머신의 전체 성능을 향상시키고 특정 가상 CPU(vCPU)에 대한 인터럽트 요청(IRQ)을 마스킹합니다. 이 스크립트는 Compute Engine 로컬 SSD 장치의 성능만 최적화합니다.

Ubuntu, SLES, 이전 이미지는 이 성능 최적화를 포함하도록 구성할 수 없습니다. 이러한 이미지 또는 v20141218 이전의 이미지를 사용 중인 경우에는 게스트 환경을 설치하여 해당 최적화를 대신 사용할 수 있습니다.

NVMe 또는 SCSI 인터페이스에 최상의 이미지 선택

로컬 SSD는 인스턴스의 부팅 디스크에서 사용하는 이미지에 따라 NVMe 또는 SCSI 인터페이스 유형에서 작동 효율이 가장 높습니다. 부팅 디스크 이미지에서 가장 잘 작동하는 로컬 SSD 장치의 인터페이스를 선택하세요. 인스턴스가 SCSI 인터페이스를 사용하여 로컬 SSD에 연결되는 경우, 게스트 운영체제에서 다중 큐 SCSI를 사용해서 SCSI 인터페이스에 대해 최적 성능을 달성할 수 있습니다.

커스텀 이미지 및 로컬 SSD를 포함하는 인스턴스에서 다중 큐 SCSI 사용

일부 공개 이미지는 다중 큐 SCSI를 지원합니다. 프로젝트로 가져오는 커스텀 이미지에 다중 큐 SCSI 기능이 필요한 경우, 이를 직접 사용 설정해야 합니다. 가져온 Linux 이미지는 커널 버전 3.19 이상을 포함하는 경우에만 다중 큐 SCSI를 사용할 수 있습니다.

커스텀 이미지에서 다중 큐 SCSI를 사용하도록 설정하려면 VIRTIO_SCSI_MULTIQUEUE 게스트 운영체제 기능이 설정된 상태로 이미지를 가져오고 GRUB 구성 파일에 항목을 추가합니다.

CentOS

CentOS7만 해당합니다.

  1. API를 사용하여 커스텀 이미지를 가져오고 type 값이 VIRTIO_SCSI_MULTIQUEUEguestOsFeatures 항목을 포함합니다.

  2. 커스텀 이미지를 사용해서 인스턴스를 만들고 하나 이상의 로컬 SSD를 연결합니다.

  3. SSH를 통해 인스턴스에 연결합니다.

  4. /sys/module/scsi_mod/parameters/use_blk_mq 파일의 값을 확인합니다.

    $ cat /sys/module/scsi_mod/parameters/use_blk_mq
    

    이 파일의 값이 Y이면 가져온 이미지에 다중 큐 SCSI가 이미 사용된 것입니다. 이 파일의 값이 N이면 GRUB 구성 파일의 GRUB_CMDLINE_LINUX 항목에 scsi_mod.use_blk_mq=Y를 포함시키고 시스템을 다시 시작합니다.

    1. 텍스트 편집기에서 /etc/default/grub GRUB 구성 파일을 엽니다.

      $ sudo vi /etc/default/grub
      
    2. GRUB_CMDLINE_LINUX 항목에 scsi_mod.use_blk_mq=Y를 추가합니다.

      GRUB_CMDLINE_LINUX=" vconsole.keymap=us console=ttyS0,38400n8 vconsole.font=latarcyrheb-sun16 scsi_mod.use_blk_mq=Y"
      
    3. 구성 파일을 저장합니다.

    4. grub2-mkconfig 명령어를 실행하여 GRUB 파일을 다시 생성하고 구성을 완료합니다.

      $ sudo grub2-mkconfig -o /boot/grub2/grub.cfg
      
    5. 인스턴스를 재부팅합니다.

      $ sudo reboot
      

Ubuntu

  1. API를 사용하여 커스텀 이미지를 가져오고 type 값이 VIRTIO_SCSI_MULTIQUEUEguestOsFeatures 항목을 포함합니다.

  2. 커스텀 이미지를 사용하여 인스턴스를 만들고 SCSI 인터페이스를 사용하여 하나 이상의 로컬 SSD를 연결합니다.

  3. SSH를 통해 인스턴스에 연결합니다.

  4. /sys/module/scsi_mod/parameters/use_blk_mq 파일의 값을 확인합니다.

    $ cat /sys/module/scsi_mod/parameters/use_blk_mq
    

    이 파일의 값이 Y이면 가져온 이미지에 다중 큐 SCSI가 이미 사용된 것입니다. 이 파일의 값이 N이면 GRUB 구성 파일의 GRUB_CMDLINE_LINUX 항목에 scsi_mod.use_blk_mq=Y를 포함시키고 시스템을 다시 시작합니다.

    1. 텍스트 편집기에서 sudo nano /etc/default/grub GRUB 구성 파일을 엽니다.

      $ sudo nano /etc/default/grub
      
    2. GRUB_CMDLINE_LINUX 항목에 scsi_mod.use_blk_mq=Y를 추가합니다.

      GRUB_CMDLINE_LINUX="scsi_mod.use_blk_mq=Y"
      
    3. 구성 파일을 저장합니다.

    4. update-grub 명령어를 실행하여 GRUB 파일을 다시 생성하고 구성을 완료합니다.

      $ sudo update-grub
      
    5. 인스턴스를 재부팅합니다.

      $ sudo reboot
      

캐시 비우기로 쓰기 중지

파일 시스템, 데이터베이스, 기타 애플리케이션은 여러 체크포인트에서 데이터가 내구성 저장소에 커밋되었는지 확인하기 위해 캐시 비우기를 사용합니다. 대부분의 저장 장치에서는 이러한 기본값이 적합합니다. 하지만 쓰기 캐시 비우기는 로컬 SSD에서 상당히 느리게 수행됩니다. 일부 애플리케이션에서는 해당 애플리케이션에서 자동 비우기 명령을 중지하거나 파일 시스템 수준에서 비우기 옵션을 중지하여 쓰기 성능을 늘릴 수 있습니다.

로컬 SSD는 파일 시스템 및 애플리케이션에 대해 사용자가 설정한 비우기 명령에 관계없이 항상 2초 내에 캐시된 쓰기를 비우므로, 일시적인 하드웨어 오류가 발생하더라도 기껏해야 2초 분량의 캐시된 쓰기만 손실될 수 있습니다. 영구적인 하드웨어 오류가 발생하면 데이터가 삭제되는지 여부에 관계없이 기기에 있는 모든 데이터가 손실될 수 있으므로 중요한 데이터는 영구 디스크 또는 Cloud Storage 버킷에 백업해야 합니다.

ext4 파일 시스템에서 쓰기 캐시 비우기를 사용 중지하려면 마운트 옵션 또는 /etc/fstab 항목에 nobarrier를 포함해야 합니다. 예를 들면 다음과 같습니다.

$ sudo mount -o discard,defaults,nobarrier /dev/[LOCAL_SSD_ID] /mnt/disks/[MNT_DIR]

설명: [LOCAL_SSD_ID]는 마운트하려는 로컬 SSD의 장치 ID입니다.

로컬 SSD 성능 벤치마킹

성능 섹션에 제공된 로컬 SSD 성능 수치는 로컬 SSD 인스턴스에서의 특정 설정을 사용하여 가져온 것입니다. 인스턴스가 이러한 성능 한도에 도달하는 데 문제가 있고, 권장 로컬 SSD 설정을 사용하여 인스턴스를 이미 구성한 경우에는 Compute Engine팀에서 사용된 설정을 복제하여 게시된 한도와 사용자의 성능 한도를 비교할 수 있습니다.

  1. 작업 부하에 따라 각 장치에 대해 4개 또는 8개의 vCPU를 포함하는 로컬 SSD 인스턴스를 만듭니다. 예를 들어 하나의 인스턴스에 4개의 로컬 SSD 장치를 연결하려는 경우 vCPU가 16개 또는 32개 포함된 머신 유형을 사용합니다.

    다음 명령어는 8개의 vCPU와 단일 로컬 SSD를 포함하는 가상 머신을 만듭니다.

    gcloud compute instances create ssd-test-instance \
    --machine-type "n1-standard-8" \
    --local-ssd interface="SCSI"
    
  2. 머신에서 다음 스크립트를 실행하여 해당 속도를 달성하기 위해 사용되는 설정을 복제합니다. --bs 매개변수는 여러 유형의 읽기 및 쓰기 작업 결과에 영향을 주는 블록 크기를 정의합니다.

    # install dependencies
    sudo apt-get update -y
    sudo apt-get install -y build-essential git libtool gettext autoconf \
    libgconf2-dev libncurses5-dev python-dev fio bison autopoint
    
    # blkdiscard
    git clone https://git.kernel.org/pub/scm/utils/util-linux/util-linux.git
    cd util-linux/
    ./autogen.sh
    ./configure --disable-libblkid
    make
    sudo mv blkdiscard /usr/bin/
    sudo blkdiscard /dev/disk/by-id/google-local-ssd-0
    
    # full write pass - measures write bandwidth with 1M blocksize
    sudo fio --name=writefile --size=100G --filesize=100G \
    --filename=/dev/disk/by-id/google-local-ssd-0 --bs=1M --nrfiles=1 \
    --direct=1 --sync=0 --randrepeat=0 --rw=write --refill_buffers --end_fsync=1 \
    --iodepth=200 --ioengine=libaio
    
    # rand read - measures max read IOPS with 4k blocks
    sudo fio --time_based --name=benchmark --size=100G --runtime=30 \
    --filename=/dev/disk/by-id/google-local-ssd-0 --ioengine=libaio --randrepeat=0 \
    --iodepth=128 --direct=1 --invalidate=1 --verify=0 --verify_fatal=0 \
    --numjobs=4 --rw=randread --blocksize=4k --group_reporting
    
    # rand write - measures max write IOPS with 4k blocks
    sudo fio --time_based --name=benchmark --size=100G --runtime=30 \
    --filename=/dev/disk/by-id/google-local-ssd-0 --ioengine=libaio --randrepeat=0 \
    --iodepth=128 --direct=1 --invalidate=1 --verify=0 --verify_fatal=0 \
    --numjobs=4 --rw=randwrite --blocksize=4k --group_reporting
    

다음 단계

이 페이지가 도움이 되었나요? 평가를 부탁드립니다.

다음에 대한 의견 보내기...

Compute Engine 문서