PLAID Engineer Blog

PLAID Engineer Blog


KARTEを提供する株式会社プレイドのエンジニアブログです。プレイドのエンジニアのユニークなパーソナリティを知ってもらうため、エンジニアメンバーたちが各々執筆しています。

PLAID Engineer Blog

超大規模システム経験者が考える、攻めの開発を続けるために大切なこと

kazushi oohirakazushi oohira

0. はじめに

PLAIDのEngineerの 大平和史 (@tai-hey) です。

前職でSEとして金融系超大規模プロジェクト(数年、数十億円規模、最大数百人)を経験し、現在は真逆となる小規模プロジェクト(4人チームでのサービス開発)でスタートアップのエンジニアとして経験を積んでいます。

ミッションクリティカルな、一つのエラーでも業務影響が存在する大規模な品質最重要のシステムと、toBではあるものの、攻めの開発かつスピード重視のSaaSスタートアップでの開発手法に目的と手法にかなりの差異を感じる毎日です。

それぞれのシステムは価値を提供するビジネスに合わせて作られるため一長一短であり、スピード重視・品質重視か、またそのバランスは生み出すビジネスの価値や目的に沿って特徴があります。その中でプレイドのこだわりはスピード重視の攻めの開発です。社員数を増やし、日々開発を進めていく中で、プロジェクトの規模が大きくなってもいかに開発スピードを落とさずにいれるかの対策を考察していきたいと思います。

メッセージ

今回のブログのメッセージをここで先にお伝えしたいと思います。「構造が硬直しがちなシステムを、肥大化する前に最適な単位に疎結合・高密度にアップデートし続け、 開発スピードを維持する」となります。

1. ビジネスモデルと社会インパクトの特徴について

まず、そもそもの品質重視の大規模システムと、スピード重視の開発では、ビジネスモデルの生まれや経緯が違うことが大きな源流となります。今後の考察にも役に立ちますので先に整理しておきたいと思います。
両者には大きなビジネスモデルの差異(受託開発かプロダクト・アウトか)と社会インパクトについての観点から分析します。

1.1 ビジネスモデル

大規模システム開発のビジネス(基本受託開発となる)

biz_jutaku-1

大規模システムは基本的に顧客から外部に開発を外注します。大規模システムの目的はミッションクリティカルで、SLAが他の業界にくらべ高く、求められる品質も高い傾向にあります。

そのため顧客の社内では開発要員の調整や、品質の保持を実現が難しいため、開発手法はウォーターフォールで実施し、顧客から求められた仕様でガチガチにシステム構築を行い、受託会社が顧客のシステムを構築します。

受託開発では顧客が仕様を決めてそれ通りに作るため、ソースコードなどの資産は顧客のものになり、顧客のものを修正することになるので修正一つ一つに契約の合意形成のプロセスが発生します。また、顧客のビジネスにほぼ100%アジャストすることが求められます。

作った後の話にはなりますが品質を求める実例としては下記のようなケースがあります。これで温度感をイメージしていただければと思います。

例えば

  • 業務を止められないので業務停止中に原則で夜10時〜朝の間に作業を行わなければならない
  • 夜間一つのジョブが落ちてしまったら業務開始までに必ずリカバリする

等があります。
     
     
    
SaaSのビジネス

biz_SaaS-1

SaaSプロダクトは自社製品としてプロダクトを開発し、顧客のシステムと連携する形になるため、プロダクトの仕様は自社で決めてそれに顧客の業務やシステムが、ある程度アジャストする方針になります。プロダクトのソースコードも自社資産になるのでコストの払い出しや修正の要否は自社で検討することになります。個別の顧客ビジネスに必ずしも100%アジャストしなくてもよいですし、プレイドの場合はKARTEを用いて新たな接客の形態や業務を提案することが弊社ビジネスの価値となります。

1.2 社会インパクト

次に社会インパクトについて比較してみます。

大規模システムの社会インパクト

受託大規模開発では顧客のビジネスや業務を理解し、深く入り込んでいくことがビジネスの強みです。個社適用でシステムを構築しており、システム作成当時から顧客数やデータ量が元々多いため、一つのミスのインパクトが社会的に大きいケースが多く、構造の変更よりも社会インフラとしての現状をいかに守るかの判断が重要視されます。

