クックパッドマートのプロダクト開発チームに On-Call を導入した話

クックパッドマートでサーバーサイドエンジニアを担当している奥薗 基 ( @mokuzon ) です。

クックパッドマートのプロダクト開発チーム*1では半年ほど前からサービスの運用・障害・割り込み対応の当番として on-call を導入しています。直訳すると呼べばすぐ来る、待機しているという意味で、業務時間外も含めシステムを安定して運用するために待機するエンジニア、またはその制度そのものを指しています。SRE チーム*2には on-call は一般的ですし、プロダクト開発チームでも問題があれば直ぐに駆けつけることは一般的です。しかし、プロダクト開発チームで on-call を運用している事例は意外と世に出ていないので、モチベーションと運用方法、効果についてご紹介したいと思います。

クックパッドマートとは?

このブログでクックパッドマートに関するエントリーは久しぶりなので、改めてサービスの紹介をします。既にご存知の方はこのセクションは読み飛ばしても差し支えありません。

クックパッドマートは現在クックパッドが力を入れている新規事業の一つで、生鮮を中心とした EC プラットフォームです。

https://cookpad-mart.com/

以下がサービスの主な登場人物とその関係図です。

クックパッドマートの主な登場人物とその関係図

ユーザーが商品を購入し、販売者が商品を出荷し、ドライバーが各所に設置されたマートステーションに商品を届けます。 この流通を支えるために

  • ユーザー向け
    • EC モバイルアプリケーション
  • 販売者向け
    • 商品管理・出荷管理用 web アプリケーション
  • ドライバー向け
    • 作業用モバイルアプリケーション
    • 管理者向け web アプリケーション
  • マートステーション
    • 冷蔵庫そのもの
    • 遠隔監視・操作用のネットワークとアプリケーション

などを提供しています。

サービスローンチから2年経ち、最近では大手コンビニでマートステーション設置が始まるなど、鋭意拡大中のサービスです。 人員も急増しており、事業部の規模も社内最大になりつつあります。

なぜ On-Call を導入したか

クックパッドマートが on-call を導入することにした大きな理由は

  • 遅延が許されない流通に関わる処理が深夜に集中しているが、それが失敗することが多かった
  • 平日昼間の割り込みタスクが多い

の2つです。

深夜に起きる、遅延が許されない処理の失敗

これを説明するためにはクックパッドマートの特性について話しておく必要があります。

クックパッドマートの特性

1週間ごとに見直されるルーティング

理想はすべての販売者の商品をすべてのマートステーションで受け取り可能にすることですが、事業的・物理的制約でこれはまだ実現できていません。

そのため今は1週間ごとに販売者( 正確には販売者の共同出荷先 ) とマートステーションの組み合わせ、そしてそれを回るドライバーのルーティングを組み直しています。

購入可能かどうかが在庫だけではなく配送計画にも依存していること、そしてこの配送計画のデータ構造そのものが言葉にする以上に複雑です。

この複雑さにアプリケーションも人も対応しきれず、以前は入稿ミスやバグによるデータ不整合が多発していました。

山場が深夜から始まる

クックパッドマートの山場は販売者の商品の出荷から始まります。

市場や農家など、販売者の方々の朝はとても早いです。 早い販売者では深夜 02:00 から出荷が始まり、遅くても朝 10:00 までにほとんどの販売者が出荷を完了しています。 この出荷に合わせてシステムでは深夜から早朝にかけてユーザーの注文を締め切り集計し、出荷方法の指示をまとめて販売者に送信するという処理が動いています。

また、朝 08:00 にはドライバーの集荷・配送手順をまとめたデータ群が作成されます。

実際のドライバーへの指示
実際のドライバーへの指示

On-Call 導入へ

データ不整合があると販売者への出荷指示やドライバーへの集荷・配送指示の作成が止まり、比喩ではなく流通が止まります。流通はかなりギリギリのタイムラインで組まれているため、一刻も早く修正する必要があります。

これらを支える処理は販売者やドライバーが活動する前に処理が済んでいる必要があります。しかしまだアプリケーションが成熟していなかった頃は、この重要な処理を行うバッチが深夜に高頻度で落ち、夜な夜な対応に追われるということが続きました。

深夜に需要バッチが落ち悲鳴を上げるエンジニア達深夜に需要バッチが落ち悲鳴を上げるエンジニア達
深夜に需要バッチが落ち悲鳴を上げるエンジニア達

