CLOSE

SUZURIにおけるSREの取り組み(全2記事)

突然の負荷増加によるサービスダウンを防ぐために GMOペパボのSREが取り組む4つの問題とその対処

オリジナルグッズ作成・販売サービス「SUZURI byGMOペパボ」に関わるエンジニアメンバーや事業部長が登壇し、SUZURIの開発の今や、現在の課題・今後の取り組みについて話す「43万人超のクリエイターの表現活動を支える!ECプラットフォームSUZURIの開発の裏側」。ここでモバイル/Webアプリケーションエンジニアの時田氏が登壇。ここからは、パフォーマンス改善の対策と取り組みについて紹介します。前回はこちらから。

事前に検出できない問題でサービスダウンすることも

時田理氏(以下、時田):という感じでいろいろやっているんですが、ちょっとこの間のセールで、実はサービスがちょっとダウンしてしまいまして。

サービスダウンは当然避けたいものではありますが、やはりけっこう突然やってきたりするものです。

セール時は最大で10倍ぐらいのリクエストが来ると説明をしましたが、そうするとふだんは特に問題ないようなところに突然負荷が増えて。それでサービスがダウンしてしまうようなことはあるので、事前に検知できればいいんですが、発生してからわかることがいくつかあるので。そういったサービスダウンとの戦いの歴史が今までにいくつかあるので、そういった対策を今日はちょっと紹介しようかなと思います。

N+1問題と対策

まずは1つ目ですが「N+1問題」です。これはいろいろなWebサービスでよく問題になるものだと思うんですけど、クエリの発行数が増えてしまうやつです。

パフォーマンスを下げる要因のたぶん第1位なんじゃないかと思っています。実は検出自体はわりとしやすくて、RailならBulletというN+1問題を検出してくれるgemがあるので、こういったものを使うと検出自体はわりと簡単にできます。

ただ、コードレビューなどの見落としで、N+1を含んだActive Recordのコードが紛れ込んでしまうことはあるので、これは減らしたい。もちろん検出できたら直しますが、セールとかになって突然エンドポイントがすごく重くなり「あ、これN+1じゃん」となったりすることはあるので、こういったのは減らしたいと。

再発防止として、N+1の検出をCI上でやるようにしています。Bulletでは検出したらログを出し、そのままCIを失敗させることができるんですが、CIでN+1が検出されたら落とすようにしました。これでたぶんけっこう紛れ込む頻度は減ったんじゃないかな、と思っています。

スロークエリの見つけ方と対処法

次はスロークエリです。これはN+1よりも検出がしづらいものになっていて、コードレビューで見つかるというよりかは、わりとDatadogなどのAPMツールを眺めていて、SQLの発行回数が多かったり、「なんか実行時間長いね」と眺めて見つけることが多いです。

これは見つけるところは、機能も実装して、リリースをして、APMツールを眺めて、場所を特定して、そうしたらActive Recordと格闘することになります。1行で書いていますがけっこう大変で。Active Record特有のSQLの組み方次第で、重くなっちゃったりすることもあるので。ここはけっこう調査が必要で、RailsのActive Record自体のコードを読んだりすることもわりとあります。

Herokuの管理方法

次はHerokuです。HerokuにはDynoというものがあり、これはすごく簡単に言うと、アプリケーションのスケール単位です。ほかのサービスだと、わりとインスタンスなどと言うことが多いと思いますが、HerokuではDynoという単位で管理しています。

SUZURIはHerokuのPrivate Spaceを使っていますが、これはDynoの数の上限が、デフォルトで100になっています。いろいろ調べた感じ、上限を上げてもらうことは可能みたいなんですがSUZURIではDynoサイズそのものを上げることで対応しています。

Dynoサイズは1台あたりのパフォーマンスのことです。これを1台あたりのパフォーマンスを上げることで、なるべく上限に近づかないように運用をしています。1台あたりのパフォーマンスが上がるので、一応何もしなくてもマシーン自体のパフォーマンスが上がるので、速くはなります。ただ、上げただけだとあまり効率がよくないので、パフォーマンスに応じた設定を行っています。

例えば、Pumaの使用スレッド数をCPUのコア数に合わせるとか。いろいろな項目があるんですが、そういったものをやっています。

データベースの問題と対策

次はデータベースです。SUZURIはHerokuのPostgres add-onを使用していますが、これがなかなか曲者です。Postgresのadd-onは、プランによって金額は変わりますが、高いプランでもConnection Limitは500で固定されていて、かつ、HerokuのDyno単位でコネクションプールをRailsは確保しようとするので、何も対策しないと、Dynoの数×割り当てられるコネクションプールが、わりとすぐ500に到達してしまうっていうのがあるんです。

たぶん2年ぐらい前だと思いますが、このコネクションプールが500に到達してしまって、それが起因でサービスが止まってしまったことがあって。それはその時に対策をしました。

その時にやったことがいくつかあるんですけど、そのうちのいくつかは、例えばリードレプリカ用のDBを用意するとかです。書き込みをしないリクエストは、リードレプリカのほうを向けることによって、コネクションを分散できると。

