Contents
■はじめに
Azure の仮想マシン (VM) 上で SQL Server を稼働させた際の情報は様々な情報が公開されていますが、まずは確認すべき情報を整理しておきたいと思います。
– 基本情報 –
基本情報は以下を確認するとよいかと思います。
Azure の仮想マシンにおける SQL Server
Azure の仮想マシンにおける SQL Server の概要
仮想マシンで SQL Server を動作させる場合の基本的な情報については、ここから確認することができます。
– パフォーマンス –
パフォーマンスの考慮については、以下の情報が基本になります。
Azure Virtual Machines における SQL Server のパフォーマンスに関するベスト プラクティス
Azure 仮想マシンにおける SQL Server のパフォーマンス ガイダンス
仮想マシンで SQL Server を実行した際に考慮すべき設定やディスクの考慮の基本的な情報については、これらの情報から確認することができます。
– ディスクのパフォーマンス –
データベースはディスク I/O の考慮が重要となってきます。
ディスクについての情報を知りたい場合には、以下の情報を確認することをお勧めします。
Azure ストレージのスケーラビリティおよびパフォーマンスのターゲット
Premium ストレージ:Azure 仮想マシン ワークロード向けの高パフォーマンス ストレージ
Scaling-out SQL Server disks and data files on Windows Azure Virtual Machines…a real-world example
仮想マシンのディスクは Azure ストレージ上に VHD として配置されますので、基本的な性能上限については BLOB ストレージの制限に依存する形になります。
そのため、Azure ストレージの性能特性を理解しておくのが重要なポイントとなります。
通常のデータディスクは、1 本のディスクで、500IOPS / 60MB/sec が性能の上限となっています。
これ以上の性能を出したい場合には、複数のデータディスクを記憶域スペースを使用して束ねることが推奨されています。
何本のディスクを束ねるとどれくらいの効果があるのかは SQLCAT の Caling-out~ で公開されています。
– D シリーズの利用 –
D シリーズの仮想マシンでは、揮発性の高速の SSD が搭載されており、SQL Server で使用するための例として、以下の情報が公開されています。
Using SSDs in Azure VMs to store SQL Server TempDB and Buffer Pool Extensions
Mission Critical Performance with SQL Server 2014: (07) Buffer Pool Extension and Resource Governor for IO
Slow performance due to SQL Server 2014 Buffer Pool Extension (BPE) and serial queries (MAXDOP 1)
D シリーズの SSD の有効的な利用方法として、tempdb とバッファプール拡張 (Buffer Pool Extension : BPE) での利用が公開されています。
設定の方法については上記の情報を確認するとよいかと。
– 最新のベストプラクティス –
資料が公開されればですが、Deploying SQL Server with Microsoft Azure Virtual Machine のセッション資料が公開されれば、この情報が最新の情報になるかと思います。
以下は 2014 年の 11 月に Las Vegas で実施された上記のセッションの内容を公開してくださっているものになります。
SQLintersection session – Deploying SQL Server with Microsoft Azure Virtual Machine
抑えるべきポイントがまとめられており、とても参考になります。
本文内で触れられている tempdb の Fix は FIX: Poor performance on I/O when you execute select into temporary table operation in SQL Server 2012 ではないかと思うのですが、こちらについては資料が見れるようになったら (公開されるといいな…) 確認することをお勧めいたします。
また、情報の中でいくつかのトレースフラグが紹介されていますが、こちらについては Recommended updates and configuration options for SQL Server 2012 and SQL Server 2014 with high-performance workloads を参照されるとよいかと。
■本投稿で使用している環境
本投稿で使用している環境は、「米国東部2」上にデプロイした、「DS13」を使用しています。
DS シリーズでは永続化された高速な SSD ストレージであるプレミアムストレージを使用することができますので、このディスクについても本投稿で性能を確認してみたいと考えています。
また、DS シリーズには通常のストレージを接続することが可能ですので、通常のストレージに配置されたディクスについての検証を行うことも可能です。
本環境では、OS のディスクならびにシステムデータベースについては通常のストレージに配置されたデータディスクを使用しています。
# tempdb については検証の内容に応じて適宜場所を移動します。
■データディスクの I/O 特性を理解する (SQLIO を使用したディスク性能の傾向把握)
– テスト用のディスクの作成 –
まず最初に仮想マシンに接続しているデータディスクの I/O 特性を確認したいと思います。
データディスクの I/O 特性の把握には SQLIO を使用しています。
これで、データファイル / ログファイルの I/O 特性のベースラインを確認してみたいと思います。
本検証では 5 本の通常のストレージに接続されたデータディスクを以下のように記憶域スペースから仮想ディスクを作成しています。
記憶域スペース名 | ディスク本数 | 列数 | ストライプサイズ | アロケーションサイズ |
1DiskPool | 1 | 1 | 64KB | 64KB |
4DiskPool | 1 | 1 | 64KB | 64KB |
New-StoragePool -FriendlyName "1DiskPool" -StorageSubsystemFriendlyName "Storage Spaces*" -PhysicalDisks (Get-PhysicalDisk | ? {($_.Friendlyname -eq "PhysicalDisk2") -and ($_.CanPool -eq $true)}) New-StoragePool -FriendlyName "4DiskPool" -StorageSubsystemFriendlyName "Storage Spaces*" -PhysicalDisks (Get-PhysicalDisk | ? {($_.CanPool -eq $true)}) New-VirtualDisk -FriendlyName "1Disk" -UseMaximumSize -StoragePoolFriendlyName "1DiskPool" -ResiliencySettingName simple -NumberOfColumns 1 -Interleave 64KB New-VirtualDisk -FriendlyName "4Disk" -UseMaximumSize -StoragePoolFriendlyName "4DiskPool" -ResiliencySettingName simple -NumberOfColumns 4 -Interleave 64KB $disk = Get-Disk | Where PartitionStyle -eq "RAW" $disk | Initialize-Disk $part = $disk | New-Partition -UseMaximumSize Start-Sleep 5 $part | Format-Volume -FileSystem NTFS -Confirm:$false -AllocationUnitSize 64KB
ストライプサイズ / アロケーションサイズは一般的な OLTP でしい用される 64KB に設定しています。
ストライプサイズは、記憶域スペースの仮想ディスクの分散単位になりますので 64KB 単位で各ディスクにデータが分散されることになります。
それでは SQLIO で負荷をかけてみたいと思います。
SQL Server の標準な I/O は以下のようになると思います
操作 | 操作単位 |
インデックスシーク | 8KB |
先行読み取り | 8KB ~ 512KB |
ログ書き込み | 512B~60KB |
それでは、それぞれの操作単位で性能を比較してみたいと思います。
– 1 スレッドでの 8KB I/O –
8KB 単位の 1 スレッド I/O でディスクを変更しながら計測した結果が以下になります。
# SQLIO で操作するファイルは特筆していない場合 1 GB の 1 ファイルとしています。
スレッド数 | ブロックサイズ |
ディスク
|
操作 | IOPS | MB/sec |
1 | 8K | 記憶域 : 1 | Seq : Read | 120.90 | 0.94 |
Seq : Write | 119.16 | 0.93 | |||
Rand Read | 47.15 | 0.36 | |||
Rand : Write | 114.56 | 0.89 | |||
記憶域 : 4 | Seq : Read | 103.61 | 0.80 | ||
Seq : Write | 107.47 | 0.83 | |||
Rand Read | 51.44 | 0.40 | |||
Rand : Write | 96.71 | 0.75 | |||
D ドライブ (SSD) | Seq : Read | 499.86 | 3.90 | ||
Seq : Write | 500.03 | 3.90 | |||
Rand Read | 499.94 | 3.90 | |||
Rand : Write | 500.02 | 3.90 | |||
P10 (1 ディスク) | Seq : Read | 412.55 | 3.22 | ||
Seq : Write | 338.78 | 2.64 | |||
Rand Read | 308.93 | 2.41 | |||
Rand : Write | 343.84 | 2.68 | |||
P20 (1 ディスク) | Seq : Read | 436.00 | 3.40 | ||
Seq : Write | 358.41 | 2.80 | |||
Rand Read | 329.45 | 2.57 | |||
Rand : Write | 362.28 | 2.83 |
8KB I/O を発生させた場合の結果として、いくつかのことが見えてきました。
- 1 スレッドで I/O を発生させた場合、記憶域スペースのディスクの本数を増やしてもパフォーマンスは変わっていない
- D ドライブではシングルスレッドで 500IOPS を発生させることができている
- P10 / P20 で 1 スレッドで I/O を発生させた場合、パフォーマンスは変わっていない
- 全体的な傾向としてランダム読み込みは低い値を示している
記憶域スペースは特定のサイズ (今回は 64KB) でストライプしてデータを書き込むものになります。
そのため、1 スレッドで I/O を実行してもストライプサイズ単位で I/O を発生させますので、各ディスクに対して直列の I/O となっているのかと思います。そのため、1 スレッドの I/O では、パフォーマンスは変わっていません。
# この結果はあくまでも「8KB I/O」の場合ということは「必ず」意識しておく必要があります。
P10 / P20 については新たな発見だったのですが、1 スレッドで負荷を発生させた場合の I/O はあまり変わらないようですね。
D ドライブについては、1 スレッドで 500IOPS を発生させることができており、1 スレッドの検証の中では一番高速なディスクとなっていました。
以下は D13 の D ドライブに対して、同様のテストをした結果になります。
– D13 の D ドライブ –
スレッド数 | ブロックサイズ |
ディスク
|
操作 | IOPS | MB/sec |
1 | 8K | D ドライブ (SSD) | Seq : Read | 16,538.80 | 129.20 |
Seq : Write | 16,001.93 | 125.01 | |||
Rand Read | 15,322.68 | 119.70 | |||
Rand : Write | 15,810.10 | 123.51 |
現状の DS シリーズと D シリーズの D ドライブの性能は異なっているようですね。
DS シリーズは 500IOPS で上限となっていますがD シリーズでは 500IOPS 以上のスループットを得ることができています。
– 4 / 8 スレッドでの 8KB I/O –
それでは次に 8KB I/O をスレッド数を変えて実行してみたいと思います。
今回は 4 / 8 スレッドで実行しています。
– 4 スレッドでの実行結果 –
スレッド数 | ブロックサイズ |
ディスク
|
操作 | IOPS | MB/sec |
4 | 8K | 記憶域 : 1 | Seq : Read | 443.76 | 3.46 |
Seq : Write | 433.73 | 3.38 | |||
Rand Read | 209.36 | 1.63 | |||
Rand : Write | 437.71 | 3.41 | |||
記憶域 : 4 | Seq : Read | 366.33 | 2.86 | ||
Seq : Write | 415.62 | 3.24 | |||
Rand Read | 240.21 | 1.87 | |||
Rand : Write | 422.83 | 3.30 | |||
D ドライブ (SSD) | Seq : Read | 500.22 | 3.90 | ||
Seq : Write | 500.14 | 3.90 | |||
Rand Read | 499.90 | 3.90 | |||
Rand : Write | 500.15 | 3.90 | |||
P10 (1 ディスク) | Seq : Read | 510.00 | 3.98 | ||
Seq : Write | 510.16 | 3.98 | |||
Rand Read | 510.00 | 3.98 | |||
Rand : Write | 510.17 | 3.98 | |||
P20 (1 ディスク) | Seq : Read | 1532.70 | 11.97 | ||
Seq : Write | 1481.06 | 11.64 | |||
Rand Read | 1463.91 | 11.43 | |||
Rand : Write | 1451.03 | 11.33 |
– 8 スレッドでの実行結果 –
スレッド数 | ブロックサイズ |
ディスク
|
操作 | IOPS | MB/sec |
8 | 8K | 記憶域 : 1 | Seq : Read | 497.96 | 3.89 |
Seq : Write | 498.96 | 3.89 | |||
Rand Read | 390.24 | 3.04 | |||
Rand : Write | 496.22 | 3.87 | |||
記憶域 : 4 | Seq : Read | 638.66 | 4.98 | ||
Seq : Write | 784.45 | 6.12 | |||
Rand Read | 445.37 | 3.47 | |||
Rand : Write | 861.78 | 6.73 | |||
D ドライブ (SSD) | Seq : Read | 500.15 | 3.90 | ||
Seq : Write | 500.15 | 3.90 | |||
Rand Read | 500.06 | 3.90 | |||
Rand : Write | 500.14 | 3.90 | |||
P10 (1 ディスク) | Seq : Read | 510.43 | 3.98 | ||
Seq : Write | 510.26 | 3.98 | |||
Rand Read | 510.22 | 3.98 | |||
Rand : Write | 510.28 | 3.98 | |||
P20 (1 ディスク) | Seq : Read | 2345.33 | 18.32 | ||
Seq : Write | 2345.45 | 18.32 | |||
Rand Read | 2345.71 | 18.32 | |||
Rand : Write | 2346.44 | 18.33 |
スレッド数を上昇させることで、I/O 数が上昇していることが確認できますが、ある程度のスレッド数になると、ディスクI/Oが性能の上限に達して I/O が上昇しなくなっています。
このような傾向になった場合は、記憶域スペースのストライプのディスク数を変更することで、I/O を上昇できる可能性があります。
ただし、ストライプ数については、仮想ディスクの作成時にしか設定することができないため、あとから変更するためには、ディスクの内容を移行する必要がありますので、事前に複数のストライプで仮想ディスクを作成しておく必要があります。
1 ディスクと 4 ディスク、P10 と P20 では 1 スレッドの 8KB I/O では差がありませんでしたが、スレッド数が上昇すると、性能に差が出ているのが確認できます。
それでは、次にブロックサイズを変更して I/O を取得した結果を載せてみたいと思います。
– 64KB I/O での実行結果 –
スレッド数 | ブロックサイズ | ディスク | 操作 | IOPS | MB/sec |
1 | 64K | 記憶域 : 1 | Seq : Read | 39.08 | 2.44 |
Seq : Write | 61.03 | 1.91 | |||
Rand Read | 30.58 | 1.91 | |||
Rand : Write | 60.48 | 3.78 | |||
記憶域 : 4 | Seq : Read | 28.73 | 1.79 | ||
Seq : Write | 72.26 | 4.51 | |||
Rand Read | 29.44 | 1.84 | |||
Rand : Write | 79.56 | 4.97 | |||
D ドライブ (SSD) | Seq : Read | 62.54 | 3.90 | ||
Seq : Write | 62.51 | 3.90 | |||
Rand Read | 62.50 | 3.90 | |||
Rand : Write | 62.51 | 3.90 | |||
P10 (1 ディスク) | Seq : Read | 241.02 | 15.60 | ||
Seq : Write | 254.16 | 15.88 | |||
Rand Read | 259.14 | 16.90 | |||
Rand : Write | 256.30 | 16.01 | |||
P20 (1 ディスク) | Seq : Read | 240.81 | 15.05 | ||
Seq : Write | 251.84 | 15.74 | |||
Rand Read | 267.93 | 16.74 | |||
Rand : Write | 259.28 | 16.20 |
スレッド数 | ブロックサイズ | ディスク | 操作 | IOPS | MB/sec |
4 | 64K | 記憶域 : 1 | Seq : Read | 62.59 | 3.91 |
Seq : Write | 62.47 | 3.90 | |||
Rand Read | 62.49 | 3.90 | |||
Rand : Write | 62.41 | 3.90 | |||
記憶域 : 4 | Seq : Read | 156.60 | 9.78 | ||
Seq : Write | 237.53 | 15.47 | |||
Rand Read | 201.07 | 12.56 | |||
Rand : Write | 197.09 | 12.31 | |||
D ドライブ (SSD) | Seq : Read | 62.57 | 3.91 | ||
Seq : Write | 62.55 | 3.90 | |||
Rand Read | 62.55 | 3.90 | |||
Rand : Write | 62.50 | 3.90 | |||
P10 (1 ディスク) | Seq : Read | 510.33 | 31.89 | ||
Seq : Write | 510.03 | 31.87 | |||
Rand Read | 510.06 | 31.87 | |||
Rand : Write | 510.15 | 31.88 | |||
P20 (1 ディスク) | Seq : Read | 1139.31 | 71.20 | ||
Seq : Write | 1049.13 | 65.57 | |||
Rand Read | 1058.61 | 66.16 | |||
Rand : Write | 1043.46 | 65.21 |
スレッド数 | ブロックサイズ | ディスク | 操作 | IOPS | MB/sec |
8 | 64K | 記憶域 : 1 | Seq : Read | 62.61 | 3.91 |
Seq : Write | 62.57 | 3.91 | |||
Rand Read | 62.52 | 3.90 | |||
Rand : Write | 62.42 | 3.90 | |||
記憶域 : 4 | Seq : Read | 250.08 | 15.63 | ||
Seq : Write | 349.05 | 15.56 | |||
Rand Read | 221.34 | 13.83 | |||
Rand : Write | 217.00 | 13.56 | |||
D ドライブ (SSD) | Seq : Read | 62.62 | 3.91 | ||
Seq : Write | 62.56 | 3.91 | |||
Rand Read | 62.57 | 3.91 | |||
Rand : Write | 62.55 | 3.90 | |||
P10 (1 ディスク) | Seq : Read | 510.25 | 31.89 | ||
Seq : Write | 510.15 | 31.88 | |||
Rand Read | 510.16 | 31.88 | |||
Rand : Write | 510.16 | 31.88 | |||
P20 (1 ディスク) | Seq : Read | 2209.05 | 138.06 | ||
Seq : Write | 2134.85 | 133.42 | |||
Rand Read | 2218.12 | 138.63 | |||
Rand : Write | 2142.81 | 133.92 |
– 512KB I/O での実行結果 –
スレッド数 | ブロックサイズ |
ディスク
|
操作 | IOPS | MB/sec |
1 | 512K | 記憶域 : 1 | Seq : Read | 7.80 | 3.90 |
Seq : Write | 7.63 | 3.81 | |||
Rand Read | 7.76 | 3.88 | |||
Rand : Write | 7.82 | 3.91 | |||
記憶域 : 4 | Seq : Read | 25.96 | 12.98 | ||
Seq : Write | 25.62 | 12.81 | |||
Rand Read | 25.46 | 12.73 | |||
Rand : Write | 26.56 | 13.28 | |||
D ドライブ (SSD) | Seq : Read | 7.82 | 3.91 | ||
Seq : Write | 7.81 | 3.90 | |||
Rand Read | 7.81 | 3.90 | |||
Rand : Write | 7.81 | 3.90 | |||
P10 (1 ディスク) | Seq : Read | 94.60 | 47.30 | ||
Seq : Write | 81.79 | 40.89 | |||
Rand Read | 83.38 | 41.69 | |||
Rand : Write | 80.53 | 40.26 | |||
P20 (1 ディスク) | Seq : Read | 92.07 | 46.03 | ||
Seq : Write | 75.18 | 37.59 | |||
Rand Read | 83.01 | 41.50 | |||
Rand : Write | 76.84 | 38.42 |
スレッド数 | ブロックサイズ |
ディスク
|
操作 | IOPS | MB/sec |
4 | 512K | 記憶域 : 1 | Seq : Read | 7.85 | 3.92 |
Seq : Write | 7.84 | 3.92 | |||
Rand Read | 7.84 | 3.92 | |||
Rand : Write | 7.85 | 3.92 | |||
記憶域 : 4 | Seq : Read | 31.29 | 15.64 | ||
Seq : Write | 31.08 | 15.54 | |||
Rand Read | 31.27 | 15.63 | |||
Rand : Write | 31.13 | 15.56 | |||
D ドライブ (SSD) | Seq : Read | 7.84 | 3.92 | ||
Seq : Write | 7.83 | 3.91 | |||
Rand Read | 7.84 | 3.92 | |||
Rand : Write | 7.83 | 3.91 | |||
P10 (1 ディスク) | Seq : Read | 194.53 | 97.26 | ||
Seq : Write | 193.94 | 96.97 | |||
Rand Read | 194.65 | 97.32 | |||
Rand : Write | 193.99 | 96.99 | |||
P20 (1 ディスク) | Seq : Read | 291.39 | 145.36 | ||
Seq : Write | 288.77 | 144.38 | |||
Rand Read | 291.73 | 145.86 | |||
Rand : Write | 289.41 | 144.70 |
スレッド数 | ブロックサイズ |
ディスク
|
操作 | IOPS | MB/sec |
8 | 512K | 記憶域 : 1 | Seq : Read | 7.88 | 3.94 |
Seq : Write | 7.88 | 3.94 | |||
Rand Read | 7.88 | 3.94 | |||
Rand : Write | 7.88 | 3.94 | |||
記憶域 : 4 | Seq : Read | 31.31 | 15.65 | ||
Seq : Write | 31.31 | 15.65 | |||
Rand Read | 31.31 | 15.65 | |||
Rand : Write | 30.57 | 15.28 | |||
D ドライブ (SSD) | Seq : Read | 7.88 | 3.94 | ||
Seq : Write | 7.87 | 3.93 | |||
Rand Read | 7.87 | 3.93 | |||
Rand : Write | 7.87 | 3.93 | |||
P10 (1 ディスク) | Seq : Read | 194.69 | 97.34 | ||
Seq : Write | 194.29 | 97.14 | |||
Rand Read | 194.67 | 97.33 | |||
Rand : Write | 194.21 | 97.10 | |||
P20 (1 ディスク) | Seq : Read | 291.94 | 145.97 | ||
Seq : Write | 290.78 | 145.39 | |||
Rand Read | 291.98 | 145.99 | |||
Rand : Write | 290.00 | 145.30 |
8KB I/O では、D ドライブ / P10 ともに顕著な差はありませんでしたが、ブロックサイズが高い I/O では P10 のほうが性能が出ていることが確認できます。
このことから、ブロックサイズが高い I/O が発生した場合、プレミアムストレージを使用したほうがローカルディスクより性能が出ることが考えられます。
また、64KB I/O の場合は 1 ディスク /4 ディスクの 1 スレッドの性能に差はありませんでしたが。512KB の場合には、1 スレッドでも明確な性能差が出てきていました。
512KB I/O の場合以外は、1 ディスク と 4 ディスク、P10 と P20 では 1 スレッドの I/O に大きな差は出ていないかと思います。
このことから、
- 1 スレッドでかけられる I/O を意識する
- 複数のスレッドで I/O をかけていない場合、ディスクを束ねた効果が得られないことがある
- 同期 I/O ではなく、非同期 I/O を用いて、複数のスレッドで効果的にアクセスを行う
というようなことがポイントになってくるのかと思います。
今回は SQLIO を使用しましたが、次の投稿では SQL Server を使用して、I/O 特性を確認してみたいと思います。