しかも原因が複雑さにあるために対応可能なエンジニアも少なく、特定メンバーの深夜労働時間が突出して伸びたり、毎晩深夜 02:00 のバッチが通るまでは心配で寝られない、という非常に不健全な状態に陥っていました。 そのため各日ごとに張り込むメンバーを決めて、それ以外のメンバーを解放することが急務でした。 この張り込みを当番化することが on-call 導入のきっかけになりました。

なお、現在は

  • 事前チェックスクリプトが整備され、深夜になる前に問題の修正ができるようになった
  • 万が一の場合も電話で通知されるようになった

ため、深夜のトラブルはほぼなくなり張り込みは完全になくなっています。

割り込み対応

もちろん理想は割り込みが起きないよう根本的な改善をしていくことですが、限られたリソースで新規開発を進めている以上、必ず割り込みは発生します。 そして悲しい現実として、割り込み対応をし続けると本来の業務へ使える時間は減っていき、人事評価に繋がる成果からは遠のきやすくなります。これでは負担が集中しているメンバーのメンタルは濁ります。

そこで、まずは最低限 on-call によりローテーションを決めて特定メンバーに割り込み対応が偏らないようにしています。 また、on-call の時とそうでない時で割り込み対応の有無を明確に分けることはエンジニアが集中しやすい環境としても重要です。

以下の3つがクックパッドマートの割り込み対応の大半を占めています。

データ修正

新規サービスに携わったことがある方々は分かると思いますが、サービス初期は素早くユーザーに価値を提供し事業を成立させることが最優先であるため、どうしても管理画面をはじめ運営用ツールの開発は後回しになりがちです。 しかし事業の規模や複雑さが増すにつれてデータ修正の件数は増えてきます。

すると何が起こるかと言うと、データ修正の依頼がエンジニアに殺到します。 管理画面や機能がない以上、非エンジニアはエンジニアにデータを直接書き換えてもらうかデータ更新のワンタイムスクリプトを書いてもらうしかないからです。

そしてこの割り込みは、関わるメンバーの多さや親切さなど理由はいくつかありますが、一部のメンバーに集中する傾向があります。今も個人への依頼を都度 on-call に誘導する努力を続けています。

非エンジニアからの質問を調査

非エンジニアの同僚から仕様を質問されたり、問題が起きた時に原因調査を依頼されたりすることはよくあります。 もちろんすぐに答えられたり責任範囲が明確だったりするものはそのメンバーが対応すればよいでしょう。しかし、エンジニアも自分が実装した内容を全て覚えてはいませんし、そもそも実装したエンジニアが今も在籍しているとは限りません。その場合結局エンジニアも都度コードを読んだり背景をたどったりして調べる必要があるのです。

特にユーザーからの問い合わせをまとめて受けている CS*3 からの質問が圧倒的に多いです。 またクックパッドマートのようなプラットフォーム型サービスでは、提供者側 ( クックパッドマートでは販売者 ) に対しても CS が存在します。こちらは売り上げに直結するため温度感が総じて高く、優先度最高の割り込みになりがちです。

実は on-call 導入前はまだユーザー向けの CS 専任メンバーがおらず、大きな負担にはなっていませんでした。しかし、経験上専任メンバーが生まれたら爆発的に増えることはわかっていたのであらかじめ負担が分散される on-call の仕組みに乗せてしまいました。実際に予想通りになった上、ユーザー数の増加にあわせて CS 案件も増えているので、先手を打ててよかったと思っています。

アクセススパイクへの事前準備

クックパッドマートは EC サービスなので、販促イベント等の

  • いい商品が出た
  • 期間限定品が出た
  • 安く買える商品が出た

という状況ではアクセスが如実に跳ねます。具体的には販促のプッシュ通知やタイムセールが該当します。特にタイムセール開始時のアクセス数は平時の15倍以上になります。このようなアクセススパイクは平時のインフラ構成では捌ききれないので、適切に対策をしておく必要があります。

タイムセール時の rps
実際のタイムセール時の rps、 18:30 過ぎに跳ねている

クックパッドマートのシステムのインフラは殆ど AWS*4 を利用して構成されています。さらに、プロダクト開発チームが自走出来るように SRE チームが権限の譲渡や基盤の整備などいわゆるセルフサービス化を進めているため、プロダクト開発チームでも容易にアプリケーションやデータベースのスケールアウトが出来る環境になっています。

