こんにちは、開発部の鶴見です。
ZOZOTOWNのリプレースを担当しています。
ZOZOTOWNリプレースですが、オンプレからクラウドに単純に置き換えるのでなく「運用が楽になる」などメリットを考えながら作り替えています。
主にデータベースは、AzureのRDBであるSQL Databaseを利用しています。
先日までSQL Databaseのパフォーマンスとコストがネックになっていました。そこでAzure Automationを利用しSQL Databaseを定期的にスケールアップ/ダウンさせリソース、コストの最適化をしました。
その方法をご紹介します。
- はじめに
- スケールアップ/ダウンについて
- 多数のモデルが存在するSQL Database
- オートスケールを考える
- 参考情報(スケールアウト)
- スケール変更注意点
- Azure AutomationでSQL Databaseをスケールアップ/ダウン
- まとめ
はじめに
パブリッククラウドで利用できるサービスのほとんどが従量課金であり、SQL Databaseも時間単位で課金されています。
コスト、リソースが最適となるようSQL Databaseに対して定期的なスケールアップ/ダウンを行いました。改善にあたり達成目標は次の通りです。
- スケールアップ/ダウンの自動化
- 適切なリソースの確保
- 適切なコスト
- ダウンタイム最小化
対応内容は次の2つです。
環境 | 対応内容 |
---|---|
本番環境 | 時間帯や負荷に合わせて自動でスケールアップ/ダウンする対応。 |
開発環境 | 業務時間外に自動でスケールダウンし、業務時間内にスケールアップする対応。 |
上記の内容に加え「SQL Databaseは、どのようにスケールアップ/ダウンしているのか」「SQL Databaseのモデル選び」もご紹介します。 AWSやGCPでも同じような考えでRDBをスケールアップ/ダウンできると思います。
リプレースにあたりインフラ全体で「システムが安全、構成がシンプル、スケール可能、そしてコストが安い」状態を目指しています。
スケールアップ/ダウンについて
SQL DatabaseをCPU4コアから8コアにスケールアップした場合、下図のような仕組みでSQL Databaseのコア数が変わります(スケールダウンの場合も同様)。
- スケールアップ実行
- 新インスタンス起動、旧インスタンスから新インスタンスにデータコピー
- 新インスタンス準備完了、エンドポイント切替え
多数のモデルが存在するSQL Database
SQL Databaseは、様々なモデルがあります。
チーム内でもモデル選びに迷いましたので、一覧にします。
どれもがSQL Serverと互換性のあるPaaSです。
種類 | 特徴 | 備考 |
---|---|---|
DTUモデル | CPU、メモリ、ディスクI/OなどをまとめてDTUという単位で表現されます。DTUとは、Database Throughput Unitの略です。リソースはDTUで管理されます。 | 簡単にDatabaseを扱いたい方にはオススメですが、CPUコア数やメモリ数の指定はできないため、細かく管理したい場合は不向きです。 |
vCOREモデル | CPUコア数を指定できます。メモリ数は指定できませんが、CPUコア数と比例して増えます。 | CPUコア数にてDatabaseを管理したい場合に向いています。 |
ハイパースケール | ストレージが自動で拡張され、読み取り専用(セカンダリ)のスケールアウトは4台まで可能です。CPUコア数も指定できます。 | Amazon Auroraに近いアーキテクチャーです。柔軟にスケールアウト/インできます。 |
Managed Instance | SQL Serverとほぼ100%の互換性があります。CPUコア数も指定できます。 | 他のモデルではジョブが作成できない。などの制限があります。SQL Serverのフル機能が必要な場合、Managed Instanceを利用します。 |
サーバレス | CPUコア数の最大と最小を指定することでスケールアップ/ダウンできます(2019年5月に発表されプレビューです)。 | プレビューのためスケールアップは最大CPU4コアの制限があります。今後に期待します。 |
モデル選定
DTUモデルはCPU、メモリが管理できないことから採用しませんでした。
正確にはリプレース当初(2017年後半)はDTUモデルしかありませんでした。そのためリプレース当初はDTUモデルを利用していましたが、DTUに馴染めず、その後発表されたCPUコア数を管理できるモデルに乗り換えました。
ハイパースケールについては2018年12月にプレビューを検証した結果、当時はまだ性能面で不安があったので利用を見送りました。最近GAとなったため、また時期を見て再検証してみます。
サーバレスについては、求めていた自動のスケールアップ/ダウンを実現してくれるモデルですが、まだ発表されたばかりで最大CPU4コアの制限もあるため、採用を見送ります。
Managed Instanceは、SQL Serverのほぼ全ての機能を使えるのが売りですが、リプレースに於いて使いたい機能が特にありませんでした。性能に関してはvCOREモデルと同程度でした。
DTUモデル、vCOREモデルはGAから時間が経っていることありプロダクトとして安定しています。
上記のことからZOZOTOWNでは安定していて、CPUコア数も指定できるvCOREモデルを採用しています。
オートスケールを考える
vCOREモデルを利用していますが、その他モデルも含めてスケールアップ/ダウンを考えます。
種類 | 方法 |
---|---|
DTUモデル | DTUを変更することでスケールできます。※DTUを変えたことでCPU、メモリがどの程度増えるのか分からないため、どのくらいDTUを上げればシステムとして足りていると判断するのか難しいです。 |
vCOREモデル | CPUコア数を変更することでスケールできます。 |
Managed Instance | CPUコア数を変更することでスケールできます。 |
ハイパースケール | CPUコア数の変更に加えて、読み込み専用レプリカ追加(0~4台まで)によるスケールイン/アウトもできます。 |
サーバレス | CPUコア数の最小と最大を設定することで自動的に変更してくれます。 |
上記のように、どのモデルを利用したとしても動的にスケールアップ/ダウンできそうです。
実装はAzure AutomationでサポートされているPowerShellを利用しました。PowerShellにてAzureを操作(リソースの削除、追加、変更)できます。
下記、vCOREモデルでスケールアップ/ダウンを考えた場合のサンプルです。
サンプル(CPUコア数変更)
$resourceGroup = "XXXXXXXX" $databaseName = "XXXXXXXX" $serverName = "XXXXXXXX" $serverEdition = "XXXXXXXX" $computeGeneration = "XXXXXXXX" $vCore = "XXXXXXXX" $environmentName = "XXXXXXXX" $connectionName = "XXXXXXXX" $servicePrincipalConnection = Get-AutomationConnection -Name $connectionName $environment = Get-AzEnvironment -Name $environmentName Add-AzAccount ` -Environment $environment ` -ServicePrincipal ` -TenantId $servicePrincipalConnection.TenantId ` -ApplicationId $servicePrincipalConnection.ApplicationId ` -CertificateThumbprint $servicePrincipalConnection.CertificateThumbprint Set-AzSqlDatabase -ResourceGroupName $resourceGroup ` -DatabaseName $databaseName ` -ServerName $serverName ` -Edition $serverEdition ` -ComputeGeneration $computeGeneration ` -VCore $vCore
上記、PowerShellコードは簡易版のためエラーハンドリングは含まれていません。
他にも「CPU、メモリを動的管理ビューで確認し閾値を超えたらスケールアップ」や「時間帯で読み取り専用(セカンダリ)追加によるスケールアウト」なども行うことが可能です。
サンプル(クエリ発行)
$query = " SELECT * FROM XXXX " Invoke-Sqlcmd -ServerInstance $serverInstance –Username $userName –Password $password -Database $database -Query $query -ErrorAction Stop -QueryTimeout $queryTimeout
PowerShellからSQL Databaseに接続しクエリを実行できます。 CPU、メモリの値を動的管理ビューから取得することも可能です。
参考情報(スケールアウト)
ハイパースケール以外でもGeoレプリケーションを利用したスケールアウトができます。 Geoレプリケーションはディザスターリカバリの目的で違う地域にデータを保持できるのですが、読み取り専用(セカンダリ)としても利用できます。
サンプル(Geoレプリケーション設定)
$database = Get-AzSqlDatabase -ResourceGroupName $resourceGroupName -ServerName $serverName -DatabaseName $databaseName New-AzSqlServer -ResourceGroupName $resourceGroupName ` -Location $database.Location ` -ServerName $serverName ` -SqlAdministratorCredentials $(New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $user, $(ConvertTo-SecureString -String $pass -AsPlainText -Force)) $database | New-AzSqlDatabaseSecondary ` -PartnerResourceGroupName $resourceGroupName ` -PartnerServerName $serverName ` -AllowConnections $allowConnections ` -SecondaryVCore $vCore ` -SecondaryComputeGeneration $computeGeneration
Geoレプリケーションを利用して読み取り専用(セカンダリ)を追加する場合は、ファイヤフォールと仮想ネットワークの設定・脅威の検出・監査設定なども必要に応じて設定します。
サンプル(ファイヤフォール設定)
New-AzSqlServerFirewallRule -ResourceGroupName $resourceGroupName ` -ServerName $serverName ` -FirewallRuleName $firewallRuleName ` -StartIpAddress "XXX.XXX.XXX.XXX" ` -EndIpAddress "XXX.XXX.XXX.XXX"
サンプル(脅威の検出・監査設定)
Set-AzSqlServerThreatDetectionPolicy -ResourceGroupName $resourceGroupName ` -ServerName $serverName ` -NotificationRecipientsEmails "XXXX@XXXX" ` -EmailAdmins $False ` -ExcludedDetectionType "Sql_Injection_Vulnerability","SQL_Injection","Access_Anomaly" ` -StorageAccountName $storageAccountName Set-AzSqlServerAuditing -State Enabled ` -ResourceGroupName $resourceGroupName ` -ServerName $serverName ` -StorageAccountName $storageAccountName
スケール変更注意点
- サービスレベルやモデル、容量にもよりますが、スケールアップ/ダウンに数分~数時間掛かります(図②)。どの程度時間が掛かるか検証してから利用してください。
- スケールアップ/ダウン切り替えのタイミングで数秒~数十秒の切断が発生します(図③)。リトライ処理などの考慮が必要です。
- スケールアップ/ダウン切り替え直後は、キャッシュクリアされているためパフォーマンスが一時的に劣化する可能性があります。
- 大幅にスケールダウンすると、主要データがメモリにのらずパフォーマンス劣化となる可能性があります。
その他、SQL Databaseでは定期的にreconfigurationがあり一時的に接続できなくなることがあります。この場合もリトライ処理など考慮が必要になります。
メリット・デメリットありますがZOZOTOWNでは開発環境・本番環境にスケールアップ/ダウン(定期的なCPUコア数変更)を入れており、問題なく動作しています。
参考までにGeoレプリケーションを利用したスケールアウトを記載していますが自動化はしておらず、必要に応じて手動設定しています。
Azure AutomationでSQL Databaseをスケールアップ/ダウン
次にAzure Automationを利用して自動化します。
Azure Automationの実態は、PowerShellを定期的(または一時的)に動かすことが出来るジョブです。
SQL Databaseのスケールアップ/ダウンに限らず「Azure上の環境構築を自動化」「定期的なデータ作成」など様々な用途で利用できます。
最初にAzure Automation設定で躓いたところが2点あったのでお伝えます。
モジュールのインストール
Azure AutomationからPowerShellを実行したところ必要なモジュールが入っておらず実行できないことがありました。
各リソース毎にモジュールが用意されており、まず必要なモジュールをインストールする必要があります。「SQL Databaseを操作するモジュール」「Application Gatewayを操作するモジュール」と言った具合です。
初回実行でエラーとなった場合、モジュールがインストールされているかを疑います。
また、Azure操作はAzure Resource Manager(以下ARMと略します)というモジュールを使うことが多かったのですが、今後はAzモジュールに切り替わっていきます。
AzモジュールはARMモジュールの代わりになるものです。最新機能はAzモジュールに追加されていきます(AzモジュールがGAされたのは2018年9月頃です)。
世の中の記事を見るとARMモジュールで書かれれていることが多いので、Azコマンドに置き換えての実装することをオススメします。
ARMモジュールは2020年12月まではサポートされるようです。
Azモジュールについてはこちらを参照ください。
Azure Automationの実行アカウント
Azure Automationアカウントを作成すると自動で、Azure Active Directoryにアプリケーションが登録され、この権限に基づき実行されます。
また、デフォルトではアカウントの有効期限が作成から1年で設定されるため、気を付けないと1年後に実行できなくなります。
実際にあった話ですが、組織のチームメンバー変更により当初設定した人がチームを外れて数か月後、有効期限切れで動かなくなりました。
特に本番環境で定期的にAzure Automationで処理を実行している場合は、障害になりかねないので実行アカウントには注意が必要です。
上記のことに気を付けてPowerShellを用意し、Runbookに登録します。
次にスケジュールを決めて設定完了です。
スケジュールは曜日や時間などで設定できます。
試しにAzure Automationを実行してSQL DatabaseをCPU8コアに変更してみます。
正常終了を確認したので、SQL DatabaseでCPUコア数を確認します。
問題なくCPUコア数が変更されていることを確認できました。
このAzure Automationを定期的に動かすことでスケールアップ/ダウンさせています。
まとめ
今回はAzure Automationを利用してSQL Databaseをスケールアップ/ダウンさせた事例をご紹介しました。結果、開発環境・本番環境で問題なくスケールアップ/ダウンできておりコストを40%削減できました。
コストの詳細はSQL Database 節約術に記載しています。
ZOZOテクノロジーズでは、このような問題を1つずつ改善しています。
一緒に前向きなチーム作りを盛り上げてくれるエンジニアを大募集中です。
ご興味のある方は、こちらからぜひご応募ください。