コミューンのアーキテクチャ選定

はじめに

こんにちは。

前原夏樹と申します。

コミューン株式会社のSREチームでアクティングマネージャーをしています。

今日は当社のプロダクトであるcommmuneのアーキテクチャについてざっくり紹介していきたいと思います。

今回公開に至った動機としては知見の共有が最も大きいです。

運用負荷が比較的低いマルチテナントSaaSのアーキテクチャの具体的な一例として、どのようなアーキテクチャにしようか悩むエンジニアの参考情報になると嬉しいです。

現在のアーキテクチャについて正直素晴らしいエレガントなアーキテクチャだとは思っていません。改善すべき箇所はまだまだ存在しています。

しかし、改善に改善を重ねつつ必要なところでは負債を返して(あるいは返そうとして)おり現実的に戦っていけるアーキテクチャではあるなと自負しています。

(あわよくば改善提案、今後ぶち当たりそうな問題など諸先輩方のフィードバックをいただけると非常に助かります。または『こんなアーキテクチャぶっ壊して俺が最強のアーキテクチャを作るんだ!』っていう気合の入った方も是非当社の開発チームに応募いただきたいです!)

では紹介していきます。

そもそもcommmune って何?

アーキテクチャについて紹介する前にその前提となるサービスとその特性について簡単に紹介させてください。

サービスの紹介

commmune はBtoBtoXのSaaSで、コミュニティサクセスを実現します。