販促イベントは不定期かつ内容も多彩なので、こうしたイベントがスケジュールされた際に過去の事例等からキャパシティプランニングをしてインフラの対策をし、該当時間に監視を行うのも on-call の重要な役目となっています。

このアクセススパイクとの奮闘はまた別の機会に詳細にご紹介できればと思います。

On-Call の運用方法

クックパッドマートでは2020年12月時点で 18 名のエンジニアで Primary と Secondary を12時間ないし24時間間隔でローテーションしています。 基本的には Primary が優先的に対応し、あふれた分を Secondary が拾うスタイルです。 現状では障害や割り込みといったタスクの種類と役割の紐付けは行っていません。

運用にあたっては以下のツールを使っています。

エンジニア依頼・質問専用の Slack チャンネル

弊社は全社的に Slack*5 を使っており、クックパッドマートも大量のチャンネルを使っています。その中で、エンジニア依頼・質問専用のチャンネルを作りました。

これにより

  • 各チャンネルにいる身近なエンジニアに負担が集中することを防げる
  • 各チャンネルに散らばっていて全体像が見えない割り込み対応の規模・状況が俯瞰できる
  • 記録が一箇所に蓄積される
  • 新メンバーがコミュニケーションする場所を迷わない

などのメリットがあります。

GitHub Issue

よくフロー型とストック型のツールを適切に使い分けましょうと言いますが、上記の Slack 専用チャンネルでは正に情報をストックしづらく参照しにくいという課題があったため、GitHub*6 の issue 上にて記録を残すことを意識したやり取りにシフトしつつあります。

こうすることで、初めて経験する問題に直面した際も、過去の同様の事例を元に対処しやすくなりました。

なお、この issue は一つ専用リポジトリを作って、issue open / close のみ先述の Slack チャンネルに通知を流すようにしています。

これにより通知で流れが阻害されることなく、各案件のアサイン割り振りや状況確認等を適切に Slack で行えるようになっています。

現在は以下の template を設けています。

## 概要

## 関係する URL

## 解決したい期限(あれば)

<!---
どなたかをこの issue にアサインして、誰がこの issue に取り組んでいるのか分かりやすい状態にしてください。

* エンジニア on-call で今 Primary の人をまずはアサインしてください。
    * その後、より適切な方がいればエンジニアの方で適宜アサインを変えていきます。
* よく分からなければ何もせずそのままにしておいてください。
    * 気づいたエンジニアの方、アサインの設定をお願いします。
    * もしちょっと待っても誰もコメントしていないようであれば #kaimono-dev-inquiry でエンジニアにご連絡ください。
-->

PagerDuty

当初は2ヶ月ほど Google スプレッドシート*7 でローテーション管理をしていました。しかしこの運用は管理者とon-call 対象者に少なくない負担を強いていました。 さらに、通知などツールによる支援を受けたい需要も大きかったため、部署横断の SRE チームで既に利用実績のある PagerDuty*8 を採用しました。

  • 夜間に重要な処理が多く走るため、電話をはじめ多くの通知方法を備えている点
  • 業務委託の方にも on-call をご対応いただく際に、業務時間外に割り振られないよう柔軟にローテーションのルールを決められる点
  • 各自のスケジュールを iCal 形式で出力できる点

が特に助かっています。

On-Call を導入して

これまで述べた役割を上記の方法で機械的に分担するようにした結果、

  • on-call 時以外の平和な夜
    • とはいえ今は on-call でもほとんど平和
  • on-call 時以外の割り込みが激減し、生産性が向上
  • on-call は予めスケジューリングされているため、それを見越した見積もりが出来る
  • 割り込み対応の偏りが軽減し、メンバーのメンタルに良い影響
  • 特定メンバーに集中していたアプリケーションの知識やノウハウの拡散

など、サービスの課題から組織の課題まで幅広く健全な状態に近づいたと考えています。

反面、参画して間もないメンバーにも在籍が長いメンバーと同様の負担を強いており、on-call に精神的負担を感じてしまう課題も出始めています。 この問題には、初期は経験豊富なメンバーとペアを組んだり、可能な限りドキュメント整備したりすることで改善を図っています。また、on-call のオンボーディングに関して SRE 本*9で非常に実践的な内容が紹介されており、SRE でなくともそのエッセンスは十分に活かせると考えています。