あとは、先ほどもちょっと説明しましたが、Dynoサイズを上げることで、そもそも必要なDyno数が減ることによって、コネクションプールの削減ができたりしました。このような感じで対策をしています。

いろいろチューニングはしていますが、機能開発とパフォーマンスの改善はわりとトレードオフなことが多いので、戦いはまだまだ続く感じです。

これからやりたいこと1:エラーバジェットの導入

次はこれからやりたいことについて話したいと思います。まず1個やりたいことがあって、エラーバジェットの導入をしたいなと考えています。

エラーバジェットというのは、サービスでエラーレートのSLOをまず決めるんですけども。例えば、エラーレートは99.9パーセント以上を確保しようと。エラーバジェットは、そのSLOと現状の差分のことを表します。

すごく簡単に言うと、その99.9パーセントに落ちるまで、あと何回500エラーを起こしていいか、というバジェットになります。

エラーバジェットはどういうふうに使うかというと、そのエラーバジェットを使い果たすまでは新機能の追加に注力していいと。それを使い果たしたら、SLOを下回ってしまうので、新機能開発をいったん止めて、パフォーマンスとかエラーレートの改善に活動をシフトさせていくようなものになります。

エラーバジェット自体の可視化はけっこう簡単です。Datadogに、確かSLOモニターかな、という機能が最近できて、これを使うとそのエラーレート、(スライドの)下のグラフを見てほしいんですが、一番左上にSTATUSと書いてあって、これは現状のエラーレート。TARGETが目的とするSLO。エラーバジェットは、このパーセントで確か管理されるのかな? あと何パーセントの余地があります、みたいな感じで表示されます。

エラーバジェット自体は30日単位で見ることがわりと多くて、例えば月の真ん中ぐらいにエラーバジェットを使い果たしたら、月の残りはもう全部、パフォーマンス改善やエラーレートの改善に取り組む感じです。

可視化自体はできていますが、もちろんビジネスとの兼ね合いがあるので、いきなりエラーバジェットの仕組みを導入するのではなく、まずは誰でも見られるような状態にして、少しずつエラーバジェットの文化をチームに導入していこうかな、と考えています。

これからやりたいこと2:プライベートクラウドの活用

あともう1個は、プライベートクラウドの活用です。先ほども少し説明しましたが、ペパボには全社で利用できるNKEというKubernetesのクラスタがあり、これをちょっと活用したいなと考えています。

SUZURIのRuby on Railsアプリケーションは12 factor appという概念に基づいて作っています。Heroku以外へのプラットフォームへの移植性は高いので、Herokuを今は使い倒しつつ、いつでもこういったプライベートクラウドのKubernetesクラスタに移行できる状態を保とうかな、と思っています。

ただいきなりHerokuをやめるとかそういう予定はまだなくて。Herokuはすごいシンプルで使いやすいサービスなので、このあたりはデプロイの手軽さと、あとは設定の柔軟性。Herokuは簡単ではあるけれども、どうしても制約はいくつかあるので、そういった部分。トレードオフを考えながら、今後そのプライベートクラウドを活用すべきかどうかを考えていこうかと思います。

もう1個具体的にやりたいことはあって、Railsアプリケーションの機能検証で、今SUZURIはプロダクション用の環境と、あとステージング用の環境が1個ずつあって。ステージング用の環境で検証を行っていますが、どうしても複数の開発者が複数の機能を別々の機能を作っていて、機能検証したい時に検証環境が空くのを待つ必要がある課題があるので、その課題を解消するために、気軽にプライベートクラウド上で検証環境を作成できるようにしようとしています。

これはインフラの専門知識がそこまでなくても簡単に使えるような仕組みを目指していて、具体的に言うとGitHub Actions、CIをトリガーにして検証環境を作って、いらなくなったら簡単に環境ごと捨てるのを実現しようとしています。

現状はSUZURIのRailsアプリケーションが、Kubernetesのクラスタ上でDockerイメージから起動できるようになるところはできたので、これからCI上に乗せて、簡単に作れるフローを考えていく予定です。

終わりになりますが、今SUZURIではSREの活動をいろいろやっているので。SUZURIのSREに興味ある方、求人募集中なので、興味持った方は応募していただければと思います。

以上です。ありがとうございました。

続きを読むには会員登録
(無料)が必要です。

会員登録していただくと、すべての記事が制限なく閲覧でき、
著者フォローや記事の保存機能など、便利な機能がご利用いただけます。

無料会員登録

会員の方はこちら

関連タグ:

この記事のスピーカー

同じログの記事

コミュニティ情報

Brand Topics

Brand Topics

  • 大変な現場作業も「動画を撮るだけ」で一瞬で完了 労働者不足のインフラ管理を変える、急成長スタートアップの挑戦 

人気の記事

新着イベント

ログミーBusinessに
記事掲載しませんか?

イベント・インタビュー・対談 etc.

“編集しない編集”で、
スピーカーの「意図をそのまま」お届け!