こんにちは。GunosyでCTOをしています、koidです。こちらの記事は Gunosy Advent Calendar 2020 - Adventar の最終日の記事となります。
今回は、事業ごとに Product Owner を中心とした Product Team で組成している Gunosy において、CTOである自分は何をすべきか、この一年悶々と考えトライしてきたことを、(まだ道半ばではありますが)振り返りを兼ねて文字に起こそうと思います。
はじめに
CTO = 最高技術責任者、字義通り捉えるならば「技術に責任を持つ」ということですが、その役割は会社の業態やステージ、組織構成によって様々だと思っています。
そういえば、前CTOの @y_matsuwitter が3年前にこんな記事を書いていましたね。 tech.gunosy.io
現在のGunosyのエンジニアリング組織
少しイメージがしやすくなるように、現在のGunosyのエンジニアリング組織についての概況を書きたいと思います。
以前は、「開発本部」という組織の中に、全エンジニアが所属していましたが、現在は事業部制に移行し、Product Owner / Business Owner を中心とした Product Teamを組成しています。(グノシー, ニュースパス, LUCRA, オトクル, Gunosy Ads, Network Ads, ...)
とはいえ、全てが全て事業部制に移行したというわけではなく、Gunosy Tech Lab. や、SRE, QA といった横断型組織(職能型組織)も残っており、実際にはマトリックス風味で協働しながら、日々プロダクトの開発・改善をしています。
感じていた課題、やりたいこと
1プロダクトならいざしらず、複数のプロダクトおよびチームがある中で、全てのコードをレビューしたり、全てのデイリーミーティングに出席したり、全ての技術的意思決定に関与したりするなんてことは到底できません。
また、「必要だからやってください」と言うのは簡単ですが、Product Team 内で課題が発見され、議論され、優先順位が設定され、やる/やらないの判断ができるようになること、すなわち、チーム主体にセルフマネジメントされる組織にしていくことで、スケールできる組織(自身がボトルネックにならない組織)にしていきたいと考えていました。
セルフマネジメントされる組織を目指して
とはいえ、いきなり「セルフマネジメントしてね!」と言っても漠然としていて、何をどこから、という話かと思います。
そもそも自分はどういうことをしてたんだっけ?
技術責任者として、経営陣や事業責任者とコミュニケーションをしていく中で、よく話題にあがるのは、
- なんで障害/不具合おこったの?抑えられる?(Quality)
- サーバ費用って何に連動して増えるの?(Cost)
- 開発どのぐらい時間かかる?そもそもこれ技術的に実現できる?(Delivery)
など、「スピード」と「リスク」のバランスやコントロールに関するトピックが多いように思っています。
QCDのバランスを考え、チームで改善・向上させていく
QCDは製造業でよく用いられる考え方ですが、インセプションデッキにも出てきます。
期日(終わり、特定の期間)のあるプロジェクトにおいて、これらはトレードオフの関係にありますが、継続していく「チーム」においてはそれぞれを改善・向上させていくことが可能だと思っています。
Lead Engineer(ミニCTO)の設置
昨年、Gunosy では Lead Engineer という役割を設置し、運用を開始しました。各 Product Team における「技術的意思決定」について、Lead Engineer に委譲していく中で、下記のことを意識するようになりました。
- Lead Engineerが、スピードやリスクのバランスについて、Product Owner と合理的に意思決定・合意できるようにする
- そのために、意思決定に必要な材料、共通言語を作っていく(数値は共通言語)
計測・可視化・振り返り
改善を行っていくためには、変化やリスクへの気付きが重要となります。
振り返りによって、現状を認識し、次にとるべきアクションが明確化され、まずはそれがバックログに積まれることが必要条件だと思っています。
振り返りの習慣化
振り返りはたまに実施するのではなく、習慣化が大事だと考えています。今年は、SRE, QAのチームが主導し、障害/不具合や、コストについて定期的な(スプリント毎や、リリースの都度)振り返り会を実施しはじめました。
ゆくゆくはSRE, QAが主導せずとも、各チームにおいて自主的に振り返りが実施されるようになっていくといいなと思っています。
振り返りの材料(指標の定義・計測・可視化)
振り返りを行うためには、以前と比較してどうだったのかが大事で、例えば障害であれば、感覚的に「今週障害多かったね」ではなく、どんな障害が何回起こったのか、情報を蓄積し、分析を行う必要があります。
サーバー費用であれば、割と数値で見やすいとはいえ、ただ漠然と増えた減ったではなく、どういったコンポーネントがどう変化したのかなど、ブレイクダウンしていく必要があります。
数値は共通言語
改善のためのアクションは、ただバックログに積まれるだけでは十分条件ではなく、次に、優先順位を判断する必要があります。
優先順位を判断するためには、そのアクションの費用や効果、やらない場合のリスクがわからないと判断できないと思っています。 その材料として、今年はそれぞれの数値化、構造化を行ってきました。
例えば Cost
今年、いくつかのプロダクトでは、サーバ費用においてCost/DAUという目標を導入しました。
当然、我々も事業組織ではありますので、「利益」を出していかなければ、サービスを継続していけません。何が変動費で何が固定費かという議論はありますが、一旦省略して、変動費をアクティブユーザ数で割ると、次のように考えることができます。
Cost/DAU = リクエストあたりコスト * セッションあたりリクエスト * 1アクティユーザあたりセッション数
のように考えることができます。ここで謎のハックをしてはいけず、フォーカスすべきは、
リクエストあたりコスト = リクエストあたり消費するリソース * リソース単価
でしょうか。(もちろん、厳密に計算していくと、消費するリソースに対して安全率をかけて、突発的なリクエストにも耐えられるようリソースの確保は必要になるため、そこも考慮する必要があります)
こういった指標を改善していくためのアプローチとして、今年は下記のようなアクションが盛んになりました。
- Auto ScalingやServerlessを活用し、突発的なリクエストに耐えられるようリソースを確保しつつ、過剰なProvisioningを抑える
- RequestあたりのResourceを減らす(計算処理を効率化したり、DB問い合わせ回数を減らしたりなど)
- Spotインスタンスなど、単価の安いResourceを使う
今年のアドベントカレンダーを見たときに、Kubernetesのエントリーが多いように思いますが、Auto ScalingやSpotを活用するためにコンテナ化が進んだという側面はあるかなと思っています。
Costというと、エンジニアは割と関心が薄い人もいますが、これって結構エンジニアリングというか、エンジニアとして腕の見せどころなのではないかなと思っています
例えば Quality
今年、いくつかのプロダクトでは、サービスレベル目標(SLO)や、クラッシュフリーセッションレートといった信頼性に関する目標を導入しました。
例えば、アプリのクラッシュや、サーバーのエラーが発生すると、当然そのユーザの体験は悪いものとなり、リテンションレート(継続率)に影響を及ぼすのは直感的です。 クラッシュやエラーに巻き込まれたユーザの継続率を計測すると、如実に差が出ることがわかり、そこからクラッシュやエラーあたりの影響度合いを推定することができます。
クラッシュやエラーだけでなく、「レスポンスの速さ、アプリの起動の速さ」というのも、信頼性の1つで、リテンションレートに影響を及ぼします。(というのもデータを取得し、分析しています) もちろん、こちらもサービスレベルとして目標に入れています。
信頼性と時間やコストの関係は難しく、かけた時間やコストに対して品質は線形には比例しない(限界効用逓減)ため、100% を目指し、達成することは現実的ではありません。 事業として担保したい信頼性 = 事業として許容可能なリスクから、維持すべきラインの逆算を行う必要があります。
リリース前のQAでも、常に全項目をテストするのではなく、デグレにより発生しうるリスクを認識、区分し、目標とした信頼性を維持しつつ、効率化を行うということを進めています。
終わりに
Gunosyでは、もともと数値を元に改善していく文化があることもあり、数値化・可視化することで、Cost, Quality については少しずつ各チームで改善が進んでいるように感じています。
一方で、Deliveryについては、まだまだ計測・蓄積、数値化・可視化ができていない部分があるので、来年も引き続きTryしていきたいと思います。
まだまだ道のりは長いですが、より良いチームにしていきたいと思っています!