BETA

わたし(たち)がSREに至るまでの道のり

投稿日:2018-12-08
最終更新:2018-12-09

これは SRE Advent Calendar 2018 8 日目の記事です。

昨日は valerauko さんでした。


元は「ある日突然、上からSRE業務を丸投げされた話(注:フィクションです)」というタイトルで書こうと思っていたのですが、

  • 諸事情で SRE 業務をまだ本格的に始められていないこと
  • 創作するネタが思いつかなかったこと

から、テーマを変えました(すみません)。

とある自社 Web サービスのオンプレ→ AWS 移行を行った際に直面した性能面の課題と、それを克服するために行ってきたことについて記そうと思います。

前提など

  • 母体が非 IT のお堅い業界の会社の話です。
  • Java(Tomcat 8)+ MySQL で、同業者(非 IT)向けの Web サービスを提供していました。
  • データセンタでラックを数本(うち 1 本が本番環境)借りて運用していました。
    • UTM + VMware 環境(LB + Web + DB etc.)on IA Server + 外部ストレージで構成。
  • これを、AWS の ALB + EC2(Web サーバ・複数台) + Aurora(MySQL)に移行しました。
  • Dev と Ops の対立は存在せず、Dev のメンバーが Ops 業務も担っていました(オンコール対応含む)。
    • 但し、インフラを担当するメンバーは一部に限られていました。

昨年(2017年)9 月頃のことです。

システムを AWS に移行した時点での性能面の課題

実は、移行前にベンチマークを繰り返していた時点で分かっていたことですが、

  • ユーザが高負荷な状態を生み出す(例:画面表示の遅さに耐えかねてリロードを繰り返す)と Web サーバの処理が詰まる
  • 障害などで Aurora(DB)がフェイルオーバーすると Web サーバの処理が詰まる

という状況で、案の定、移行直後に早速 Web サーバが順番に不安定になりました。

※あらかじめ、このような仕組みを仕込んでおいたので、システム全停止には至りませんでした。

本来なら移行を延期すべき状況でしたが、直前にオンプレ環境のハードウェアが「故障祭り」状態になり、8 月には金曜夜から日曜まで週末をまるまる修理対応と復旧作業にあてるような事態も発生しましたので、なるはやで移行せざるをえない状況でした。

AWS 移行後のシステムが不安定になった原因は、AWS のネットワーク、特にアベイラビリティ・ゾーン(AZ)間の遅延でした(オンプレより大きくなった)。

この記事には若干の誤解があるようで、AZ 間の遅延について、

めっちゃ遅延しとるやん!!!数msっていう話はどこ行った!!!

という「怒りのコメント」がありますが(笑)、1 つの HTTP(S) リクエストを処理するのに Web サーバから DB サーバへ送られるクエリ/コマンドは、たとえ開発者がコード上に 1 個しか書いていなかったとしても、実際には数個、下手をすると数十個になることもあります。

結果、それが積み重なると AZ 間で 100ms を超える「差」が生まれます。1 往復分が数 ms たっだとしても(実際に計測してみると 1 ~数 ms の範囲です)。

「100ms ならほぼ瞬時」と思われるかもしれませんが、これが(リロードなどで)積み重なると、あっという間に Web サーバや DB サーバのコネクション/スレッドが埋まり、システムは停止します。

また、Connection Pooling を使っている場合、フェイルオーバーなどで切れたコネクションのチェックと回収・再接続処理にネットワーク遅延が影響します。

実施した対応策

このように、DB の処理時間(ネットワークの往復時間を含む)が問題になった場合、

  • DB に対するクエリ/コマンドのチューニングを行って DB の処理時間を短くする
  • Web アプリケーションの機能に制限を設けてシステム停止だけは回避する
  • 更新が少ないデータ(マスタデータなど)についてキャッシュする

などの対応策が考えられます。1 つ目については今回の Advent Calendar(5 日目)でも取り上げられています。

3 つ目については、

  • Web サーバのクラスタ全体で共有するキャッシュ(AWS ElastiCache など)
  • 個々の Web サーバのローカルキャッシュ

の利用が考えられますが、ネットワーク遅延が問題になる場合は(容量面の無駄や更新処理への対応の問題がありますが)後者について検討してみると良さそうです。

このときは、ローカルキャッシュを memcached や Redis ではなく、アプリケーション内で Java のキャッシュオブジェクトを使い、データキャッシュではなく重複リクエストのカウントを行う目的で、以下のようなものを実装しました。

一旦これで「時間稼ぎ」を行いつつ、Connection Pooling の見直しを行いました。

当初利用していた Tomcat 標準の Commons DBCP2 や、それを置き換えて使うことができる Tomcat JDBC Pool では思うように性能が出ずフェイルオーバーで処理が詰まり、また Connection Pooling をやめるとかえって平常時に処理が詰まるようになったので、このときは HikariCP への置き換えを実施しました。

ここまでの対応で、概ねオンプレ時代の性能と比べても遜色がないレベルまで回復しました。

…こうしてみると、アプリケーションのコードから AWS のインフラまで、必要になった対応策は複数のレイヤにまたがっていますね。

計測について

特に性能面に課題がある場合、やみくもに原因を推測して対応しても、良い結果が出るとは限りません。原因と有効な対応策を探すには、計測が必要です。

この記事では「対応策」にフォーカスするために、計測についてはあえて割愛しますが、実際には

  • 移行前に監視システム + インフラ観点の可視化
  • 移行後にアプリケーション観点の可視化

を進めました。

そして SRE 業務(と仲間たち?)が降ってきた

…というわけで、元々書こうとしていたテーマにつながるわけです。

ある日、唐突に「SRE をやれ」という指令?と、一緒に SRE 業務を担当するメンバーが発表されました。

SRE というと専任チームのようなイメージがありますが、残念ながら私も含めて全員兼任です。

そのため、初っ端から、サービスの機能リニューアルのプロジェクトに押されて SRE 業務にまともに取り組むことができない日々が続きました。

とはいえ、現在進行中の新機能の開発や機能リニューアルのプロジェクトの中では、

  • DB に過大な負荷を掛ける処理の改善
  • キャッシュの有効利用

などを進めています。

現在の課題

  • 人の手による温かみのある作業がたくさん残っている
    • オンプレ時代に Ansible を有効活用していたので、そのときと比較して後退した感も…
  • サービスをスケールさせるのが厳しい構成のままになっている
    • 同期 I/O、キューなどによる緩衝機構なしのアーキテクチャ
    • モノリシックで技術的負債が満載のアプリケーション
    • 固定的でクラウドフレンドリーでないインフラ構成
  • メンバーの知識が圧倒的に足りていない

…などなど、色々と山積みです。

1 つずつメンバーと協力しながら解決していくことになりそうです。


明日 9 日は _dozen_ さんです。

(偶然だとは思いますが、関連する話題を提供してくださったようでうれしいです。)

技術ブログをはじめよう Qrunch(クランチ)は、プログラマの技術アプトプットに特化したブログサービスです
駆け出しエンジニアからエキスパートまで全ての方々のアウトプットを歓迎しております!
or 外部アカウントで 登録 / ログイン する
クランチについてもっと詳しく

この記事が掲載されているブログ

@hmatsu47の技術ブログ

よく一緒に読まれる記事

0件のコメント

ブログ開設 or ログイン してコメントを送ってみよう
目次をみる
技術ブログをはじめよう Qrunch(クランチ)は、プログラマの技術アプトプットに特化したブログサービスです
or 外部アカウントではじめる
10秒で技術ブログが作れます!