🔨

新規事業開発におけるアーキテクチャ設計基準

2022/03/05に公開

そろそろ忘れ始めているのでメモに残して置こうと思います。
自分がやったときに気をつけてたとことか。

注意事項

特に以下の点に注意を払う必要があります。

サービスイン最優先

売上が立たない間は開発費はまるまる赤字です。
どれだけ投資してどうやって回収するのか?
そのためにはどの程度の物を出す必要がのか?
この辺の判断は経営判断になるので、責任者と話してちゃんと決めておく。

マーケットインにしてもプロダクトアウトにしても、果たして市場があるのかとか競合に勝てるのかとかは出すまで推測の域を出ないので可能な限り早く出したいところ。
フルスクラッチで作るときは色々思うところはあるだろうがオーバーエンジニアリングをしてはいけない。

これが経営サイドの要求。

柔軟に作る

2つの大きなリスク要素が有る。

  • 市場の反応に合わせたプロダクトの方針変更
  • 顧客が増えたときのシステム負荷

あらゆる変更とあらゆる負荷に耐えることは出来ないので、何処まで方針変更を許容するのか、何処までのキャパは想定するのかは予め決めておく必要がある。

とにかく早く出すためには簡易に作る必要があるが必要があるが、立て付けがすぎると柔軟性がなくなる。
直近の経営戦略を確認して、どこがトレードオフになっているか報告し、何処を妥協するかを決めて貰う必要がある。

これが開発サイドが提示する制約条件。

検討事項

コンセプト反映

プロダクトのコア機能を実現するには何が必要なのか?
システムの本質はデータなのでデータフロー中心で考える。
そのシステムは、①何を入力して②いつまでに③何を出力するのか。

①ユーザーのPV検知と過去アクセス履歴をもとに②0.1秒以内に③最適な広告を出す
みたいな感じ。

特に②の性能要件が極めてシビアな場合、アーキテクチャは自ずと限られてくる。
インフラは詳細では有るが、実現可能性を考慮する上でインフラ知識も必要。

これはプロダクトが続く限り変わらない構造で、今後できることと出来ないことが決まってくる。
図面はレビューして機能制約に関して説明しておく。

機能拡張サポート

入出力データの本質は変わらないが、データのとり方は恐らくどんどん増えていく。
入出力は拡張可能なようにサブシステムに分割し、データモデルを抽象化しておく。

マイクロサービスアーキテクチャが流行ってるので何でもかんでもAPIにしたいところであるが、最初はそこまでする必要はないだろう。

YAGNIの法則とか言われるが、どうせ1年以内に拡張する。
拡張されなくても『データ種別』のフィールドに常に固定値が入るだけなので大した問題にならない。

どこを抽象化するかは勘所であるが、「別の構造が入ってきても動かせんことないなぁ・・・・・・」ってところは抽象化しておいて「固定値しかサポートしてねーよ」って実装で落とすのがいいと思う。

スケーラビリティ

インフラ構成が決まってくる。
AWSとか使うとオートスケールとかしてくれるので運用計画をだいぶ省力化できて非常に助かる。

対応するのは顧客数の増大なのか、顧客ごとの利用量なのかで話が変わってくるのだが、プロダクト初期は顧客を増やしたいところだと思う。
想定使用量を超えたヘビーユーザには一旦頭下げて待ってもらうしかない。

システム全体をスケーラブルにするには、まず各インフラの負荷を線形にしないといけない。
指数相関とかあったら即死である。
各々のインフラの扱うデータ特性によって対応は変わってくるが、特に気をつけたいのがデータベース。

全顧客の蓄積性データを一箇所に入れたりなんかすると、クエリ負荷は顧客数x蓄積データ量のオーダーで増えるのであっという間に逼迫する。
パーティションを分けるなりデータベースを分割するなりして水平スケールするようにしておきたいところ。

少し実装よりの話になるが、KVSの場合は定数オーダでアクセスできるのでデータベース種別も決めてしまっていいだろう。

どこまでスケールするかにもよるが基本的には水平スケールで対応を考えたほうがいいと思う。
とはいえリソースに余裕のある部分に関しては一旦は垂直スケールで逃げて、限界が見えてきてから水平スケール対応するのがいいかなと。

デプロイ容易性

初期はガンガン変更かけるのでコマンド一発でデプロイしておきたいところ。
インフラ変更も頻繁にかかると思うのでIaCで纏めて管理しておいたほうがいい。

なにげに重要なのがコンポーネント分割して独立にデプロイできること。
最初は個別にデプロイするのは手間だと感じるが、メンバが増えたときに作業を分離できるメリットが有る。

後回し事項

マルチクラウド

AWSが死ぬ心配より、プロダクトが死ぬ心配をしたほうがいい。
とはいえ特定のクラウドにべったり依存した書き方をしないほうがいいのも事実。
FaaSを避けて全部コンテナベースにすべきとか有ると思うけどそのへんは要議論。

コスト最適化

ものによるがインフラやアプリで細やかな努力するより、売上立ててスケールメリット生かしたほうが経済作用は強いはず。
運用していく中で最初期のアーキテクチャだと線形にコストが増える箇所があって原価率を圧迫するところが見えてくる。

プログラミング言語/フレームワーク

よほど性能にシビアな箇所以外はなんでもいい。(ドライバとか)
一応選定の基準として社内メンバに書ける人が多いもの、寿命が長そうなものを選んだほうが良い。
とはいえ、最悪対象のコンポーネントをリプレイスすればいいのでなんとかなる。

おわりに

異論は認める。
ケースバイケース。
要はバランス。

Discussion