2024.10.10
将来は卵1パックの価格が2倍に? 多くの日本人が知らない世界の新潮流、「動物福祉」とは
リンクをコピー
記事をブックマーク
内藤研介氏:開発言語とコミュニティへの貢献に続きまして、ここからはインフラとか開発環境について、お金と技術的選択を軸にお話ししたいと思っております。
一般的に、私たちのようなB to Bサービスは、B to Cサービスに比べるとユーザー数は少ない傾向にあります。その中でもSmartHRは、主に社内の管理者が使うサービスなので、サービス自体の特性としてインフラの投資がめちゃくちゃ必要なものでもないです。
こちらの数字は、2015年11月に本番リリースした際のサーバ費用です。ステージング環境も含めた費用ですね。非常に経済的なアーキテクチャだったわけです。料金のうちのほとんどはAWSの、RDSというデータベースのサービスです。あとはElastiCacheというキャッシュのサービスとか、そういった部分が占めていました。
詳しい方が聞かれるとちょっと驚かれるかと思うんですが、Webサーバーはt2.microとかt2.smallとか、あとDBはt2.smallとか。非常に「経済的な」サービスを使ってました。
ユーザー数は、最初はもちろん少ないので、あんまりリソースがないとはいえ、本番環境ではまあまあ心もとない環境だったんですね。でも、これはこれでいいところもあったと思うことがあります。
ちょっと話が変わるんですけど「トヨタ生産方式」という言葉をご存知ですかね。いろんな取組みの総称なんですが、すごくざっくり言うと「現場の無理とか無駄をなくして効率的にしよう」という生産方式です。個人的にその中でお気に入りの概念が「在庫を持たない」です。在庫を持たないことで、ボトルネックを見つけて改善をしていくという発想です。
この発想がよく遠足に例えられるので、紹介したいと思います。遠足で1列に並んで、長い道のりを子どもたちに歩かせる場合に、先頭を足の速い子にして、最後尾を足の遅い子にする。そうするとどんどん列の幅が広がっていって、結局管理コストが上がって到着が遅くなる。
それよりも、列の先頭を1番足の遅い子にすると、その子を改善していけば最終的な到着時間が早くなる。工場のライン生産も同じことが言えるんですね。「在庫を持たない」というのは、一番能率の悪い機械のスピードに合わせて製品を生産することを意味しています。「一番足の遅い子」は、つまり一番能率の悪い機械ですね。それを改善していくと、全体の効率が良くなるという発想です。
ちょっと話が脱線しちゃったんですが、システムアーキテクチャもわりと、これに近いことが言えると思っています。ユーザーが満足するギリギリのラインのパフォーマンスでアーキテクチャを構成することで、ボトルネックが明らかになりやすくなる。改善ポイントが見つけやすくなるんじゃないかと考えております。
緊張感は多少あるんですけど(笑)、ギリギリのラインですね。実際そうやって見つかったパフォーマンスのボトルネックは、わりと早い段階で潰せてきました。人件費と比べればサーバー費用は安いもんですし、スケールアウトも簡単な時代ですし。「とりあえずサーバー追加しとこう」ってなりがちですけど、それはそれでボトルネックを見つけづらくして、負債の先送りになってしまう傾向があるのかなと感じることはあります。
今年の11月のサーバー費用です。サービス開始から丸3年経ちました。おかげさまで順調にユーザーさんも増えてきて、売上は1ヶ月目の売上なんで微々たるものですけど、それと比べてかなり伸びてきましたし、サーバーの費用も20倍ぐらいになりました。アーキテクチャも随分変わりましたね。とくに大きかったところがDBまわりです。
SmartHRでは、サービスリリース当初より「マルチテナントアーキテクチャ」というアーキテクチャを使ってサービスを提供しています。マルチテナントアーキテクチャってなんだろう、と思われるかもしれませんが、ざっくりいうと「1つの環境を複数のお客様で利用しよう」というアーキテクチャです。
お金に糸目をつけないなら、お客様ごとに環境をつければいいんですけど、なかなかそういうわけにもいかないので。世の中のクラウド型サービスといわれている部分の多くは、こういったマルチテナントアーキテクチャを採用しています。
マルチテナントアーキテクチャの中でもさまざまな形態があるんですが、SmartHRでは apartmentというgemを使って、MySQLでいうところのデータベース、PostgreSQLでいうところのスキーマ単位で、お客様のDBを作っていました。
テナントごとにわざわざDBインスタンスを作らないということは、まぁ理解できると思うんです。RDSインスタンスをお客様ごとに立てるのはなかなか、コストもかかることですし。でも「テナントごとに作る必要もないんじゃないか」というような発想もあると思うんです。確かに、それも1つの方法です。
ただ、私たちが一番避けたかったことは、開発者の考慮漏れで他のテナントのデータが別のテナントから見えるとか、ほかのテナントのデータを更新しちゃうといったことです。開発者のミスでデータが漏洩することを、仕組みで防ぎたかったんですね。
私たちのサービスは、人事労務の情報を扱うわけです。給与の情報があったり、マイナンバーの情報があったりと、かなりセンシティブな情報を扱っている。万が一に備えて「うっかりミスで漏れる」を仕組みで解決したかったので、こういったアーキテクチャを決めました。
RDBMSに詳しい方でしたら察しがつくかもしれないんですが、こういった技術的選択は、非常に大きなリスクを持っていました。それは「データのマイグレーションに非常に時間がかかる」ということです。
どういうことかといいますと、テナントごとにスキーマを用意しているので、SaaSの特性上、すべてのスキーマを同じ状態に保つ必要があるんですね。いざテーブル定義を変更しようとした場合、テナントの数だけalter tableが走るわけです。
1つのalter tableに0.5秒かかるとして、例えば100テナントあったら50秒かかる。数百~数千くらいまでだったら、まぁメンテナンス時間をもってやればできるんじゃないかな、みたいな感じですけど。
ただ、それ以上にテナントが増えてくると、だんだん管理コストが積み上がってくるわけです。
先ほどもちょっとあったんですけど、私たちのサービスの特徴として、様式の決まった書類を作るというものがあるんですね。DB上には大量の書類用のカラムがあるわけです。なので、しょっちゅうテーブルの更新が走る。それこそ週に数回、テーブルの更新が走ったりもするわけです。
結局、あるときトラブルが発生して。マイグレーションが終わらなくて、サーバーのメモリとかCPUとかリソースを逼迫してしまって、結果的に数時間のサービスダウンが発生してしまいました。
それ以前も、アーキテクチャの問題には気付いていたんですけど、本腰を入れて対応できてなくて。実際にトラブルが起きたあとにようやく、本格的なアーキテクチャの見直しを検討することになりました。
ただ、アーキテクチャの見直しから実際に刷新されるまでには、けっこう時間が必要でした。その間もサービスは成長して、ユーザーも増え続けて。データマイグレーション含むサービスのメンテナンスを、深夜にエンジニアが張り付いてやる。かなりしんどい状況になっていました。
結局、どうやって問題を解決したかといいますと、これまでよりちょっとだけお金を余分に払って、外部のDBサービスを利用することにしました。
Citus CloudというDB as a serviceです。こちらはPostgreSQLを拡張したサービスで、テナントごとにデータを分割してくれるという、まさに私たちの望んでいたようなサービスだったんですね。
実現したかったことは2点あります。もともとこういったアーキテクチャを採用した理由である、開発者がテナントのデータを意識しなくても済む、データの漏洩を考えなくても済むという状態。それから、今回発生した、マイグレーションに時間がかからないという問題。この2点をうまいこと解決してくれるサービスなわけです。
とはいえ、普通にAWSのDBサービスを使うよりはお金がかかるわけです。ただ、サービスも十分に成長していましたし、今後の成長も見込めましたし。深夜メンテナンスが不要になるということで、エンジニアの負荷も下がる。結果的に、迅速にお客様に価値を届けられるということで、十二分にペイすると判断しました。
振り返ってみて、初期の技術的選択、マルチテナントアーキテクチャでテナントごとにスキーマを用意するという選択が、適切なものだったかどうかは議論の余地があると思っております。そもそも先ほどのCitusというサービスはリリース当初にはなかったんですけど、それは置いておいて。
売上を生み出していないサービスに対して、はじめから商用のがっつりしたサービスを入れることはオーバーエンジニアリングになりがちですし、開発のスピードを殺してしまう恐れもあるわけです。一方で、まずい技術的選択は将来に大きな負債を残すことになります。
私たちエンジニアは常に、オーバーエンジニアリングと、こういった将来にわたる技術的負債、そういったバランスを取りながら技術的選択をしていく必要があると考えております。そして、結果的にサービスがうまく成長して、ユーザーが増えて、売上が上がると、取りうる技術的選択は広がると思っております。
最後に、これまでのまとめです。
お金のないスタートアップにとって、素早く開発・検証できる言語が正義だというお話をしました。そして、お金があってもなくてもコミュニティへの貢献はできるというお話をしました。最後に、オーバーエンジニアリングと技術的負債とのバランスを取りながら、技術的選択はなされるというお話をしました。
トヨタの生産方式の例を挙げて、最小限のアーキテクチャでボトルネックを明らかにする方法があるという紹介もしました。最後に、サービスが成長するとより良い選択を取りやすくなるというお話をしました。
ちょっと駆け足だったんですが、以上です。みなさまの参考になれば幸いです。ご清聴ありがとうございました。
(会場拍手)
2024.11.13
週3日働いて年収2,000万稼ぐ元印刷屋のおじさん 好きなことだけして楽に稼ぐ3つのパターン
2024.11.11
自分の「本質的な才能」が見つかる一番簡単な質問 他者から「すごい」と思われても意外と気づかないのが才能
2024.11.13
“退職者が出た時の会社の対応”を従業員は見ている 離職防止策の前に見つめ直したい、部下との向き合い方
2024.11.12
自分の人生にプラスに働く「イライラ」は才能 自分の強みや才能につながる“良いイライラ”を見分けるポイント
2023.03.21
民間宇宙開発で高まる「飛行機とロケットの衝突」の危機...どうやって回避する?
2024.11.11
気づいたら借金、倒産して身ぐるみを剥がされる経営者 起業に「立派な動機」を求められる恐ろしさ
2024.11.11
「退職代行」を使われた管理職の本音と葛藤 メディアで話題、利用者が右肩上がり…企業が置かれている現状とは
2024.11.18
20名の会社でGoogleの採用を真似するのはもったいない 人手不足の時代における「脱能力主義」のヒント
2024.11.12
先週まで元気だったのに、突然辞める「びっくり退職」 退職代行サービスの影響も?上司と部下の“すれ違い”が起きる原因
2024.11.14
よってたかってハイリスクのビジネスモデルに仕立て上げるステークホルダー 「社会的理由」が求められる時代の起業戦略