AMIから構築したEC2は最初EBSが遅い、プレウォーミングが必要

EC2をAMIから構築したところ、ディスク(EBS)が遅い。CloudWatchでもキュー長が増加してしまっていました。

問い合わせたところ、AMI からEC2インスタンスを作成した場合、各 EBSボリュームは スナップショットからリストアした際と同様、データは S3 がダウンロードされるため、未ダウンロードのブロックにアクセスした場合には EBS で大きな Latencyが発生するようです。

新規に作成したEBSボリュームにおいてはプレウォーミングは不要です。

ちゃんとドキュメントにも書いてありました。

docs.aws.amazon.com

ウォームアップ方法

以下、ウォームアップ(事前ウォーミングとかPre-Warmingとか言われている)をする方法です。

まずは対象のディスクを確認。

$ lsblk
NAME            MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
xvda            202:0    0   80G  0 disk
├─xvda1         202:1    0  500M  0 part /boot
...

実際にどれくらい時間がかかるか 上記の80GB 汎用SSD(gp2)のEBSの例です。

ddを使った場合

# time dd if=/dev/xvda of=/dev/null bs=1M
81920+0 レコード入力
81920+0 レコード出力
85899345920 バイト (86 GB) コピーされました、 4467.6 秒、 19.2 MB/秒
real    74m27.608s
user    0m0.036s
sys     0m26.619s

fioの場合

# time fio --filename=/dev/xvda --rw=read --bs=128k --iodepth=32 --ioengine=libaio --direct=1 --name=volume-initialize
volume-initialize: (g=0): rw=read, bs=128K-128K/128K-128K/128K-128K, ioengine=libaio, iodepth=32
fio-2.2.8
Starting 1 process
Jobs: 1 (f=1): [R(1)] [100.0% done] [91648KB/0KB/0KB /s] [716/0/0 iops] [eta 00m:00s]
volume-initialize: (groupid=0, jobs=1): err= 0: pid=4017: Tue May  9 18:26:11 2017
  read : io=81920MB, bw=20012KB/s, iops=156, runt=4191689msec
    slat (usec): min=6, max=460, avg=15.17, stdev= 3.79
    clat (usec): min=439, max=5222.9K, avg=204655.34, stdev=255346.64
     lat (usec): min=450, max=5222.9K, avg=204670.76, stdev=255347.34
    clat percentiles (msec):
     |  1.00th=[    4],  5.00th=[   39], 10.00th=[   45], 20.00th=[   45],
     | 30.00th=[   45], 40.00th=[   45], 50.00th=[  122], 60.00th=[  192],
     | 70.00th=[  245], 80.00th=[  310], 90.00th=[  457], 95.00th=[  668],
     | 99.00th=[ 1254], 99.50th=[ 1516], 99.90th=[ 2180], 99.95th=[ 2540],
     | 99.99th=[ 3359]
    bw (KB  /s): min=  283, max=282624, per=100.00%, avg=20704.57, stdev=26483.62
    lat (usec) : 500=0.01%, 750=0.01%, 1000=0.01%
    lat (msec) : 2=0.02%, 4=1.46%, 10=1.15%, 20=0.52%, 50=41.24%
    lat (msec) : 100=3.85%, 250=22.66%, 500=20.54%, 750=4.61%, 1000=1.95%
    lat (msec) : 2000=1.84%, >=2000=0.16%
  cpu          : usr=0.03%, sys=0.35%, ctx=655140, majf=0, minf=546
  IO depths    : 1=0.1%, 2=0.1%, 4=0.1%, 8=0.1%, 16=0.1%, 32=100.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.1%, 64=0.0%, >=64=0.0%
     issued    : total=r=655360/w=0/d=0, short=r=0/w=0/d=0, drop=r=0/w=0/d=0
     latency   : target=0, window=0, percentile=100.00%, depth=32

Run status group 0 (all jobs):
   READ: io=81920MB, aggrb=20012KB/s, minb=20012KB/s, maxb=20012KB/s, mint=4191689msec, maxt=4191689msec

Disk stats (read/write):
  xvda: ios=655258/954, merge=0/51, ticks=134111557/394258, in_queue=134506630, util=100.00%
real 69m53.280s
user    0m2.753s
sys 0m19.730s

今回は fio 使った方が早くウォームアップ処理が終わりました。進捗状況がわかる分 fio の方が良いかもしれないです。

dd fio のどちらにしろ、かなり時間がかかる処理なので必ずしも全てのディスクをウォームアップする必要はありません。

以下の時間などを参考にディスクを切り方考えたり、どこまでウォームアップさせるか考える必要があります。またはEBSのお金を払えるならEC2を事前準備しておくとかも考慮の余地ありかも。