今後も、様々な問題を仕組みで解決するエンジニアらしさを武器にサービスも組織も更に成長させてゆきたいと思います。 そんなクックパッドマートは絶賛エンジニア大募集中なので、興味のある方はぜひ以下のリンクから詳細な採用情報をご覧ください。

https://cookpad-mart-careers.studio.site/

最後までお読みいただきありがとうございました。

*1:プロダクトの開発を行うチーム。イノベーションを生み出すことに責任があり、その速度も非常に重要視されている。チームには様々な職種のメンバーがいるが、本記事ではその中のエンジニアを指してこの用語を使っている。

*2:サイト・リライアビリティ・エンジニアリング ( Site Reliability Engineering ) を行うエンジニアチーム。Google が提唱していて、プロダクトの安定性に責任を持ち、そのためにソフトウェア・エンジニアリングのエッセンスを用いている。

*3:Customer Support、いわゆるお客様窓口。

*4:https://aws.amazon.com/

*5:https://slack.com/

*6:https://github.com/

*7:https://www.google.com/sheets/about/

*8:https://pagerduty.com/

*9:Betsy Beyer, Chris Jones, Jennifer Petoff, Niall Richard Murphy 編、澤田 武男、関根 達夫、細川 一茂、矢吹 大輔 監訳、Sky株式会社 玉川 竜司 訳『SRE サイトリライアビリティエンジニアリング―Googleの信頼性を支えるエンジニアリングチーム』 O'Reilly Japan, Inc. ( 2017 )

/* */ @import "/css/theme/report/report.css"; /* */ /* */ body{ background-image: url('https://cdn-ak.f.st-hatena.com/images/fotolife/c/cookpadtech/20140527/20140527163350.png'); background-repeat: repeat-x; background-color:transparent; background-attachment: scroll; background-position: left top;} /* */ body{ border-top: 3px solid orange; color: #3c3c3c; font-family: 'Helvetica Neue', Helvetica, 'ヒラギノ角ゴ Pro W3', 'Hiragino Kaku Gothic Pro', Meiryo, Osaka, 'MS Pゴシック', sans-serif; line-height: 1.8; font-size: 16px; } a { text-decoration: underline; color: #693e1c; } a:hover { color: #80400e; text-decoration: underline; } .entry-title a{ color: rgb(176, 108, 28); cursor: auto; display: inline; font-family: 'Helvetica Neue', Helvetica, 'ヒラギノ角ゴ Pro W3', 'Hiragino Kaku Gothic Pro', Meiryo, Osaka, 'MS Pゴシック', sans-serif; font-size: 30px; font-weight: bold; height: auto; line-height: 40.5px; text-decoration: underline solid rgb(176, 108, 28); width: auto; line-height: 1.35; } .date a { color: #9b8b6c; font-size: 14px; text-decoration: none; font-weight: normal; } .urllist-title-link { font-size: 14px; } /* Recent Entries */ .recent-entries a{ color: #693e1c; } .recent-entries a:visited { color: #4d2200; text-decoration: none; } .hatena-module-recent-entries li { padding-bottom: 8px; border-bottom-width: 0px; } /*Widget*/ .hatena-module-body li { list-style-type: circle; } .hatena-module-body a{ text-decoration: none; } .hatena-module-body a:hover{ text-decoration: underline; } /* Widget name */ .hatena-module-title, .hatena-module-title a{ color: #b06c1c; margin-top: 20px; margin-bottom: 7px; } /* work frame*/ #container { width: 970px; text-align: center; margin: 0 auto; background: transparent; padding: 0 30px; } #wrapper { float: left; overflow: hidden; width: 660px; } #box2 { width: 240px; float: right; font-size: 14px; word-wrap: break-word; } /*#blog-title-inner{*/ /*margin-top: 3px;*/ /*height: 125px;*/ /*background-position: left 0px;*/ /*}*/ /*.header-image-only #blog-title-inner {*/ /*background-repeat: no-repeat;*/ /*position: relative;*/ /*height: 200px;*/ /*display: none;*/ /*}*/ /*#blog-title {*/ /*margin-top: 3px;*/ /*height: 125px;*/ /*background-image: url('https://cdn-ak.f.st-hatena.com/images/fotolife/c/cookpadtech/20140527/20140527172848.png');*/ /*background-repeat: no-repeat;*/ /*background-position: left 0px;*/ /*}*/