皆さん、こんにちは。 SQL Server/Microsoft Azure SQL Database サポートチーム です。
今回は、Microsoft Azure SQL Database (以下 MASD) を使用したシステムを構築するうえで、推奨されるアプリケーションの実装について紹介します。
MASD は、クラウド上に配置されたデータベースをサービス (Software as a Service : SaaS) として提供しており、高可用性を実現するため、複数レプリカによる冗長性を備えています。また、高可用性を維持していくために、Reconfiguration (リコンフィグレーション) が内部的に行われています。
※ Reconfiguration (リコンフィグレーション) の詳細については、以下の ブログを参照ください。
[SQL Database] Reconfiguration (リコンフィグレーション) は悪ではない。
http://blogs.msdn.com/b/jpsql/archive/2014/10/22/sql-database-reconfiguration.aspx
そのため、MASD を使用したシステムを構築する場合は、アプリケーション側でも、 アプリケーションからデータベースまでの経路間におけるネットワーク遅延、及び、Reconfiguration (リコンフィグレーション) の発生に伴う、既存セッションの切断、ロールの変更 (セカンダリからプライマリへの昇格など) が完了するまでの期間 (数秒から数十秒程度) における、新規接続の一時的な遅延を考慮した実装を検討する必要があります。
上記の事項を考慮した実装として、アプリケーション側で以下を実装することを推奨しています。
推奨実装 (アプリケーション側)
1) リトライ ロジックを実装し、接続切断や接続タイムアウトなどを検知時にリトライ処理を実施する
2) 接続タイムアウト値 (既定 15秒) を 30秒に以上に設定する
3) リトライ処理の間隔は、10秒以上 (最低 5 秒以上) に設定する
推奨実装に関する補足事項を以下に記載します。
1) リトライ ロジックについて
接続タイムアウトが発生した場合、リトライ処理の中で接続オブジェクトを再利用せず、オブジェクトの作成から処理を再実行します。
※ リトライ ロジック の実装例として、以下のサンプル ソースを参考ください。
SQL Azure Retry Logic
https://code.msdn.microsoft.com/windowsazure/SQL-Azure-Retry-Logic-2d0a8401
2) 接続タイムアウト値について
接続タイムアウト値は、アプリケーションからデータベースに対する接続処理において、アプリケーション側が接続処理が完了するまでに待機できる最大時間を設定するものになります。
そのため、接続タイムアウト値を延ばしたとしても、アプリケーションからデータベースに対する接続処理が、接続タイムアウト値に指定した時間まで必ず待機状態になるわけではなく、通常時の即座にアプリケーションからデータベースに接続ができる状況時において、即座に接続が可能となりますので、ご安心ください。
[参考URL]
SqlConnection.ConnectionTimeout プロパティ (ADO.Net)
http://msdn.microsoft.com/ja-jp/library/system.data.sqlclient.sqlconnection.connectiontimeout(v=vs.110).aspx
private static void OpenSqlConnection() static private string GetConnectionString() |
接続文字列 (Entity Framework)
http://msdn.microsoft.com/ja-jp/library/cc716756.aspx
<connectionStrings> <add name="AdventureWorksEntities" connectionString="metadata=.\AdventureWorks.csdl|.\AdventureWorks.ssdl|.\AdventureWorks.msl; provider=System.Data.SqlClient;provider connection string='Data Source=localhost; Initial Catalog=AdventureWorks;Integrated Security=True;Connection Timeout=60; multipleactiveresultsets=true'" providerName="System.Data.EntityClient" /> < /connectionStrings> |
3) リトライ 間隔について
短期間の間に接続が失敗し続ける現象が大量に発生した場合、SQL Database 側では、攻撃を受けていると検知し、一定期間、アプリケーションからのすべての接続を拒否するという現象(DoS Guard) が発生する可能性があります。
そのため、リトライ処理を実施する際には、リトライ間隔を十分に取ることを推奨しています。
※ 本Blogの内容は、2014年10月 現在の内容となっております