個人開発(趣味プロジェクト)でプロダクトを作りながら, 本職の仕事でソリューションアーキテクトっぽいことをしているマンです*1.
最近は個人開発のネタとして,
- プロ野球選手の成績予測プロジェクト
- ヘルスケア周りの自分専用プロダクト開発
この2本軸で週末エンジニアリングをしているのですが, これらの事をしているうちに,
- Webアプリケーション + 分析用のデータ基盤の最小セット, みたいなパターンが見えてきた
- クラウドにおけるサービスの選び方・スケール(=拡張)するときに気をつけるべき勘所
みたいなのがまとまってきました.
せっかくなので, 言語化した上で再現性をもたせよう!という主旨でこのエントリーを書きたいと思います.
なお, これだけは強く言っておきます.
参考にするのは自由です&真似ができるようなプラクティスではありますが, ベストプラクティスかどうかは(この記事を読んだ皆様の)状況次第です.
一つの事例として, 参考になれば幸いです.
また,
本職の業務とは関係ない, あくまでも個人開発という趣味から生まれたお話となります.
TL;DR
個人開発および, 新規事業もしくはスタートアップのプロダクト初期構築時はフルマネージドなサーバレス系サービスで楽をしましょう, 構築もスケールもメッチャ楽です.
今回のアーキテクチャは原則「フルマネージド」もしくは「サーバレス」のどちらか(もしくは両方)の声質を持ったサービスで構築しています.
対象読者
このエントリーは主に以下のような読者を想定しています.
- お仕事で, Google CloudやAWS, Azureなどのクラウドプラットフォーム上でシステムを構築・運用している方.
- 個人の趣味・営みとして, Webサービスやデータ分析などの趣味開発・個人開発をクラウドサービス上でやっている方.
- 何かしらのクラウドプラットフォームでWebアプリケーションを作って動かした経験がある方.
更に, 以下にハマる方にはより読みやすいかなと思います.
- 新規事業やスタートアップの中で新規にWebアプリケーションを中心としたプロダクトをこれから開発・運用を予定している.
- プロダクトであるWebアプリケーションと, 社内で使うデータ基盤をまとめてGoogle Cloudで開発・運用を予定している.
- チームメンバーが少なく, 2〜3人, 場合によってはエンジニア一人ですべての開発・運用をまかないたい.
なお, 大規模なプロダクト・大企業の大きなシステムにはちょっと合わないかもしれませんが, スタートアップや新規事業のゼロイチ立ち上げフェーズ, みたいなところでは結構応用が効くと思われます.
目次
全体像
そもそも私が何を作っているのか?そしてどうやって実現させようとしているのか?の話を書きます.
何を作っているのか
何を作っているかと言うと,
オープンな野球データを元に, 「プロ野球選手の成績予測サイト*2」を構築しようとしています.
メジャーリーグの野球データサイエンスなサイトであるFanGraphsの超簡易版, みたいなのを想定しています.
プロダクトとして必要なものは,
- Webアプリケーションとその周辺システム
- データ解析・分析のための基盤
大きく分けてこの2つを想定しています.
スマホアプリは無く, IoT的なモノもない非常にオーソドックスなスタイルかなと思います.
なお, これとは別に自分専用のヘルスケアSaaSも作っていますがこれもまあ似たような構成で作っています.
アーキテクチャの絵
「野球のサイトを作る」「ヘルスケアSaaSの開発」という, 作りたいもの像から検討して試行錯誤して作っているモノの絵がこちらとなります.
個人的な開発やデータ解析・分析は全面的にGoogle Cloudを使っているため, 一部のモノ(といってもGitHubぐらいですが)を除きGoogle Cloud上に構築しています.
解説
ここから先はどういう思いで選定・構築したかの解説となります.
すべてを書くと終わらないので,
以上のドキュメントの力もお借りして解説します.
基本的な考え方
これから紹介するアーキテクチャの選定・利用した理由というか基本的な考え方ですが以下の3つのどれかにハマっています.
- フルマネージド & サーバレス重視
- 運用の呪縛から逃れる
- 「使った分だけ」のコストに収める
小規模なチームや個人開発では, 掛けられる人もお金も限られています, 何だったら個人開発で掛けられるコストは私の週末の時間とお小遣いぐらいです*3.
フルマネージド & サーバレス重視
ここが最も大事な観点で, この前提こそがすべてです.
世の中のクラウド活用やDXみたいな営みもだいぶ浸透してきたかと思いますが,やり方を間違えると,
- サービス・システムが増えるたびに運用が増える
- 都度メンテナンスや保守とかすると大変
だったりもします, もっと具体的に言うと令和のこの時代になってから「sshでサーバーに入ってライブラリをアップデート」とか, 「ビルドしたアプリケーションをscpでコピってデプロイ」とか基本やりたくはないです(そんな事しなくても出来ることまぁまぁありますので).
また, 変に仮想マシンを持ってしまうと使っていない間のコストも考えないとアカンのでそれも辛いです.
なので,
- 仮想マシン(VM)を前提とした「ある程度自分でマネージするサービス」を避けて, 「クラウド事業者が定めたSLA(Service Level Agreement)でいい感じにしてくれる」, 「フルマネージド」系サービスで基本的に構築・運用
- CPU, メモリ, ディスクなどのコンピューティングリソースを「使った分だけお支払いする」「使う予定の分の拡張が楽にできる」サーバレスなサービスを原則使う
これをルールにしました.
運用の呪縛から逃れる
「フルマネージドなクラウドサービス」の利点そのもの.
小さいアプリ開発・個人開発で運用とか保守は最小限に留めたいので,
- 少なくともサーバー周りはノータッチで行けるもの(セキュリティアップデートとか)
- アプリケーションのデプロイがコマンド一発, さらにCI/CDといったDevOpsな営みをすることで自動化できるもの
これを中心に選択しました.
例えばサーバー周りはGoogle Cloudだけでも,
- Cloud Run(今回紹介するもの)
- Google App Engine
- Firebase
- Cloud Functions
これだけの選択肢があります.
あとは長所に合わせて(もしくはやりたいことに合わせて)選択で大丈夫そうです.
「使った分だけ」のコストに収める
これはサーバレスの利点に乗っかるところ.
「使ったコンピューティングリソースの分だけお支払いください」的なサービスにより, お財布に優しいプロダクトを実現するため大事な視点です.
- 個人開発などでお小遣いの範疇でやってる
- スタートアップ・ベンチャーでシビアな予算の中やってる
これらの時にこの視点はめちゃくちゃ大事です.
また, 沢山のアクセス・トラフィックが予想される時(例えばバズったりTVに出たり)もこの考え方は重要で,
- アクセス集中が予想される時, 事前にCPU・メモリ・ディスクを増強 & CDNなどでアクセス保護
- アクセスの波が収まったら元の体制に戻す
といった, 「必要なときだけリソースを増やす(=払うべきコストを払って機会損失を防ぐ)」営みをスマートに実現するという視点もあります.
アプリケーション
ここから先は要素別に解説します.
最初はアプリケーションからです, なおWebアプリケーションで必要になるであろう以下のものは最後に補足解説します.
- データベース
- 認証認可(ユーザー認証)
Cloud Run
Dockerコンテナ化したアプリケーションをホスティングできるフルマネージド・サーバレスなサービスです.
これを使っている理由としては,
- データ分析・解析をJupyter Lab(Python)でしたあと, Python製のWebアプリにすることが多い
- かつ, Docker化して取り回しを良くする
事を普段からやっているので, 作業との相性および汎用性を重視してCloud Runにしています.
と言いつつも, ここの部分はやることによって変えるところもあって,
- ReactやVue.jsでフロントエンドを実装&アプリとして出すときはFirebaseのほうが便利なのでFirebaseを利用
- Pythonで作る時も, FlaskやDjangoでシンプルに作るときはGoogle App Engineを利用
といった形で分けています.
なお, Cloud Runは「Dockerで動くものだいたい行ける」のですが, FirebaseとGoogle App Engineは言語やランタイムのバージョンなどの制約があるので選択時は注意が必要です*4.
App EngineとCloud Runを併用したこともあって,
JX通信社で仕事した際は役割ごとに分けて活用したりもしていました.
ここについてはGoogle Cloudだけでも結構の選択肢があるので考えどころかつ面白いところかもしれません.
Cloud Storage
静的コンテンツや一部のデータファイルの置き場としてCloud Storageを使っています.
これはデータ基盤でも置き場所として使っていますが, もちろんアプリ側でも使うことがあります.
ここはあまり解説いらないかも.
GitHub Actions
「mainブランチにpushしたら, テストを流してCloud Runアプリをデプロイする」みたいなCI/CDをGitHub Actionsでやっています.
Google Cloud公式のActionsも充実しており, 非常に使いやすいです.
なお, 別の手段として「Cloud Buildにビルド環境を構築してそっちでCI/CDを回す」方法もあります.
これは要件次第で使い分けていいかもしれません.*5
データ基盤
最近脚光を浴びている「データ活用のためのデータ基盤」的なシステム.
前回のエントリーでは「データ人材のためのキャリアパス」的な話でしたが, 今回は「データ基盤をなるべく小規模かつシュッと始める方法」について解説します.
BigQuery
Google Cloudで代表的なDWH(Data Ware House)プロダクトで, これももちろんフルマネージドなサービスとなります.
野球のプロダクトでは,
- 日々収集しているデータの格納先
- 機械学習ワークフローを回す時の元データ
としてフル活用しています.
(最近はあまり聞かなくなった気がしますが)「使い方を間違えると料金が!?」という話もありますが, 安心してください, ちゃんと使えば大丈夫です.
使い始める前にこのブログを読むことを強くおすすめします.
Cloud Storage
再び登場, Cloud Storage.
BigQueryに保存する前の生データ(いわゆるraw data)の保存先として使っています.
ちなみに, 「BigQueryに保存する前の生データをStorageで保存」するのは間違いなくベストプラクティスで,
- 障害時のバックアップ
- BigQuery以外の手段での解析・分析のDatalakeとして使う
- データ収集・保存タスクの再実行
といったところで無いと詰むので絶対やったほうがいいやつです.
なお, Storageの利用タイプや保存期間(ファイル変更がないまま保存すると長期保存になってお安く済む)とかあるので, 容量用法を把握して正しく使うと良いかもです.
Cloud Functions
関数ベースの小さいプログラムを動かすためのサーバレス・フルマネージドなサービスで, 「Google Cloud版AWS Lamda」みたいなものです.
以下の小さいアプリケーションを動かす動作環境として使っています.
- Web上からデータを集めるためのクローラー. WebページをスクレイピングしてネタをStorageに保存(Crawler)
- Storageに保存したデータを加工してBigQueryに保存(Loader)
これらは毎日決まった時間に動かしていまして,
- Cloud Functions関数をPub/Sub(キュー)にメッセージを送ることで動かす設定に
- 決まった時間にPub/Subにメッセージを送る(=Functionsを動かす合図)ためのCloud Scheduler
を仕掛ける(ちょっとしたピタゴラスイッチ的な)バッチシステムとして運用しています*6.
絵にするとこういう感じです.
Compute EngineなどのVMでわざわざバッチを作らなくてもこれだけでいけるのでオススメです, 私はこんな感じでやりました.
気をつけるべきポイントとして, Cloud Functionsは動作時間の制限があります(1リクエストあたり9分*7)ので,
- 長いかつ複雑な処理はCloud Composer(Apache Airflowのフルマネージドサービス)でDAGに処理を書いて実行
- もしくはCloud Runで同じような処理を実現*8
といった工夫が必要です.
分析環境
個人的には,
- Google Cloud Consoleでやる
- 自分のPCに作ったJupyter Lab環境でやる(ここが唯一のフルマネージドでもサーバレスでもない部分*9)
これがめちゃくちゃ多いのですが, 人におすすめする際はGoogle Colaboratory(Colab)を強く推奨します.
- 環境構築が不要
- GitHubと連携できる
- チーム内共有などが楽
もう, 利点しか無いぐらいの良いサービスなので初手はColabを活用し, 必要に応じてAI Platformなどを使うのがベストかなと思います.
こんな時どうする?
今回のアーキに入っていないものの, 絶対出てくる以下のケースに付いての見解です.
- アプリケーションの認証・認可
- どのデータベースを使うか?
アプリに認証・認可を入れる
こちらは分けて考えると手数が少なく済むかなと思います.
- すべてGoogle Cloudに閉じる構成であれば, IAP(Identity-Aware Proxy)に則った認証を実現する. 要件がハマればほぼ未実装で実現可能.
- JWT認証などが必要な場合, 認証(ユーザーのログイン・ログアウト, token管理)はFirebase Authenticationで設定しつつ, アプリ内に取り込み&API Gatewayで認証を行う. アプリ内の認証実装が大幅に減る(ログイン用のフォームに埋め込んで終わる)のでオススメ.
これらを前提に行うと, わざわざ自分で認証の実装をしなくても実現できる可能性が高いです.
私もこの方式で実装を行っています.
なお, 「ユーザーAは管理者だからフルアクセス, ほかは参照権限のみ」みたいな「認可」はアプリケーションの仕様に依存するところが大きいため, 実装を考える必要があるかなと思います.
データベースを使う
Google Cloudの場合,
- Cloud SQL(MySQL, PostgreSQL, etc...いわゆるRDBMSのマネージドなエンジン)
- Cloud Spanner(大規模利用・アクセスに向いたRDBMS風の大規模データベース*10)
がいわゆるDBっぽいサービスになりますが, 個人開発および小さいプロダクトだとここまで用意するのは大げさかも?というユースケースがあるかなと思います.
実際, 私の個人開発はそうなので, 「SQLっぽい記述ができる」かつ「サーバレス・管理不要」なCloud Firestoreを活用しています.
なお, リレーショナルデータベースではないのでトランザクション管理だったりそれっぽいことをやりたい!と出てきたらCloud SQLを選択するかなというイメージです.
迷った時は
以上, 自分がやった事をベースにしたプラクティスの紹介でした.
ここまでやるのに, 公私ともに手を動かして覚えたこともありますが, いくつか参考にしたものもあるのでちょこっと紹介します.
書籍
Google Cloudの公式ドキュメントもよく揃っているのですが, やはり手元に1冊2冊本があると調べ物の時に最適です.
個人的にはこの辺をよく参考にしています.
このエントリーで紹介しきれなかった,
- 大規模エンタープライズ向けの設計・観点での考え方
- サービスアカウントの取り扱い・組織設計
この辺はユースケース含めて参考になるかと思います.
公式のアイコンライブラリ
最も身近かつ, 今すぐ参考にできるものとして, Google Cloudの公式アイコンライブラリがあります.
こちらのGoogle Slide版にはいくつかサンプルのアーキテクチャがあるのですが, これを眺めるだけでもいくつかパターンが存在し, 結構勉強になります.
「手っ取り早くオススメがしりたい!」という方はこちらを見るといいかもしれません.
結び
というわけで, 「Webアプリとデータ基盤をサクッと立ち上げるためのプラクティス」という題材で自分が個人開発・小さいプロダクトでよくやるGoogle Cloudの使い方を紹介しました.
小規模なシステム・サービスはこの手の考え方で結構行けると思いますし, AWSやAzureといった他のクラウドを使うときも参考になるんじゃないかなと思います, サービスを置き換えて探せばなんとかなるという意味で.
個人的には今, Google Cloudの資格とかも取りにいってるので, 知識と実際の構築両方で経験積んでこの辺りもっと上手くなるぞ!というお気持ちです.
やってて楽しいんですよこれ, 仕事にもつながるのでオススメです!
*1:なぜ, こういう二重生活をしているかの話はこちらを参照.
*2:これはちょっとずつ進めながらいずれ披露したい
*3:(多少自虐的に言うと)週末はあまり遊ばない&独り暮らしでお小遣いの範疇もまあまあ広いのでやれることはまあまあ多いのかもしれない苦笑
*4:FirebaseはJavaScriptオンリー, App Engineは選択可能な言語が限定される(スタンダートとフレキシブルでもぜんぜん違う)ので注意が必要です.
*5:「RepositoryのコピーをCloud Source Repositoriesに保持して, そこのトリガーからCloud Buildを使う」みたいなパターンはたまに聞きます
*6:「トリガーとなるイベントと実際の振る舞いを別々のサービスの組み合わせでやる」のは正にクラウドサービスを活用したシステム開発の勘所で, 「昔はプログラム書いてそれをcrontabで動かしてたのよな」の「crontab」と「プログラム」を分けて考えることができるか?みたいな思考が問われます(実務経験とクラウドサービスの知識両方が問われる).
*7:これは今後出るCloud Functions第二世代では結構緩和されるらしいです.
*8:ちなみにCloud Functions第二世代は裏側がCloud Runで動いてるらしいのでこのアプローチは早々になくなるかもしれません.
*9:ここは単純に慣れというかやりやすさ・好みの問題です. チームでやるときは絶対Colabがいいですし, 個人開発じゃなければ私もColabを使うかなと思います.
*10:これはホントに強いサービスで, 個人的にはまだ使ったこと無いので使いたいなという憧れがあります.