Aurora のカスタムエンドポイントを使ったサービス可用性の改善

こんにちは。アソビューで SRE チームを担当している秋元です。

アソビューのシステムやサービス運用をする上での取り組みを紹介していきたいと思います。
今回は、Aurora のカスタムエンドポイントを使ってサービス可用性を改善している話を書きたいと思います。

アソビューではデータベースに AWS の Aurora を使用しているんですが、Aurora のカスタムエンドポイントという機能を使って一部のサービスレベルの高いアプリケーションが他のアプリケーションの影響を受けないようにしています。

Aurora のカスタムエンドポイントはそれほど新しいネタではありませんが、アソビュー内の取り組みの紹介ということでご容赦いただければと思います。

前提

他のスタートアップのサービスでもよくあるケースかとは思いますが、アソビューのシステムでは複数のアプリケーションから参照されている Aurora クラスターがあり、そこの負荷が高まると参照している全てのアプリケーションのレスポンスに影響が出てしまう、という問題がありました。
またこの Aurora クラスターへは、アプリケーションからのアクセス以外にも、集計、分析用の重い SQL が実行されているなど、様々な用途に使用されていました。
そのため、集計、分析用の SQL やサービスレベルのそれほど高くないアプリケーションによる負荷の増加が、サービスレベルの高いアプリケーションに影響を与えてしまうという状況でした。
本来であれば、少なくともスキーマなどの単位でアプリケーションごとデータが分割されているのがいいかと思いますが、テーブルレベルで共有されているものもあり、データ移行してクラスターを分割、というのも難しい状況でした。

改善の対応

この状況を改善するために、Aurora のカスタムエンドポイントを利用し、ロールごとにアクセスするリードインスタンスを分割しました。
これにより、サービスレベルの高いアプリケーションが他のアプリケーションの影響を受けないようにしたり、データ集計などの重い SQL の実行がアプリケーションに影響を与えないようにすることができました。

Aurora カスタムエンドポイント

具体的にどういった対応をしているかをお話しする前に、Aurora カスタムエンドポイントとはどういったものかをご説明します。

Aurora にはデフォルトで writer と reader のエンドポイントがあり、writer のエンドポイントに接続すると、Aurora クラスターのマスターインスタンスへ、reader のエンドポイントに接続するとリードインスタンスのどれかへアクセスします。
このデフォルトのエンドポイントに加えカスタムエンドポイントを設定することができ、接続するリードインスタンスを柔軟に設定することができます。

接続する先のインスタンスは、ブラックリストかホワイトリストで指定できます。 AWS CLI で作成する場合、ブラックリストは --excluded-members オプションで、ホワイトリストは --static-members オプションで指定できます。

docs.aws.amazon.com

カスタムエンドポイントには

  • READER
  • ANY

の 2 種類があります。
READER のエンドポイントはマスターインスタンスが接続先の対象から除かれますが、ANY の場合は除かれません。

どのように使用しているか?

現在 3 つのカスタムエンドポイントを作成して使用しています。

  • アプリケーション用(サービスレベル高い)
  • アプリケーション用(その他)
  • 集計、分析用

f:id:akmtr:20191105143427j:plain
Aurora カスタムエンドポイントの構成

カスタムエンドポイントの設定

それぞれの設定は下記の通りです。

エンドポイント インスタンスの指定 エンドポイントのタイプ
アプリケーション用(サービスレベル高い) static-members ANY
アプリケーション用(その他) excluded-members READER
集計、分析用 static-members READER

設定の意図は下記の通りです。

  • 「アプリケーション用(その他)」のインスタンスをスケールアウトさせるケースが多いので、インスタンスの指定を excluded-members で行なっています。
  • 「アプリケーション用(サービスレベル高い)」のインスタンスがマスターインスタンスになってもアクセスできるように、エンドポイントのタイプは ANY で指定しています。
  • 「集計、分析用」のアクセスがマスターインスタンスに影響を与えないよう、エンドポイントのタイプは READER に指定しています。

フェールオーバーの設定

Aurora クラスターのインスタンスは、フェールオーバーが発生した際にどれがマスターインスタンスになるかの優先度を設定することができます。
カスタムエンドポイントを利用してロールごとにアクセスするインスタンスを設定している場合、優先度を適切に設定しておかないとマスターインスタンスへの昇格で、本来負荷をあまりかけたくないインスタンスに意図せず負荷がかかってしまいます。

弊社では優先度を下記のように設定しています。

  • 「アプリケーション用(その他)」のインスタンスの優先度を小さく、「アプリケーション用(サービスレベル高い)」のインスタンスの優先度を大きくし、「アプリケーション用(その他)」のインスタンスに基本的にフェールオーバーするように設定しています。 (優先度の設定値が小さい方が優先的にマスターインスタンスに昇格します。)
  • 「アプリケーション用(その他)」のエンドポイントのタイプは READER にし、フェールオーバーが発生してもマスターインスタンスに余計な負荷がかからないようにしています。

まとめ

今回は、Aurora のカスタムエンドポイントの機能を利用して、アクセスするインスタンスを分散させる対応をご紹介しました。

  • Aurora のカスタムエンドポイントの機能を利用することで、アクセスするインスタンスを分散することができます。
  • 複数のアプリケーション間でテーブルレベルでデータが共有されている場合でも、低コストで分散することが可能です。
  • カスタムエンドポイントの設定やインスタンスのフェールオーバーの設定を適切に行わないと、運用を進めるうちに意図しない構成になってしまうので注意が必要です。

こちらは Aurora のシングルマスターのクラスターを想定して記載しています。
書き込みの負荷を分散させたい場合は、 Aurora のマルチマスター、Aurora クラスター間のレプリケーションなど、別途対応を検討する必要がありますので、ご注意ください。