EBS ボリューム初期化を最小の手間で実行するスクリプトを作った
全然関係ないけど最近懸垂にハマってます、那須です。
AMI やスナップショットから EBS ボリュームを作成した場合、ストレージブロックはまだ S3 にあります。 なので何もせずに使うと「あれ?なんか遅いな…」と思うことになりますよね。 それを解消するために EBS ボリュームの初期化を行うわけです。 EBS ボリューム初期化って何よ?って方は↓このドキュメントを読んでください。
で、このドキュメントの手順を見てみると、
という流れですが、wmic で出てきたデバイス ID をコピペして dd や fio の引数として指定するのはなんか面倒ですね。 それが数デバイスだったらまだいいんですが、10個近くなるとだいぶテンション下がります。
私の周りの方に聞く限り、EC2 インスタンスのバックアップは AMI 作成で対応されている方がほとんどだったので、EBS ボリューム初期化も全デバイスに行うことになるはずです。 それなら、手順って 1 つにできるんじゃない?
スクリプト実行するだけにしよう
全デバイス ID を取ってきてそれを引数に使ってコマンド実行するスクリプトを作りました。 wmic の代わりに (Get-WmiObject Win32_DiskDrive).deviceid でデバイス ID を取ってます。 dd 実行スクリプトはこんな感じ。
$dd_path = "'C:\dd.exe'" [System.Collections.ArrayList]$processes = @() foreach ($deviceid in (Get-WmiObject Win32_DiskDrive).deviceid) { $command1 = "$dd_path if=$deviceid of=/dev/null bs=1M --progress --size" $command2 = "Write-Host $command1" $dd_process = Start-Process -FilePath powershell.exe -ArgumentList "& $command2; & $command1" -PassThru $processes.Add($dd_process) } foreach ($dd_process in $processes) { Wait-Process -InputObject $dd_process Get-Process -InputObject $dd_process } Write-Host "Initializing Amazon EBS Volumes finished!"
fio 実行スクリプトはこんな感じ。
$fio_path = "'C:\Program Files\fio\fio.exe'" [System.Collections.ArrayList]$processes = @() foreach ($deviceid in (Get-WmiObject Win32_DiskDrive).deviceid) { $command1 = "$fio_path --filename=$deviceid --rw=read --bs=128k --iodepth=32 --direct=1 --name=volume-initialize" $command2 = "Write-Host $command1" $dd_process = Start-Process -FilePath powershell.exe -ArgumentList "& $command2; & $command1" -PassThru $processes.Add($dd_process) } foreach ($dd_process in $processes) { Wait-Process -InputObject $dd_process Get-Process -InputObject $dd_process } Write-Host "Initializing Amazon EBS Volumes finished!"
よく見るとわかりますが、コマンド部分が違うだけなので function でいい感じにしようと思えばできますが、そんなに頻繁に使わないのでこれでいいかなーと…
このスクリプトを対象インスタンスに置いといて、リストアした時に上記のスクリプトを実行するだけで EBS ボリューム初期化ができます。 EC2 インスタンス作成時であれば、ユーザデータにこのスクリプトを実行するように書けばさらに手間を減らせますね。
実際に実行すると、各デバイスごとに PowerShell ウィンドウが開いてコマンド実行するようになってます。
スクリプト実行したウィンドウでは、↓こんな感じの出力になります。 特に意識してログ等は出してないですが、必要に応じてログを出したりすることもできますよ。
PS C:\Users\Administrator> C:\exec_dd.ps1 0 1 2 Handles NPM(K) PM(K) WS(K) CPU(s) Id SI ProcessName ------- ------ ----- ----- ------ -- -- ----------- 0 0 0 5.66 1448 0 0 0 5.97 1816 0 0 0 5.89 1068 Initializing Amazon EBS Volumes finished!
PS C:\Users\Administrator> C:\exec_fio.ps1 0 1 2 Handles NPM(K) PM(K) WS(K) CPU(s) Id SI ProcessName ------- ------ ----- ----- ------ -- -- ----------- 0 0 0 5.67 3612 0 0 0 5.92 3628 0 0 0 6.00 380 Initializing Amazon EBS Volumes finished!
感想
あんまりしない作業なので毎回ドキュメントを見て思い出してやってましたが、これでドキュメントを見ずにすみます。 でも本当にあまりやらない作業なのでここまでする必要があったのかどうかは疑問が残りますが、PowerShell のお勉強をしたと思って積極的に使っていこうと思いました。