ニーリーのSREによるリリースサイクルの改善〜「隔週深夜1回→1日2回」にリリース頻度を向上させた道のり〜
プロダクト開発グループSREチームの大木(おおぎ)と菊地です。
突然ですが、皆さんのプロダクトではリリースはどのように行われていますか?
実は、ニーリーのメインプロダクトであるPark Direct(パークダイレクト)はわずか1年前まで隔週に一度、深夜0時からしかリリースを行うことができていませんでした。開発組織の健全性の指標として使われる d/d/d (deploys / a day / a developer) という指標で、1年前の我々は d/d/d=0.015ぐらいのスコアでした。この指標は d/d/d >= 0.1 が健全な組織としての目安となるそうです(※1)。かなりの開きがありますね・・・。
この記事では、SREチームのリリースエンジニアリングと開発チームのプロセス改善により、リリースの頻度が大幅に向上したというお話をしたいと思います。
当時のリリースサイクルとその限界
「隔週に一度、深夜0時から」というのは、プロダクトのローンチ直後の手動リリース(scpなどでやっていました)時代のサイクルがそのまま定着してしまったという歴史的経緯が大きいものの、一方で理にかなっている面もありました。
まず、Park DirectのtoB側のお客様は不動産管理会社さんであり、その営業時間を避ければ明確なオフピークになるので、深夜に計画停止時間を取ることは妥当です。多くのtoBサービスで同様のことが言えるはずです。また、2週間developブランチに差分を溜めておき、リリース前日にstaging環境にデプロイしてまとめてリグレッションテストを行うというのは、QAエンジニアが少ない(または不在の)場合には効率的と言えます。深夜作業が発生してしまうのはもちろんツラいのですが、社員のエンジニアもじわじわ増えていて担当を分散できるようになっていったのも、「たまにしか深夜作業にならないし、まぁいいか」というマインドを生み出してしまっていたと思います(言い方がアレでしたが、分散は一つの有効な手法です)。
その、ある意味コンフォート化していた「隔週に一度、深夜0時から」というサイクルが限界を迎えたのがちょうど1年前です。まず、変更障害率が非常に高くなっていました。2週間溜めた差分をビックバンリリースするので、当然それぞれの影響範囲が複雑に絡みつき想定外のバグを生み出します。その都度hotfixが必要になり、そしてそのhotfixのリリースはまた深夜に行うしかないのです・・・。
もう1つの限界がフロー効率です。前述の通りエンジニアの数も増えており、開発自体の速度はどんどん上がっていました。しかしリリースは2週間ごとにしかできない。事業のスピードを止めない、むしろ加速させるべき開発が、事業の足を引っ張っていたと言えます。メール文面の修正のような非常に軽微な修正も出せるのは最大2週間、文面に不備があってもその間はカスタマーサクセスにカバーしてもらって耐え忍ばなければならない、そんなイメージです。他部署にしわ寄せが行っているのは改善したかったですし、なによりユーザーになるべく速く価値を届けたい、その思いでリリースサイクル改善施策がスタートしました。
フェーズ1:「ゼロダウンタイムリリース」への道
「リリースサイクルを改善する」ためにはいくつものアプローチが考えられます。例えば深夜作業を増やして毎週やろう、というのも有効です。運用に耐えることさえできれば単純に2倍に向上させることができます。SREチーム主導の施策ではあったものの、実際に運用するのは開発チームなので、入念なヒアリングを行いました。概ね以下のような思いが見えてきました。
軽微なものはすぐリリースしてしまいたい。
逆に大きい案件は2週間ごとぐらいでちょうどいいかも。
深夜作業が増えるのは厳しい。隔週程度で抑えておきたい。
あらゆるものをすぐリリースしたい!とはならず、「ものによる」という結論が出るのは非常にウチのカルチャーが出ていると思います(笑)。このアプローチの場合、「すぐに出せる」の判断軸をどうするかが重要になってきます。例えばチケットのストーリーポイントにしきい値を設定する、のようなことができるとスマートだと思いますが、Park Directの場合DBのマイグレーションの有無が大きなポイントとなりました。
事業フェーズももちろんですがデータモデルの特性も相まって、非常に多くのケースでマイグレーションが必要になる傾向があります。カラム追加ばかりなら先にマイグレーションをかけておき、その後モデルを変更したコードをデプロイすればシームレスにリリースできると思うのですが、Park Directでは既存レコードの更新も行うことがそれなりの頻度であります。そのためマイグレーションに時間がかかり、そのテーブルロックの時間を無視できないだろうという結論になりました。
ということで「すぐ出せる」の基準は「マイグレーションがないこと」(※2)とし、これをインプレースで出せるようにすることを目指しました。この形式のリリースをゼロダウンタイムリリースと呼び、既存の定期リリース(計画停止リリース)と別の選択肢として提供することになりました。ゼロダウンタイムリリースを実現するためには、CI/CDの実装と入念な検証、非同期ジョブが中断してしまわないような工夫、一定のリクエストがある状態でリリースした際のエラーレートを予測するための負荷試験 etc… 多くの取り組みを行ったのですが、一応この記事はテックブログではないので、泣く泣く割愛します・・・。
意外と地味なところにあったブロック要素
というわけで2023年頭にはゼロダウンタイムリリースが実施できるようになったのですが、提供開始直後は思ったように活用が進みませんでした。具体的にはゼロダウンタイムでリリースできるはずのPRのうち2/3が、従来の計画停止リリースでリリースされていました。SREチームでは把握できていない要因があると思い、いくつか仮説を立てた上で再度開発チームにヒアリングを行いました。出た意見の一部を意訳して書いてみます。
毎回リリース手順書を作ったり、バックポートPRを作ったり、タグ打ちをするのが面倒。
CIが通るのを待っている間に他のマージが入るとUpdate branchでCIがやり直しになる。
QAチームに「明日リリースしたいです」とお願いするのが申し訳ない。
品質とのバランスがよく分からない。急いでリリースしてバグが出たら意味がない。
特段急ぎではないので次の計画停止リリースで出せばいいや、というケースがある。
これらを聞いたときはなるほど!と思いました。SREチームはそこまで頻繁にアプリケーションの開発とリリースを行うわけではないので、こういった課題に実感を持って気づくことができていませんでした。
3、4はアジリティと品質に対する目線がエンジニアの中で合っていないことや、リソースの問題でもあったので、組織として少し時間をかけて向き合う必要があります。一方で1、2は技術的に解決できそうです。5は意識レベルの課題とも言えるのですが、1と2を解決してリリースにかかるコストを最小限にすれば、自ずと変わってくるかなと思います。
ということで短期的かつ技術的に解決可能な1と2に最速で取り組むことにしました。リリース手順書は必要な項目を埋めてGitHub ActionsをWorkflow dispatchで実行すれば、issueに手順書が生まれるというツールを作りました。
タグ打ちの自動化も同様にGitHub Actionsでツール化し、バックポートPRはCDの中で自動的に作成・マージされるようにしました。PRの割り込みでCIの再実行が必要になる問題は、GitHubの自動マージ(auto-merge)機能を使うとともにUpdate branchが必要に応じて自動実行されるようにして解決しました。
ツールの整備だけで本当に活用率が上がるのかな・・・と少し不安でしたが、思った以上に改善しました。以下の図は2020年1月から現在までの本番環境へのリリース数のグラフです。2023年1月にゼロダウンタイムリリースが可能になったのですが、リリース回数が爆増していることがわかります。もちろんツールのおかげだけではなく、開発チームがゼロダウンタイムリリースに合わせた開発プロセスを模索してくれたことが大きいです。CI/CDやツールに対するフィードバックも頻繁にしてくれました。
ゼロダウンタイムリリースが導入された2023年1月ではいまいち伸び悩んでいますが、上述のようなブロック要素をなくす取り組みを行った翌月以降グッと向上しています。2023年3月は追い込みで怒涛の開発があった月なので外れ値とし、2023年5月でみると d/d/d=0.07 というスコアになったので、5倍ほどの改善が行えました。
また、リリースごとの差分が小さくなることで狙い通り変更障害率も大幅に改善しました。もちろんリリースの総数(分母)が増えたという要因も大きいですが、「細かくリリースすればバグが出にくい」ということを実感しています。変更障害率については後日QAチームから記事を出す予定ですが、2023年4月にはFour KeysのElite基準と言われる15%以下に達し、現在もその水準を維持しています。
当初掲げた「フロー効率を上げてユーザーに早く価値を届けたい」「変更障害率を下げたい」という目的は定量的に見ても達成できたと言えるでしょう。
フェーズ2:マイグレーションありでもゼロダウンタイムに!
大幅なリリースサイクルの改善ができたものの、d/d/dとしてはあと一歩上を目指したいところですし、技術的にもこれができたらイケてるのに!というもう1つの壁がありました。そうです、マイグレーションを伴う場合でもゼロダウンタイムでリリースすることです。
実は当初からフワッとした構想はありました。マイグレーションを事前にリハーサル的に実行し、テーブルのロック時間を計測、それにしきい値を定めてN秒以下なら計画停止をしなくてもリリースOKと判断するというものです。かなり作り込まなければ実現できないことは予想できていたので一度は目をつぶりましたが、いつかは絶対に達成したいチームの悲願でした。
SREチームでは2023年にSLI/SLOの運用を開始できており、もしテーブルロック中にアクセスが来てエラーレートが上がってもエラーバジェットで冷静に判断できる自信がついていたというのも後押しとなり、約1年越しでついに実施することができました。
実現方法としては、想定通り「本番相当のDBにマイグレーションを流して、ロックを計測・通知するAWS Step Functions」を作り、それをGitHub Actionsから呼び出すようにしました。DBもマイグレーションを実行するアプリケーションも本番と同じスペックで起動するようにしているので、正確なテーブルロック時間を知ることができます。そして、計測されたテーブルロック時間が十分に短ければゼロダウンタイムリリースを実施、基準値に満たなければ次回の計画停止リリースに含める、という感じです。この基準値は現在ラフに決めた固定値ですが、将来的にはSLIを基に柔軟に調整していく予定です。
2023年10月にフェーズ2が実施されてからまだ数ヶ月しか経過していませんが、リリース数の増加や、計画停止リリース時の変更差分の減少といった成果が見え始めてきています。計画停止リリースは引き続き隔週で設けているのですが、そのときもマイグレーション時間の計測を行い、基準を満たしていれば日中のゼロダウンタイムリリースに変更することが可能です。先日ついにそれが実現し、予定していた計画停止をスキップすることができました。ダウンタイムが減っただけではなく、不要な深夜作業がなくなったということです!これは本当に本当に大きな変化です。
まだこの運用フローが施行されてからそこまでの期間は経っていませんが、開発者からのフィードバックに基づき継続的に改善していきたいと考えています。d/d/dが0.1を超える日も近いです!
最後に
Park DirectのSREがリリースサイクルを改善するために行ったアプローチを紹介しました。ニーリーのSREのミッションの一つである「信頼性とアジリティの両立」を元に、リリース回数の増加と効率化、および開発サイクルの加速に寄与しました。
今後の展望としては、これらの改善案の成果を継続的に評価し、開発プロセスの更なる効率化を目指していきます。今後さまざまな課題に挑戦していくのでニーリーに少しでも興味をもっていただけたら、気軽にお声がけください!
株式会社ニーリー プロダクト開発本部 プラットフォーム開発グループ
大木 建人 Kento Ogi
2020年にDMM.comへ新卒入社。社内横断組織であるSRE部のメンバーとして複数の事業に携わる。オンプレからクラウドへのシステム移行やDeveloperExperienceの向上、リリースエンジニアリング改善などなど。
2023年6月に株式会社ニーリーに入社。冬はスノーボードと仕事の交互浴を主に行う。
株式会社ニーリー プロダクト開発本部 プラットフォーム開発グループ SREチーム/QAチームリーダー
菊地 弘晃 Hiroaki Kikuchi
2017年、DMM.comに新卒入社。動画配信事業部にてVR動画、4K動画のローンチに携わるほか、動画分散エンコードシステムの開発、動画プレイヤーのUI/UX改善などを担当。2021年11月に株式会社ニーリーにジョイン。Park Direct開発部SREチーム/QAチームのリーダーとして従事。
■開発メンバーとのカジュアル面談はこちら
・三宅 克英(CTO)
圧倒的に事業に染み出す開発組織に興味がある方お話しましょう!
・菊地 弘晃
【シリーズB累計102億調達】モビリティSaaSのエンジニアを募集してます!