(LPはこちら -> https://commmune.jp/

詳細はLPから見ていただけると良いです。

本当に簡単に説明するとcommmune の基本的な機能はコミュニティ構築とその運用支援、自動化です。

構築されたコミュニティは当社のインフラの上でマルチテナント的に動作します。

ユーザはそのコミュニティの中で様々なアクションをすることができます。代表的なものとしては投稿の閲覧や投稿です。

これらのアクションに応じてトラフィックが発生します。

特性について

commmune が受け取るHTTPリクエスト・トラフィックについては以下のような特性があります。

  • 種別
    • データ更新、書き込みのリクエストよりも取得系のリクエストが多い傾向がある
    • 基本的には低負荷
    • マーケティングキャンペーン等の利用でスパイクすることがある

この特性を念頭においてアーキテクチャとその問題点について話していきたいと思います。

旧アーキテクチャとその問題点

以前のアーキテクチャは非常にシンプルな作りでした。

簡易的な図がこちらです。

old architecture

リバースプロキシとしてNginxを立てて1台のCompute Engineの内部でフロントとバックエンドのサービスを運用していました。

DBはGoogle Cloud のCloud SQLを利用していました。

サービスの立ち上げ当初はこのアーキテクチャで問題なく運用できていたのですがサービスの成長・ユーザの増加にしたがって段々と問題が噴出し始めました。

以下で背景を含めて紹介します。

問題1:増減するトラフィックに対してコスト最適なマシンスペックを設定するのが運用上難しかった

トラフィックは大幅に増減するのに対して、コンピューティングリソースはサービスを停止しないと変更できなかったために普段のトラフィックでは必要のないレベルの性能のマシンを常に動かす必要に迫られていました。

シンプルに費用対効果が悪い作りになっていました。

問題2:トラフィックのスパイクでサービスが過度に不安定になっていた

サービスの成長、顧客数の増加とともに想定していない数のトラフィックが来るようになりました。

その結果サーバーの処理性能を超えてしまうことでサービスが不安定になっていました。キャパシティプランニングが不足していたことも原因の一つでした。

問題3:動作環境としてのVMの管理が煩雑になってしまっていた

IaCツールを用いた設定が行われておらず手動で設定が行われていました。

これにより各環境で各種ミドルウェアのバージョンを調整したりするのが苦痛な作業となって運用負荷が上がってしまっていました。

実際に環境ごとに多くの差分が発生していました。差分の影響で問題が発生することはなかったのですがこれはおそらくただのラッキーだったと思っています。

このような問題が積み重なった結果、抜本的な問題解決のためにアーキテクチャを見直すことになりました。

打ち手としての新アーキテクチャ

上で述べた問題を解決すべくアプリケーションの基盤を移行することになりました。

新アーキテクチャ

移行後の姿がこちらです。

リバースプロキシはNginxからCloud Load Balancingへ、サーバーはCloud Runへと移行しました。

(一部エンドポイントはリソース的な問題でCompute Engineで動作しています。)

これにより旧アーキテクチャの抱えていた問題点が大幅に改善されました。

  • 問題1:トラフィックは増減するのに対してコンピューティングリソースは固定されていたためコスト最適なマシンスペックにするのが難しかった
    • 解決:オートスケールしてくれるCloud Runのおかげで最適な設定ができるようになった
  • 問題2:トラフィックのスパイクで過度にレイテンシーが上がってしまい、まともにサービス提供できなくなることがあった
    • 解決:オートスケールしてくれるCloud Runによってサーバー起因のサービスの品質低下がほとんどなくなった
  • 問題3:動作環境としてのVMの管理が煩雑だった
    • 解決:Cloud Runを利用することでDockerfileでの環境定義が行え、ランタイムへの変更の反映も容易になりました

サービス選定の内訳

サービス基盤の選定のための制約条件としては以下のようなものがありました。

  • GoogleCloudのサービスであること
    • GoogleCloudにロックインしておりマルチクラウド化のコストを払える体制でなかったため
  • オートスケールする基盤であること
    • サービスの成長に従って継続的なトラフィックの増加が見込まれたため
  • 移行作業のコストが低いこと
    • 移行を決めたタイミングでは既にトラフィック起因のサービス障害が起こり始めており移行までの猶予がかなり短かったため
    • 技術的な知見を持っているメンバーがいるかどうか
  • 旧アーキテクチャにおいて発生していた問題が解消・緩和されること

実際に選択肢にのぼっていたものとしては以下がありました。

いずれもGoogle Cloudのサービスです。

  • GKE
  • App Engine
  • Compute Engine
  • Cloud Run
  • Cloud Function

先述の制約条件に基づいてこの選択肢を評価するとGKE,Cloud Functionが移行作業および運用のコストが高そうということになり却下、管理コストが高いためCompute Engineが却下され、App Engine とCloud Run の二択になりました。

GoogleCloudのサービスであること オートスケールを備えていること 移行コストが低いこと 旧アーキテクチャの問題の解消
GKE ×(チームにk8s知見のあるメンバーが不在だったため)
App Engine
Compute Engine × × ×
Cloud Run
Cloud Function ×(エンドポイントの切り分け等の対応に時間がかかってしまいそうだったため)

そこでApp Engine採用について検証したところcommmuneをApp Engine上で動かすのが難しいことが判明しました。理由は以下のようなものでした。

  • commmune のサーバーサイド周りの作りが若干特殊でApp Engineのフレームワークにそぐわなかったこと
    • (正確にはFlexible環境を使えば実現可能そうでしたがかなりリファクタリングをする必要がありそうでした。)

そこで最終的に柔軟にランタイムの定義が可能でかつ制約条件を全て満たすCloudRunが採用されることになりました。

成果

なんやかんやあって新しいアーキテクチャでのリリースが終わりました。

結果としてサービスの安定性も増し、運用が信じられないくらい楽になって運用負荷の低減とサービス品質の向上でチームとしては大満足な結果でした。

スケールアウトのための深夜メンテナンスもいらなくなったことに加え、デプロイ時のローリングリリースの安心感も増しました。

いまやCloud Runは大好きなサービスの一つです。

新たな課題

移行は完了したもののサービスのフェーズは絶えず変化し続けており、呼応するようにアーキテクチャへの要求も流動しています。

当然現在のアーキテクチャが完全な理想郷というわけでなく他にも様々な課題が現れてきています。

かいつまんで紹介します。

  • さらなるコスト最適
  • 一部のワークロードを任せているCompute Engineからの完全な脱却
  • 大量のユーザによるトラフィックの配信処理の効率化
  • 海外進出をうけたデータの配置場所の整理
  • メールや通知処理のリアーキテクチャ
  • etc…

インフラに関連する部分で思いつくままにあげてみました。まだまだ多くの改善点があります。

これからもチームとしてさまざまな課題にチャレンジできることを楽しみにしています。

最後に

簡単にアーキテクチャの紹介を行わせてもらいました。

当社のSRE、エンジニアチームではさまざまな職種の方を絶賛採用しています。

よいプロダクトを作りたい方、課題を解決することが好きな方と一緒に働けると嬉しいです。

私個人のMeetyも貼っておきます。

https://meety.net/matches/sAdpUSpSyKoD

採用文脈以外でも仕事について気になること、質問、情報交換などあれば気軽にカジュアル面談の申し込みをしてください。

最後まで読んでいただきありがとうございました。