PONCOTSU

インフラ領域を主にあれしてます

CloudSQLのメンテナンスに対する運用を考える

CloudSQLを使っていると逃げきれない仕様の一つに定期メンテナンスがあります。 数ヶ月に一度、最大で90秒ほどDBインスタンスが落ちる仕様なため、プロダクション環境などでCloudSQLを利用していると、必然と90秒のメンテナンスによるサービスダウンが発生しかねません。

頑張って高可用クラスタ冗長化)してたり、リードレプリカを作成しても、メンテナンス中はすべて停止してしまうため、サービスダウンは不可避です。

そんなわけでCloudSQLのこの仕様について頭を悩ませているインフラ運用者もきっと多いはず!
ということで2年くらいCloudSQLを運用してみえた運用方法の策定基準をまとめてみます。

前提

  • サーキットブレイカーの導入など、アプリケーションレイヤでのDBインスタンスの停止(GCPが一番推奨している対策方法)に対する処方は抜きとする
    • モノリスなのかマイクロサービス なのかで打ち手は変わってくるし、もちろんSLAにも関連してくるため、方針を決めるための考慮点が多いので今回はスコープアウト
  • アプリケーションに手を入れず、CloudSQLを運用するインフラエンジニアだけでなんとかしなきゃいけないケースを想定
  • 本番サービス運用を想定
  • 特にSLAを重要視して作った運用方針案

3通りの考えられる運用方針

1. 自動メンテナンスのなすがままパターン

方針
CCPが自動で決めたメンテナンスタイミングに従って自動メンテナンス作業をしてもらう方針です。インフラエンジニアのメンテナンス作業はほぼいらないので楽といえば楽ですが、メンテナンス作業時間幅を設定していないと、不意に作業が開始されて期待しないサービスダウンが起きてしまいかねません。

【この方針を採用できるサービス例】

  • いつサービスが落ちても重大な被害がない(SLAを設定していない場合など)
  • 数ヶ月に一度の90秒程度のサービスダウンなら許容できる
    • 日中は困るが、深夜帯ならサービスダウンが一瞬起きても許容できる場合も採用できる

【この方針をとるときに設定しておくべきこと】

  • MUST
    • 特になし
  • 推奨
    • GCPからメンテナンスについての事前通知を受け取る設定を行なう
    • メンテナンス時間幅の設定を行なう

2. 事前に手動でメンテナンス作業を実施するパターン

方針
CloudSQLでは1週間前にメンテナンスするーという旨の通知をもらうことができます(設定してないと通知はこない)。通知を受け取ったら1週間以内にメンテナンス作業を手動で実施することで、意図しないサービスダウンを防ぐことができます。ただしサービスダウン自体は発生するため、あくまで「サービスダウンが起きる時間を固定し、ステークホルダにその旨を知らせることができる」という利点があるのみです。
なお事前通知を受けてから1週間後に自動メンテナンスが走りますが、通知を受けた際に「延期」することも可能です。最大でさらに1週間ほど実施タイミングを伸ばせるので、ステークホルダへの合意・共有に時間を要する組織であればこの設定もしておくとよいです。

【この方針を採用できるサービス例】

  • SLAが定義されており、サービスをダウンさせる場合はステークホルダへの合意が必要なケース
    • 調整にかけられる時間は最大で2週間なので、それ以上に時間が必要な重厚長大な組織の場合は当てはまりません
  • 1〜2週間程度の間でメンテナンスのためにインフラチームの工数を確保できる柔軟なチームの場合

【この方針をとるときに設定しておくべきこと】

  • MUST
    • GCPからメンテナンスについての事前通知を受け取る設定を行なう
  • 推奨
    • メンテナンス作業の延期申請
    • メンテナンス時間幅の設定を行なう

3. 繁忙期だけサービスダウンを拒否し、それ以外の期間では2.で運用するパターン

方針
CloudSQLではメンテナンス作業を拒否することができます。最大で拒否できる期間は90日で、メンテナンス作業時間が設定されていてもこの設定がある場合はメンテナンスが行なわれません。しかしあくまでサービス特性上、繁忙期は1秒でもサービスを落としたくないといったニーズへの対応であり、メンテ工数・メンテナンスによって生じるサービスダウンタイムを増やしたくないという理由で拒否をするは避けた方がよいと個人的には思っています。繁忙期以外の期間では、2.で提案した運用に切り替えます。
注意点としては、年に1度しかこの拒否設定はできないため、年に複数回のキャンペーンを行ない、そのキャンペーン中はサービスを落としたくない、といったニーズには答えられません。
こうなってくるとアプリケーションレイヤに手を入れなければなりませんし、マイクロサービス 前提のアーキテクチャになっていないと実現は難しいです。

【この方針を採用できるサービス例】

  • 季節要因により負荷が高まるサービス
  • キャンペーンを行なう予定のあるサービス

【この方針をとるときに設定しておくべきこと】

  • MUST
    • GCPからメンテナンスについての事前通知を受け取る設定を行なう
    • メンテナンス拒否設定を行なう
  • 推奨
    • メンテナンス時間幅の設定を行なう

所感

すべて泥臭い運用方針でイケてる提案ではないですが、現在のCloudSQLの仕様上、しょうがないのかな?とも思っています。
せめて高可用クラスタやリードレプリカはローリングアップデート方式でメンテナンスしてくれよという気持ちでいますが、実現するでしょうか...

他、「うちはこうしてるよー」というアイデアや、「もっといい方法あるやん」というツッコミ、まってます。