[SQL Azure] 高可用性を保持するための仕組み

SQL Azure の高可用性の仕組み

マイクロソフトはService Level Agreement (SLA) にて SQL Azure の月間稼働時間のサービスレベルを99%(2011年3月時点)以上を保つことを定義しています。つまりダウンタイムは月間稼働時間の1%の範囲を超えないことを定義しています。

どうやってダウンタイムの縮小を図っているのでしょうか。様々な工夫がなされていますが、その工夫の一つにマルチテナントと呼ばれる仕組みがあります。SQL Azure では データベースはいくつかのパーティションに分けられ、いくつかの物理的なサーバーに分散して存在しています。またその3つのコピーデータベース(プライマリと2つのレプリカ)も同様にいくつかのパーティションに分けられ、いくつかの物理的なサーバーに分散して格納されます。このように物理的なリソースを複数利用することにより、ハードウェア故障の問題が発生してもデータの損失がないよう、またサービスを提供し続けることができるように設計されています。もちろん、ユーザーはデータがいくつかの物理リソースにまたがって存在することは意識することなく利用することができます。

それでは、1つの物理サーバーに注目するとどんなことが起こっているのでしょうか。1つの物理サーバーにはそれぞれ別々のユーザーのデータがパーティションとして同居していることになります。そのそれぞれのユーザーが、それぞれのデータに対して処理を行っていることになります。例えて言うと、いろんな人が同居するマンションのようなイメージです。そのような状況でサービスレベルをある一定の水準に保つにはいくつかのルールが必要になってきます。例えば、温水が限られているマンションで、ある特定の人がシャワーをとても長い時間利用することがあるとします。当然一人の人が使い続ければ、他の人が使えなくなることが予想できます。みんながある程度一緒に使えるようにするには、使用量の閾値を決める必要性がでてきます。

SQL Azureでも同じように、様々な閾値が設定され、セッションやトランザクションのライフサイクルの管理が行われています。接続先のサーバーのリソースに十分な余裕がある場合には、そのリソースをフルに活用することができますが、リソース不足が検知されると、閾値を越えてリソースを消費するセッションの見直しが図られ、すべてのユーザーが常に一定の水準でサービスを利用できるように設計されています。とくに、長い時間実行されているクエリや、CPUやメモリなどを長時間多く消費する処理などは、ある一定の閾値を超えるとサーバー側で接続を切断します。これをThrottlingといいます。次に具体的にどんな閾値があるのか見ていきましょう。

閾値例

  • ロック:
    セッションが1,000,000個を超えるロックを消費すると、そのセッションはサーバーにより切断されます。このとき、エラーコード 40550 が戻されます。ロックがどれくらい消費されているかをリアルタイムに確認するには、sys.dm_tran_locks ビューを確認します。
  • ログ領域:
    単一のトランザクションが1GBを超えてログ領域を消費するとそのトランザクションはサーバーにより終了させられます。このとき、エラーコード 40552 が戻されます。
  • 未コミットのトランザクション
    未コミットのトランザクションが消費するログ領域が、最初のLSNから最後尾のLSN(Current LSN)がログファイルの全サイズの20%を超えた場合、そのトランザクションはサーバーにより終了させられます。トランザクションはロールバックされます。このとき、エラーコード40552が戻されます。
  • TempDB の使用領域サイズ
    セッションが5GBを超えてtempdb 領域を使用した場合、そのセッションはサーバーにより切断されます。このとき、エラーコード40551 が戻されます。
  • メモリの消費
    セッションが16MB を超えるメモリを20秒を超えて使用し続けた場合、そのセッションはサーバーにより切断されます。このとき、エラーコード 40553 が戻されます。
  • データベースのサイズ
    データベースは作成時にMAXSIZEがユーザーにより選択され、設定されます。データベースがこのMAXSIZEに到達すると、データベースは Read-Only となり、トランザクションからの Update/Insert は失敗します。このとき、エラーコード 40544 が戻されます。なお、MAXSIZEは ALTER DATABASE コマンドにより変更できます。
  • アイドル状態のセッション
    SQL Azureデータベースへの接続がアイドル状態になってから30分以上経過すると、このセッションはサーバーにより切断されます。アクティブなリクエストがないので、サーバーはクライアント側にエラーを戻しません。
  • 長時間実行されているトランザクション
    24時間以上実行されているトランザクションは、サーバーにより終了させられます。このとき、エラーコード 40549 が戻されます。
  • DOS攻撃(Denial Of Service Attack)
    SQL AzureはDOS攻撃を防ぐための仕組みを実装しています。その仕組みにより、同一のソースと考えられるIPアドレスからの接続の試行が、何度も連続してログインに失敗し接続できなかった場合、DOS攻撃と見做され、一定の期間そのIPアドレスからの接続はサーバーからブロックされます。このとき、SQL Azureは接続を切断するだけで、クライアント側にエラーは戻されません。
  • 物理サーバーの負荷
    SQL Azureの負荷分散技術により、SQL Azureのデータ パーティションが割り当てられている物理サーバーにおいて高いCPU消費、I/Oの遅延、多くのWorkerがビジーとなる状態(現在32がbusy workers の閾値)が検出された場合、SQL Azure は実行されているトランザクションを終了させることがあります。このとき、エラーコード 40501 が戻されます。

上記以外にも、クライアントからサーバーまで到達する前の段階で何らかのネットワークの問題により、接続が切断されてしまうこともあります。様々な接続に関する問題に対処する意味で、接続をリトライする仕組みの実装、エラーハンドリングを確実に実装することが必要です。エラーハンドリングでは、エラー情報をログに書き出すことが一般的ですが、このログにセッショントレースIDも取得し記録しておくと、そのIDをもとにマイクロソフトのサポートに問い合わせをすることで、さらに詳しいエラーの状況がわかる場合もあります。詳しくは SQL Azure 接続系の問題に対処する編:アプリケーションのエラーハンドリングへの考慮事項 をご覧ください。

参考情報

さらに詳しい情報は、以下のサイト(英語のサイトになります)をご覧ください。

また、Windows Azure / SQL Azure のサポートについては、以下を参照ください。

--
Kayoko Gray