自社製品の SaaS をリリースしたのですが、自分の中でのテーマは「低コスト高可用性を実現する」でした。設計に入る前にいろいろ検証して、なんとか自分がやりたかったことができたので雑に書いてみます。雑に読んでください。
低コスト
単純に「低価格でサービスを提供したいから」です。維持や運用コストが高くなればなるほどサービスの価格も高くなります。
サービス自体の低コストを実現すれば、価格面での競争力を得ます。もともとの自社パッケージ製品は機能や性能、可用性では負ける要素はないので、勝負は価格面という認識し、そこをどう実現するかを設計の第一としました。
少人数
関わる人間が増えれば増えるほど人件費も増え、さらにサービスの価格は高くなります。
そのため、今回はとにかく少人数で開発、運用できることを目標にしました。目指すのはサーバーが 100 台規模になったとしても片手で足りる人数でなんとかなるサービスです。
もともと WhatsApp や Discord が数十名で数千万、数億人というユーザをさばくサービスを提供していたというのが自分の中では憧れとしてあり、今回は多くても同時に 10 万人程度しか使わないサービスではあるので、数名で十分なはずです。
ちなみに WhatsApp も Discord も Erlang VM を利用したサービスです。今回開発する サービスもErlang VM を利用した製品の SaaS ということもあり、やれないことはないだろうという気持ちで設計を始めました。
高可用性
とにかく意識したのは高可用性です。リアルタイムな配信サービスということもあり、利用し続けられる事を重視しました。
- 落ちる可能性の低い Cloudflare を軸に置く
- バックエンドはマルチクラウド化する
- 配信サーバーはベアメタルでクラスターを組む
- 監視は自前で Tailscale を使って組む
Cloudflare Workers と Cloudflare LB
今回一番最初に決めたのが Cloudflare を採用です。特に Cloudflare Workers はスケールという点では申し分なく、さらにエッジで処理ができるため、バックエンドの負荷を減らせます。
さらに Cloudflare LB を使うことでマルチクラウド化を簡単に実現できました。
Cloudflare が落ちたらもうどうしようもないので諦めるという割り切りをしましたが、Cloudflare が落ちるといろいろなサービスが落ちるはずなので、まぁいいかなと。インターネットの 10% くらいが使えなくなると思います。
マルチクラウド
バックエンドには Vultr と Linode という最近の格安クラウドを採用しました。これらにインスタンスを立てて Cloudflare LB にぶら下げています。
バックエンドアプリは Go の Echo で書いてあるので HTTPS をそのまましゃべっています。Go は十分な性能を簡単に引き出せるので安心して使えます。
クラスター
自社製品のクラスター機能を強化し、クラスターの自動構築やネットワーク障害が発生した時の自動復旧などを徹底的に作り込んでいます。
実際サービスリリース前にカオスモンキーではなく手動でベアメタルサーバーを突然落としたりしましたが、残ったサーバーだけで稼働し続けて、サーバーが復旧したタイミングでクラスターも復旧していました。
自社製品だからこそ実現できたと感じています。
監視は自前
監視機能は既存のサービスなどを利用せず、自前運用することでコストを下げることにしました。
今回は VictoriaMetrics という圧縮率の高い TSDB 内蔵の Prometheus 互換サーバーを採用しました。これで大量の監視情報をコストを意識せずにため込むことが出来るようになりました。
実はデータベースとして採用している TimescaleDB には Promscale というのがあるのですが、こちらは元々高価なマネージド TimescaleDB を利用してることもありそこのリソースを使うのは避けたいと考え採用しませんでした。
また、すべてのサーバーに Tailscale をインストールし、経路の暗号化を行って TLS なしで監視を行う仕組みを導入しました。
正式リリース前には VictoriaMetrics 自体をマルチクラウド化して相互監視にする予定です。
ここまでで費用は月 5000 円いっていません。もちろん人件費は除きます。
高コスト
ただ「TimescaleDB」と「高性能なベアメタルサーバー」と「太いネットワーク」にはお金をつぎ込んでいます。ここはコスト削減するところではなくサービスのコアとなる製品やログを記録する場所なのでドバドバお金をかけています。
TimescaleDB は RDB + TSDB という珍しいタイプのデータベースです。こちらは自前運用ではなく Managed Service for TimescaleDB という TimescaleDB が運用してくれるマネージドサービスを採用しています。スケールアップもボタン一つでできるため、安心です。ただし大変高いです。ここは惜しみなくお金かけてます。
ベアメタルとネットワークは DataPacket というサービスを利用しています。おそらくほとんど知られていないマイナーなサービスですがあの Discord が採用しています。高性能なサーバーと太い回線を良いお値段で契約してます。
スケールアップとスケールアウト
Cloudflare Workers はスケールアウトが簡単です、何もしなくてもスケールしてくれます。
バックエンドの Go はスケールアップもスケールアウトも可能です。負荷が高くなったらサーバーのスペックを上げるかサーバーの台数を増やすかすればよく出来ています。Cloudflare LB がうまいことスケール処理をしてくれます。
自社製品もクラスターを組んでスケールアウトも出来ますし、Erlang VM で書かれているため性能が良いマシンを使えばスケールアップします。
スケールアップとスケールアウトを簡単にできるようにしたというのもこのサービス設計の重要な点でした。
構築、デプロイの半自動化
構築やデプロイなどはすべて Ansible を利用して自動化してあります。ただし流すのだけは手動にしています。自動化するコストが高いのもあり、暖かいのある手作業です。なので半自動化という感じでしょうか。
E2E テスト
本番に向けた E2E テストを Pytest と Playwright で実現しました。デプロイ後の動作確認などもすべて自動で行えるようにしました。GitHub Actions でポチッとボタンを押すだけで流せるようにしてあります。
構築と運用をしなくて良いに絞る
なんでもできる SaaS ではなく、あくまでサービス内容を本来の SaaS の特徴である「構築と運用不要」に特化させることにしました。
多機能にすることはいくらでもできますし、既存のパッケージに対して付加価値をつけてサービスを提供するということもできますが、それは一切やらないことにしました。
そこはコスト削減と「ベンダーロックインをできるだけしない」という方針をとったためです。いつでもパッケージに切り替えられるというのがとても重要だと判断しました。
まとめ
現在の構成であれば数名で開発/運用ができ、スケールも出来、高可用性も担保しつつ、価格も安く抑えられます。
これで市場での十分な競争力は得られたと思います。あとはとにかく使って体験してもらうを増やすターンということで、まずは正式リリースまでは無料で提供することにしました。約 5 ヶ月間は無料で提供します。
その間によりよいものにしていければと思います。
是非、興味があったらサイトを覗いてみてください。
もう少し細かい技術選定についてはこちらにまとめてます。