CS課佐竹です。
はじめに
今回は「RDSを本番環境で停止運用しないほうが良いですよ」という理由について記載します。つまり、「EC2の様に夜間は停止して、朝に起動して使いたい」というような要件は、RDSでは積極的に推奨されないのが実情です。その3つの理由について、以下で具体的にご説明いたします。
何故、RDSを夜間に停止したいのか?
ズバリ、コスト削減のためです。RDSは停止している時間はRunning費用がかからなくなります。そのコストを削減するため、「業務時間外は停止としたい」ケースがあるでしょう。例としてですが、毎営業日において、8:00-17:59のみ利用するシステムであれば1日10時間だけの起動でよく、加えて土日は利用自体が不要となります。1ヶ月の営業日を22営業日と仮定しますと、実利用時間は月あたり220時間のみ。1ヶ月 = 31日 = 744 時間 で計算しますと、営業時間だけうまく稼働させることができれば約30%の利用料で済むので、70%の起動コストが削減できます。「おお、これはお得だ。さっそくCloud Autoamtorで夜間にRDSを停止しよう」そう考えるのも頷けます。しかし、本番環境でこれをやる前に、ちょっと立ち止まって一度以下の内容に目を通してみてください。
1. 停止機能は検証用の環境向けである
最初に共有しますのは以下の公式ドキュメントです。
Amazon RDS DB インスタンス » Amazon RDS DB インスタンスのライフサイクル » 一時的に Amazon RDS DB インスタンスを停止する
https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/USER_StopInstance.html
こちらの公式ドキュメントの最初に、以下に引用する文章が記載されています。
一時的なテストや毎日の開発作業のために、断続的に DB インスタンスを使用する場合、コスト削減のため、Amazon RDS DB インスタンスを一時的に停止できます。DB インスタンスが停止している間は、プロビジョニングされたストレージ (プロビジョニングされた IOPS を含む) とバックアップストレージ (指定された保存期間内の手動スナップショットと自動バックアップを含む) は請求されますが、DB インスタンス時間は課金されません
一時的なテストや毎日の開発作業のために とまずあります。この文章から見てもRDSの停止が開発環境や、ステージング環境など、「検証環境」の用途を目的として実装されたことが伺えます。最初に重要な点は「この機能は検証完了や開発環境などをターゲットとして提供しています」という点です。ここが「AWSが想定しているメッセージ」となりますため、これ以外の利用用途、つまり本番環境での利用においては「保証されない」ということが示唆されます。
2. 停止、開始に時間がかかる場合がある
先ほどと同じドキュメントに以下の記載もあります。
場合によっては、DB インスタンスを停止するのに長い時間がかかります。
これは読んで字のごとくですが、「停止処理を実行すると直ぐにRDSが停止されることも、いつも同じ処理時間で停止することも保証していない」ことになります。そもそもですが、データベース(DB)は停止に時間がかかります。トランザクション処理が終わってなくて、コミット待ちのデータがあるとか、メモリにある情報をディスクに降ろさないといけないとか、そういうのをしっかりクローズし、問題なく起動するために様々な終了処理が実行されます。つまり、停止にかかる時間は停止タイミングのDBの状況に依存します。それだけでなく、AWSはパブリッククラウドのサービスです。ハードウェアは共有資産のため、たまたま利用している内部のインフラストラクチャの状態が「混雑状態」になっていて、そのために停止に予想以上の時間がかかってしまうという事もあり得ます。この「DBとインフラストラクチャ状態によって停止時間が左右されてしまうために、長い時間がかかる場合がある」というのが、この注記に集約されています。
また、この注記では停止についてのみ記載されており、かつドキュメント「以前に停止した Amazon RDS DB インスタンスを開始する」には明示的に注記はないのですが、開始についても同じ事が言えます。開始にかかる時間も同様に、「停止時のDBの状態から復帰にかかるDBの内部処理の多さ」と「開始時のインフラストラクチャの混雑状況」によって左右されるのが実情です。よって、「EC2のように短時間で停止(Stop)して、短時間で開始(Start)してくれるだろう」という思いこみは危険です。
これらの状況を鑑みると停止も開始も、前後1時間から2時間は余裕をみて運用を行わないといけないでしょう。また、安定性を担保するには実際にそのようにせざるを得ません状況になります。つまり、10:00 AMから使いたいシステムであれば、8:00 AMくらいからはRDSを開始する必要が出ることになり、想定よりも3-4時間ほどコスト削減の効率が悪化するということになります。
これらのように、RDSは停止・開始にEC2よりも慎重になる必要があります。
3. キャパシティ不足時に対応する手段が限られている
これが、RDSを本番環境では停止・開始することが推奨できない最も厳しい理由となります。理由のご説明の前に、キャパシティ不足について記載します。
キャパシティ不足とは?
キャパシティ不足 (insufficient capacity) とは、利用したいRDSの DB インスタンス クラスに在庫がない場合に発生します。例えば、db.t2.smallの DB インスタンスを停止⇒開始したとします。この開始のタイミングで、利用しているAvailability Zoneにおいてdb.t2.smallの利用可能なキャパシティ(在庫)が存在しない場合、「db.t2.smallでは開始できない」という状況になります。これはEC2でも同様で、開始したいInstance Typeのキャパシティが利用したいAvailability Zoneで不足している場合は、そのInstance Typeでは開始が(もちろんLaunchもですが)できません。
EC2におけるキャパシティ不足対応
EC2におけるキャパシティ不足の対応には以下の対応が考えられます。
- 少しの時間待ってからStart(開始)のリトライを行うことを数度繰り返す
- キャパシティ不足でEC2が開始できない場合は自動的にStopされるため、Stopped状態のEC2 instanceのInstance Typeを別のTypeへ変更し、Start(開始)を試みる
- EC2のAMIを取得し、別のAvailability ZoneでLaunch(起動)を試みる
- 予め、Reserved InstanceをAvailability Zone指定で購入しておく(ゾーン リザーブドインスタンス)
- 予め、EC2 Capacity Reservation(オンデマンドキャパシティー予約)を利用する
SWXでは運用も行っておりますが、このような場合はまず[1]と[2]を実行しており、おおよその場合ではこの2つで解消します。しかし、どうしても回避できない場合は、[3]の手段を取ることもあります。[4]と[5]はどちらも予めキャパシティを予約しておく方法ですため「そもそもキャパシティ不足を発生させない」という対応策となります。さて、これと比較してRDSのキャパシティ不足を見てみましょう。
EC2と比較したRDSのキャパシティ不足対応
比較して記載します。
- ×。Start(開始)の後キャパシティ不足に陥った場合は、停止ステータスでも、起動ステータスでもない状態で固まり、復旧できないステータスで固まってしまう。この状態ではSnapshotも作成できないため、DB インスタンスを削除して既存のSnapshotから再構築を行う必要性に迫られる *1
- ×。キャパシティ不足のRDS DB インスタンスが停止中の状態では、Modifyコマンドによる DB インスタンスクラスの変更はできない。RDSは起動中のみ DB インスタンスクラスの変更が可能なModifyが実行可能なため、 DB インスタンスクラスの変更による対応は不可能である
- △。RDS DB インスタンスのSnapshotを取得することができないため、既存の最新のSnapshotを利用し、別のAvailability ZoneでCreate(作成)を試みる。なお同じdb instance identifier(DBインスタンス識別子)は利用できないため、RDSを削除するか変更を行う必要があるが、識別子の変更はModifyで実施するためこれも同様に停止中は利用ができない。そのため、この手順においては合わせて DB インスタンス削除の実施が必要となる
- ただし Aurora の場合は、クラスターに新規に Reader を追加することが可能であるため、他のサイズで新規に Reader を追加した後に、キャパシティ不足となっているDBインスタンスを削除した後、頃合いを見て元のサイズに戻す対応方法が可能
- ×。Reserved InstanceをAvailability Zone指定で購入するオプションが存在しないため、RDSではReserved Instanceを利用したキャパシティ予約が不可能である
- ×。EC2のCapacity Reservation(オンデマンドキャパシティー予約)のような機能はRDSでは提供されていない
上記の通り、EC2と比較して取れる手は限られています。それはSnapshotからの復旧です。またRDSはEC2と異なりRDSではdb instance identifier(DBインスタンス識別子)が一意になっている必要がある、という制約があるために既存の環境を削除しないといけないというのがEC2と異なる点になります。上記の通り、RDSでキャパシティ不足が発生した場合は、かなり対応が難しい状況になるとご理解頂けると思います。
まとめ
いかがでしたでしょうか。本記事では、「RDSを本番環境で停止運用しないほうが良いですよ」という理由について記載してきました。その理由は、以下の3点でした。
- 停止機能は検証用の環境向けである
- 停止、開始に時間がかかる場合がある
- キャパシティ不足時に対応する手段が限られている
特に厳しいとお伝えしましたのは「3. キャパシティ不足時に対応する手段が限られている」になります。そしてこれら3つの理由を鑑みました結果「RDSでは常時起動し続けるのが最も安定した運用になる」ということがご理解頂けるかと存じます。なお、常時起動時のコスト最適化におきましては、同時にReserved Instanceを購入されることも推奨させて頂きます。
それでも本番環境のRDSを停止したい方へ
上記3つの理由を踏まえてみても、「コストを優先されたい」場合に、やはり停止する運用を選択されるという方もいらっしゃるかと考えています。もちろん、そのような選択も可能です。ただし、夜間停止するRDSの保守運用担当が、上記の懸念点を認識されずに保守運用されている場合もあるかと存じますので、これらの懸念点はご理解頂いた上で、適切な選択を頂ければ嬉しく思います。
なお、RDSを停止する場合には「連続停止は7日間までで、7日間連続停止していると自動的に起動される」という仕様にはご留意ください。本番環境だと平日はほぼ起動しているためこの制限に抵触することは稀かと思いますが念のため記載します。
停止した DB インスタンスの自動再起動
連続 7 日後に DB インスタンスを手動で起動しなかった場合、RDS は DB インスタンスを自動的に起動します。
https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/USER_StopInstance.html
また、自動スナップショットは RDS が AVAILABLE
になっている場合にのみ取得可能ですため、夜間停止で運用する RDS においては「バックアップウィンドウは起動している時間帯に設定」して頂くようお願いします。
Modifyによる DB インスタンス クラスの変更について
停止運用に関連し、こちらも重要なため記載します。起動中のRDSでは、 DB インスタンス クラスの変更が可能です。その場合ですが、内部的には「停止⇒開始」を伴います。EC2で説明しますと「停止⇒Instance Type変更⇒開始」の流れと同じで、一度停止を経ることになります。そのため「常時起動」と言いましても「定期的にModifyによる DB インスタンス クラスの変更を行う」場合には注意が必要になります。つまり、Modifyを行う場合にも停止と同様の懸念が潜在しているということも合わせてご認識頂ければと存じます。
保留中のアクションが削除される
2020年6月18日に、本件追記します。これは弊社では2020年1月頃に発覚したのですが、現在もなお影響が大きいため記載することにしました。以下公式ドキュメントより引用してご紹介です。
DB インスタンスを停止すると、保留中のアクションが削除されます。ただし DB インスタンスのオプショングループまたは DB パラメータグループの保留中アクションは除きます。
https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/USER_StopInstance.html
この記載内容が何を指しているかということを補足します。
今年のはじめ、RDSのSSL/TLS(CA) 証明書(CACertificateIdentifier)を変更する必要があったことを皆様は覚えていらっしゃいますでしょうか?これを RDS Maintenance Window で実行するためには、マネジメントコンソールから「次回のメンテナンスウィンドウで実行する」を押下することでその設定が可能でした。以下がその例です。画像は別のメンテナンスのものとなっておりますがUIは同様となります。 このような設定を行った後、実際に Maintenance Window の時間が来る前に RDS DB インスタンスを停止すると「Maintenance Window で実行されるように待機している処理(保留中)のキューが消えてしまう」というのがこのドキュメントの記すところです。つまりキューが消失した結果、残念なことに次回のメンテナンスウィンドウにおいてメンテナンス処理自体が実行されません。これは DB インスタンスクラス の変更(Modify)なども同様に影響を受けてしまいます。
もう少し具体的な例を出しますと、RDS DB インスタンス において検証環境を毎日夜間停止しており、土曜日に Maintenance Window が設定されているとすると、金曜の日中に「次回のメンテナンスウィンドウで適用される設定」を行ったとしても、その金曜日の夜間停止時に消えてしまって土曜日に実行されないということが起きます。この仕様は、RDSの運用保守において十分な注意が必要です。
補足ですが、RDSの保留中のメンテナンスは「describe-db-instances」を実行することで確認が可能です。マネジメントコンソールからは確認ができません。 以上で終わりにしたいと思います。皆様もよきRDSライフを。
*1:2024年にAWSサポートに問い合わせを行った内容に修正しました
佐竹 陽一 (Yoichi Satake) エンジニアブログの記事一覧はコチラ
マネージドサービス部所属。AWS資格全冠。2010年1月からAWSを利用してきています。2021-2022 AWS Ambassadors/2023-2024 Japan AWS Top Engineers/2020-2024 All Certifications Engineers。AWSのコスト削減、最適化を得意としています。