SaaSスタートアップでの社会インパクト

スタートアップも同様ではじめは小さい容量や機能でスタートすることが大半です。そのため始めは社会インパクトが小さいため実現可能性のスピードが重視される傾向にあります。ただし、今後利用顧客数も増え、インパクトが少なからず大きくなり、データ量も増大していく(弊社の場合既に大きくなっています)傾向にあります。
また、利用機能やソースコード量も増えてきます。それにより既存の顧客を守るために保守的になりすぎてしまうのはビジネスの成長を考えた時に足かせとなる可能性があります。スピード減は事業リスクとなりうるので、そうならないような事業推進について考えることが必要です。

2. 構造が硬直しがちなシステムを、肥大化する前に最適な単位に疎結合・高密度にアップデートし続ける

いよいよビジネスモデルの前提を1章で踏まえた上でSaaSスタートアップがプロダクト規模、開発規模が大きくなってきた場合、2.1のモデルを使って、どのようなリスクがあり方向性が必要かを考察したいと思います。前職で超大規模システムに携わってきた際に感じた反省から、プレイドでも同様のデメリットを発生させないために攻めのアクションを考察していきたいと思います。

2.1 価値創造のためのシステムとその構造について

model

システムとビジネスを取り巻く環境は「価値、顧客のビジネス、管理/ ルール、処理、構造」を構成要素として把握することができます。構造(アーキテクチャ)を構築して、処理(ソースコード)として記載し、管理(インプットから出力されるアウトプットデータの管理)します。そこに顧客のビジネスが乗り価値が生まれる。このモデルを元に各ビジネスとシステムの構造を考えます。

2.2 超大規模システムの特徴と変遷について

2daikibo

構造と処理を変えられないシステムは硬直化・肥大化する

構築したシステムは10〜20年前のシステムが多いと思いますが、当時の最新のアーキテクチャで作られているはずです。ただ、そこからアーキテクチャの構造を変化させることはほとんどなく現在業務を行っています。
ビジネス要件が追加された場合、処理を追加するためにソースコードは増大するのが普通です。複数サブシステムを一つのモジュールに入れてしまうようなモノリシックで構築したものはそのままとなります。

アーキテクチャを更改するタイミングは5年に一度サーバリプレース案件が発生する時があるのですが、サーバを単純リプレースするだけでかなりのコストとリスクがかかるので、ソースコードを見直してリファクタリングするような活動はされづらいです。その時の判断と企業には寄りますが、業務上最低限の移行(保守が切れるサーバを新しいものに移行する)で遂行されることが多いと思います。

このようにミッションクリティカルなシステムなためどうしても現行業務を死守しなければならないと、
・処理(ソースコード)複雑性が上がってしまうが、ひとまず動くように処理を増大させる方向に傾きやすい
・構造(アーキテクチャ)をドラスティックに変えるチャレンジが数年に一度のチャンスしかない
※但し顧客の予算とリスクテイクの関係で最低限のリプレースしか行われないことが多い。
 
という選択肢を取らざるを得なくなってしまいます。
 
 
そうすると構造を変えられないので、それを補うために処理(ソースコード)を分岐処理や冗長なコードで増大していきます。(今はクラウド化の流れが来ているが)サーバもオンプレミスのままで、アップスケールで対応するのがメインとなります。

また、増える仕様を管理するためにエクセルでの管理資料を増大させることになります。顧客のビジネス要件を満たすきめ細やかな処理を追加するたびにシステムやその管理が増大し、図の各階層のバランスが肥大化するようになります。

早い段階でアーキテクチャやソースコードの最適化や分割を行わないと、構造を硬直させたまま肥大化させてしまうことが私の経験上での反省です。

顧客のビジネスとの密着度が硬直化の要素の一つ

また、顧客のビジネスとシステムとの密着度も要因の一つと考えます。大規模システムはミッションクリティカルが多いため、システム停止などが顧客のビジネスに直結します。そのため無闇にシステム構造を変更させることもできないため硬直した巨大システムは肥大化を続けていき、構造の変革が更に難しくなってきます。

2.3 KARTEのシステム構造としての特徴について

2plaid

現状は最適に近いシステム構成

相対してスピード重視のプレイドはどうでしょうか。
 
現状私が把握できているプレイドでの構造は上記のように認識しています。プロダクトリリースから3年半が経っていて、構築にあたって2010年代に作られたこともあり、最近技術を取り入れていると感じています。構造(アーキテクチャ)を見てみるとインフラはマルチクラウドで構成され、スモールスケールで増大が可能です。処理(ソースコード)に関しても日常的にリファクタリングが行われ、日々モジュール化が行われています。

構造も処理もそれぞれモジュールとして分割して、余計なソースコードは日々削除するようになっているので、余計な関数などは積極的に集約する活動が行われているように感じます。

今後の勝負は既存のデータを守りつつ積極的に構造と処理を変革させることができるか

現状はうまく行っているように見えますが、今後のリスクもはらんでいます。それぞれの処理は現状のコード量と実現したいビジネスのバランスがある程度取れている状態ではありますが、ソースコードの全体量とそれぞれのコード量が増大しているのは間違いないです。更に既存データ量も増大しているため、サーバ上にはかなりのデータ量が格納され続けています。

そうすると大規模開発の状態にもあった顧客に対するインパクトが少なからず増大する傾向になります。本当はアーキテクチャやソースコードをドラスティックに変えていきたいですが、KARTEに入っている既存データや既存顧客のビジネスを守りつつ開発を進めることになるので、そこを考慮しつつ開発することが必要となります。

ソースコードが肥大化する前に構造を硬直化させずに、アーキテクチャやモジュールを分割、共通化、最適化を積極的に行うべきと思っています。マイクロサービス的に細かくすればよいというわけではなく、構造を変革することを直近のコストを考えすぎて先送りにするのは問題と思っているので、都度最適な粒度を検討して分割するべきと思っています。

顧客ビジネスとの密着度は疎結合でありつつ、顧客のビジネスにインパクトを与える機能実装が必要

既存のデータを守りつつ構造と処理を変革させることが必要ですが、受託大規模開発と比べKARTEは汎用的な業務を提案していくスタイルなので、顧客業務との密着度を疎結合的にそのままキープしつつ、開発スピードを上げていくことが事業の価値と直結すると私は考えています。少なくとも密着度を上げすぎるような特定の顧客向けに個別の実装をするなどは避けたいと思っています。

2hikaku

3. 直近の構造を変革させる攻めの活動

1章の前提の比較、2章までの考察を踏まえて、最後に開発スピードを落とさないために必要であった、
構造と処理を積極的に変革させていく例がありました。その例を紹介します。

リポジトリの分割による構造と処理の最適化

直近の活動としては肥大化した特定のリポジトリを分割する活動を行っています。現在プロダクトリリースから開発をしている既存の大きくなりがちなリポジトリを分割し、機能ごとにデプロイを行えるようリポジトリ分割の活動を始めています。

ディレクトリ構成の変更や、共通的に使用するモジュールの集約化や、最適化を行っています。

実際に分割直後の機能を触ってみたのですが、buildも十数秒かかっていたものが体感で一瞬で終わるまでになっています。今後のプロジェクトは常に構造を変革することを念頭に入れながら開発をしていきたいと思っています。

エンジニアとして必要なのは開発時のプロジェクト判断は、構造と処理の変革を常に頭に入れておくこと

今後様々な開発プロジェクトを推進していく立場になっていくと考えると、特に既存機能が関わる箇所については、顧客と常に相対している、ビジネスサイドとのコミュニケーションを今回の考察を元に推進していきたいです。

機能開発を進めていく際に既存顧客を守りすぎて開発スピードを落とす方向に開発を進めることは避けたいです。既存顧客は守りつつ、開発スピードを落とさない方向、または長期的に見た時に構造や処理をそもそも作り変える着想を持ちつつ、プロジェクト判断をしていこうと思います。

仲間を募集しています

CX(顧客体験)プラットフォーム「KARTE」を運営するプレイドでは、KARTEを使ってこんなアプリケーションが作りたい! KARTE自体の開発に興味がある!というエンジニア(インターンも!)を募集しています。
詳しくは弊社採用ページまたはWantedlyをご覧ください。 もしくはお気軽に、下記の「話を聞きに行きたい」ボタンを押してください!

Comments