【スマートキッチン】まぜまぜ機の検討とプロトタイプ開発

研究開発部 スマートキッチングループ アルバイトの鈴本です.
今回は,最近取り組んだまぜまぜ機の検討とプロトタイプ開発について紹介します.

1.はじめに

↓こんなもの作りました.
まぜまぜ機です.フライパンや鍋に入ったものを勝手に混ぜておいてくれます.

フライパンの上に電子部品丸出しのものが乗っているの,シュールですね....
もちろん,防水なんて考えてません,プロトタイプですから.

今回は,こんなものを作ってしまった経緯とその実装について紹介します.

2.背景 〜まぜまぜ機〜

カレーやシチュー,スープやあめ色玉ねぎを作るとき,一番めんどくさいのが焦げ付かないように混ぜ続けること.
これをなんとかできないかと思い,火にかけたフライパン・鍋をほっておいても混ぜ続けてくれるデバイス,まぜまぜ機を考えてみることにしました.

3.まぜまぜ手法のアイデア整理

まず3つほど,既存製品を例にまぜまぜ機のアイデアを検討してみました.

3-1.三脚型まぜまぜ機


出典 : https://www.amazon.com/Uutensil-Stirr-Unique-Automatic-Stirrer/dp/B008OWT95S

鍋にぽんと入れておくと,まぜまぜ機自体が振動して回転することにより,まぜまぜしてくれるデバイス.

■ メリット

  • お手軽
  • 鍋,フライパンを選ばない(どの鍋・フライパンでも使える)

■ デメリット

  • 構造上,大トルクが出しにくい
  • 実際に使ってみると,全く混ざらない(後述)

3-2.縁取り付け型まぜまぜ機


出典 : https://www.amazon.co.jp/dp/B06XBY9JKM

鍋の縁にはめて使うタイプのまぜまぜ機.

■ メリット

  • 大トルクは出せそう
  • 回転速度などの制御もしやすそう

■ デメリット

  • 機構が複雑で値段が高い
  • 鍋径,深さなどの制約があり,使える鍋・フライパンを選んでしまう

3-3.マグネティックスターラ型まぜまぜ機


出典 : http://www.taiyo-kabu.co.jp/products/detail.php?product_id=1704

鍋やフライパンを選ばず,そして大トルクを出せるまぜまぜ機候補として思いついたのがこれ.
下の台で回転磁場を発生させ,鍋の中に入れた磁石でできた回転子を回転させます.

高校時代,コウジカビなどの菌を使って生物学の研究をしてたので,個人的にはとても馴染みのあるデバイスです.

■ メリット

  • 大トルクは比較的出しやすい
  • 鍋,フライパンを選ばない(どの鍋・フライパンでも使える)

■ デメリット

  • 回転子をどうやってとりだすのかが問題
  • IHクッキングヒーターと連携させた場合,ヒーターの電場と干渉しそう?

4.開発方針

4-1.要求と現状の問題

まぜまぜ機のアイデアが出そろいました.
個人的に,まぜまぜ機に求めるものは,

  • 手軽である
  • 鍋やフライパンに依存しない(どんな鍋・フライパンでも使える)

ことです.

1からシステムを作りたいところですが,今回は開発期間が短かったため,既存のデバイスをもとにプロトタイプを制作しました.

トルクが出しにくそうではありますが,三脚型まぜまぜ機を改良してみることにします.

なぜここで “改良” と言っているかというと,3-1.で上げたまぜまぜ機が,ほぼほぼ使えなかったからです(下図参照).
まあ,1枚目(煮物)は仕方がないとして,2枚目(玉ねぎ炒め)ですら回らず....
ここに水を入れて玉ねぎを浮かせてあげると,多少は回ってくれたのですが,まぜまぜ,とはいきませんでした.

4-2.開発コンセプト

開発コンセプト図はこのような感じ.
まぜまぜ機にマイコンをのせ,今までより大きな電流を流せるようにし,出力をUP.
さらに各種センサからの情報により回転を制御し,またBluetoothで他のデバイスとも繋げられるようにします.

三脚型まぜまぜ機はその足が食材と接するため,温度などを直に測れます.
そのため,今後IHクッキングヒーターなどと連携できれば,面白いのではと思いました.

5.実装(ハードウェア)

5-1.概要

全体図は下図のようになります.
回路面積などの制約から,かなりコンパクトな設計となっています.

5-2.マイコン

マイコンは,社内に転がっていた「ESPr® Developer 32」を使いました.
On-BoardでBLEモジュールがついている優れものです.

しかし,開発を始めてから,

  • すでにディスコンになったらしく,公式HPにすらデータシートがない.
      → ノリで頑張る.
  • Arduino互換マイコンといいつつ,I2CドライバがArduino互換ではない.
      → ネットに上がっている他人のコードを参考に対処.
  • BLEとADCが干渉する.
      → ledcAttachPin という関数を用いることにより,部分的に使用可能.
  • PWM出力に対応していない.
      → タイマー割り込みで自作.

など問題が多発し,なかなか苦労しました.

5-3.電源ライン

  • モーターの出力を上げたい
  • 小型高出力の電池がいい

という要求から7.4V Li-Poバッテリを選定しました.

モーターには7.4V(満充電実測では8.4V)を印加し,マイコン入力用と5V系センサ用に三端子レギュレータ「TA48M05F(SQ)」で5Vを作りました.
3.3Vラインはマイコン内蔵のレギュレータから取り出せます.

また,今回はスペースの都合上,ロジック電源とモーターバス電源が共通です.
モーター側の高ノイズがロジックに悪影響を与えないように,適当にパスコンなどを追加しました.

5-4.9軸センサ

はじめ,ESPr® Developer 32 対応シールド「ESPr® Developer用9軸慣性計測ユニットシールド」を購入しましたが,

  • 1台目はI2C通信のアドレスすら取れない.
  • 2台目はI2Cの通信確立まですすむも,センサ値が読めない.

という不具合に悩まされ続け,結局このセンサを断念.
代わりに「BMX055使用9軸センサーモジュール」を使いました.

5-5.モーター,モータードライバ

モーターは既存のまぜまぜ機についていたモーターを流用しました.

モータードライバはおなじみの「TA7291P」です.
このモータードライバ,定格はロジック電圧入力の最小値が4.5Vで,制御信号のHIGHの最小電圧が3.5Vですが,実はスレッショルドが2.5V近辺にあるので,3.3V系でも使えます.
(回路面積に余裕があれば,本来はロジック変換をかませるべき.)

5-6.温度計

防水のことを考えると,白金抵抗で温度計を自作するのがベストなのですが,定電流回路と増幅回路を載せるスペースがなかったため,今回は適当な温度センサ「LM35DZ」で妥協しました.

5-7.スピーカ

社内に落ちていた,圧電スピーカ「SPT08」を使いました.

6.実装(ソフトウェア)

6-1.概要

ハードウェアが完成したので,次はソフトウェアです.

実装した機能は次の通り.

  • 様々な振動パターン
  • Bluetooth (BLE) を用いたコマンド・テレメトリ
  • 9軸センサを用いた,回転具合の推定
  • 最適モーター出力探索
  • タイマー機能

6-2.様々な振動パターン

まず,モーターをPWM制御することにより,モーターへの電流量を調整できるようにしました.
また,定常振動ではなく,「ブッ ブッ ブッ ブッ」のようなパルス的な振動モードなども実装してみました.

6-3.Bluetooth Low Energy (BLE) を用いたコマンド・テレメトリ

開発段階であるため,セントラルにはスマホではなくMac Bookを用いました.

定期的にまぜまぜ機よりテレメトリ(時刻,モーター出力,振動モード,各種センサ値などを含む)がBLE Notifyされます.

さらに,モーター出力や振動モード変更,後述するタイマー設定などのために,Mac Bookからまぜまぜ機へコマンドがBLE Writeによって送信できます.

6-4.9軸センサを用いた,回転具合の推定

はじめ,愚直に9軸センサの角速度を取得しましたが,まぜまぜ機自体の振動ノイズにより,全く意味のある値が取れませんでした.

そこで,角速度ではなく,磁気センサから方位 \(\theta\) を取得し,その方向角をもった単位ベクトルを足し合わせていくアルゴリズムを組みました.
数式にすると次式です.

$$ \tau = {\frac{1}{N}} \sqrt{ { \left( \sum^{N} \cos\theta \right)}^{2} + { \left( \sum^{N} \sin\theta \right) }^{2} } $$

\(\tau\) は \( 0 \leq \tau \leq 1 \) をとり,値が小さいほどサンプリング時間における方位のばらつきが均質である,つまり高速で回転していることを示します.

ただ,例によって地磁気センサのキャリブレーションは難しく,そこまで高い精度は出てない気がします.

6-5.最適モーター出力探索

8.で詳しく述べますが,実は鍋や水量によって適切なモーター出力が異なることが判明しました.
そのため,モーター出力を変化させながら 6-4.で実装した回転具合の推定値をモニタし,最もよく混ぜれるモーター出力を自動で探索する機能をつけました.

6-6.タイマー機能

「あと5分だけ混ぜておいて欲しい!」などの要求に答えるため,自動停止のためのタイマー機能を設定しました.
BLEでコマンドを打つとセットされ,指定時間が経過するとスピーカが鳴り停止します.

7.結果

結果的に,このくらい混ぜれるようになりました!
(上に乗ってる乾電池は重量調整用の重りです.)

引っかかって回転しなくなったら,自動的に振動モードを変えるなどの機能も実装されています.

8.得られた知見

無事,そこそこ混ざるようになりましたが,ここまでたどり着くまでに,まぜまぜの奥深さを知りました.

8-1.モーター出力パワーを上げればいいわけではない

最初は,「回らないんだったらモーター出力を上げればいいだけではないか.」と考えていましたが,実際はそうではありませんでした.
モーター出力を上げると,モーター回転数が上がるので,振動の振動数が上がります.
しかし,振動数が上がっても,トルクが大きくなる様子は観察されませんでした.
今回はモーターが1つしかなかったので試せませんでしたが,振動振幅を変えてみるとまた新しい発見があるかもしれません.

振動を回転に変えるのは,そう一筋縄ではいかないようです.

さらに面白いことに,鍋の径や入っている水の分量によって,最も速く回転するモーター出力が異なることがわかりました.
7.に載せたGIFアニメですが,スープよりも炒めもののほうが,最適なモーター出力が小さかったのです.

8-2.回転に影響があるパラメタとは?

鍋径や水量などの外部状態も,モーターの回転に影響を与えることがわかりました.
その他にも,まぜまぜ機自体の重さも重要だったようです.
特にモーター出力を上げた場合,まぜまぜ機自体が跳ねるだけで力が伝わっていないことも見受けられました.

今回作ったプロトタイプの実験で,

  • モーター出力(電圧,電流)
  • まぜまぜ機自体の重さ
  • 鍋の径,素材
  • 具材の量や水分量
  • 振動数や振動振幅

など,様々な要因がまぜまぜ機の回転に影響を及ぼしていることがわかってきました.
もしかしたら共振あたりが関係しているのかも...しれません.

4-1.で,鍋やフライパンに依存しない(鍋やフライパンを選ばない)気軽なまぜまぜ機がよいと言いましたが,三脚型でも環境依存性のないデバイスは難しそうです.

9.Future Works

今回のプロトタイプ開発はここまでです.
これを通じて,まぜまぜが意外と奥が深そうだということがわかってきました.

今回のやり残しとしては,

  • 振動から回転への力の変換の特性解明
    • 足の形状の検討
    • 適切な振動数,振幅などの追求
  • 外部連携
    • 温度情報などを共有し,IHクッキングヒーターなどの加熱器と連携
  • 大トルクが出せ,かつできるだけ環境に依存しない手軽なまぜまぜ機の追求
  • 作り込み
    • 防水にするとか,見た目をましにする,とか

などがあげられます.

10.おわりに

ハードウェアからソフトウェアの実装まで,限られた時間で完走するのは大変でしたが,いくつも発見があり面白くもありました.

様々な要因が絡み合って実際の現象として現れ,やってみないとわからない.
これこそが,コンピュータの中で閉じてしまう実装ではなく,実際の物理世界に干渉するデバイスの実装が好きな理由です.

クックパッドは,スマートキッチンというコンセプトの下,物理世界と積極的に関わろうとしているとても興味深い企業なのです.

デザインとは「問題解決」だけじゃない?

事業開発部のデザイナー平井です。Cookpad Do!というサービスの運営をしているチームに所属しています。

cookpad.do

Cookpad Do!は、前身サービス「Cookpad料理教室」のブランド再開発として2018年8月8日に生まれた新サービスで、食・料理をコンテンツとした体験型イベントを開催するオーナーがイベントを掲載し、参加する人がイベントの予約・決済を行えるプラットフォームサービスです。

今回はグロース期に入ったサービスの開発・運営していく中で、何を考え、どのように企画し、何を気をつけながら価値創出をしようとしているかの話をしようと思います。

料理を「楽しみ」にする

世に存在するサービスデザインは、よく「顧客の問題の解決」という言葉で説明されることがありますが、クックパッドが目指す「毎日の料理を“楽しみ”に」というビジョンを目指す上では、痛みや不満などの問題の解決という文脈だけで語れない側面があると考えています。

例えば「今日の献立を決めきれない」「失敗したくない」「人気のレシピを参考にしたい」…という、面倒な工程を少しでも“楽”にするという価値は、レシピサービスを通して多くの人に提供できており、素晴らしいことです。

しかし、“楽しみ”にというステージまでシフトするには、「今見えている問題の解決」という視点から外れて「料理の楽しさを創出する」というチャレンジを行っていかなければなりません。そんなチャレンジをCookpad Do!で実践しています。

ユーザーさんのPainは目に見えるが、Gainは見えづらい

ユーザーさんの隠れたニーズを発見するための手法として、ユーザーインタビューやプロトタイプを用いたユーザーテストは、今やどのサービス開発会社でも当たり前に行われています。

しかし実際には、「あぁやっぱりね」といった具合に自分たちが考えていたソリューションを正当化してみたり、「問題なかった!よかった!」と、インタビューの時間で新たな発見を生まない結果にしてウヤムヤにしてしまった…なんてケースがあるのではないでしょうか?

私の良くない経験としては、インタビュー中ユーザーさんから発せられた表面的な不満や課題にどうしても目が行ってしまい、いきなりソリューションの説明をして、ユーザーさんをその場で納得したような気持ちにさせてしまう…ということがありました。

なぜそういった事態に陥ってしまうのでしょうか? それは、「痛み」はユーザーさん自身が一番先に意識していて、表現しやすく、話題にしやすいからです。

また、ユーザーさんの「快楽」は、いざ口に出して説明しようと思っても説明できないことが多く、絞り出した結果も「なんとなくかっこいいから」「自己満足」のように曖昧だったり、普遍的な欲求の言葉で語られます。 (あと、「異性にモテる」など、単純に恥ずかしかったりします…)

例えば「料理教室」を商品とした場合「基本を理解できていない」「料理のレパートリーを増やしたい」といった話になりやすいです。

私たちが実現したいのは「楽しみの増幅・創出」であり、本質的にフォーカスすべきなのはPainではなく、Gainです。

楽しみを見つけるアプローチ

当たり前のようですが、私たちは日々、楽しみを何かに「見出して」います。

言い換えれば「これをやったら楽しいのでは?」と自分で動機づけを行い、いろいろ試したりして、発見しています。 (逆に緊急性が高い「問題」に対しては、解決策となる多くのサービスが向こうからやってきます)

「楽しみ」を求める能動的な行動は、各々の「価値観」によって左右されることから、「楽しみ」は「価値観」から洞察されることがわかります。

問題ではなく、人の「価値観」を探りましょう。

価値観を知るためには、その人が何を「問題」として認識しているかという事実も洞察のヒントになり得ます。

例を挙げると、「料理のレパートリーを増やしたい」という声をあげている人が「子どもが最近ご馳走様でしたの挨拶をしなくなった」ことに悲しい顔を浮かべている…という生活背景を持っている場合は、「子どもの喜ぶ顔に価値がある」といった価値観を持っているのではないか?という洞察が得られます。

「子どもの喜ぶ顔を見る」手段は「料理のレパートリーを増やす」に限った話ではないはずです。

同じ「料理のレパートリーを増やしたい」と言っている人でも、「毎日同じご飯だと栄養が偏る」という「健康な生活」に価値を置いているかもしれません。

f:id:yu-hirai:20181112161509p:plain

このように一つの課題感から、生活背景や価値観を抽象化して属性分けできるレベルまでターゲットを言語化すれば、どのようなコンテンツで訴求をして動機付けることができるのか打ち手が考えやすいですよね。

本当に価値のあるアイデアとは?

さて、ここまでどのように「楽しみ」のアイデアの種を生み出すかの話をしてきましたが、プロダクト開発現場でよくある問題が「やりたいことリスト」が溢れてしまって、ただ読むのにすら時間がかかってしまう…というケースです。

そのため、実行優先順位や期待効果を相対的に判断しにくくなり、結果よくわからないまま、数カ月後には誰も話題にしないアイデアがこんなに…なんて経験はありませんか?

そういった事態に陥ってしまう原因の一つに「具体的な要件」を主語としてしまうから、というものがあると考えています。

例えば、「◯◯という訴求文言を設置する」「メッセージ機能をつける」などです。

タスクのラベリングとしては管理しやすいため、実行フェーズに移った際には上記のような共通言語を用いたほうが良いと思いますが、アイデアの価値を測るフェーズでは問題になりやすいです。

そこでCookpad Do!チームで行っている対策として、アイデアには必ずユーザーニーズと価値仮説を、価値仮説には必ず事実と洞察をセットにして起票することにしています。

f:id:yu-hirai:20181112161538p:plain

仮説はほとんどの場合、何らかの事実や背景から洞察されます。

たとえばCookpad Do!の場合「よく知らない人の自宅に上がることに抵抗がある」「イベント参加前に、イベントの内容ページよりもイベントオーナーのプロフィール画面を閲覧している傾向が強い」といった声やデータの事実が背景にあった場合、「イベントのコンテンツ以上に、イベントオーナーの人となりを気にしているユーザーさんが多いのではないか?」といった洞察がなされます。 よって、「人にフォーカスしたコンテンツをより露出させてあげたほうが良いかもしれない」といった具合に仮説が立ち、新たな要件が生まれ、開発の糸口になります。

f:id:yu-hirai:20181112161555p:plain

このような仮説の種となる事実や背景を得るために、普段からユーザーインタビューをする際に意識したり、ユーザーさんの行動ログを見ていると良いですよね。

最後に

「問題を解決すること」は「楽しいこと」ではありません。

よく「ユーザーファースト」と言いますが、ユーザーの希望する機能を聞いたまま開発するのではなく、「なぜこのような事実になっているのか」を深く洞察し、驚きや楽しみを実現するプロダクトを創り出していくことが本当の意味でユーザーファーストな考え方であると思っています。

ユーザーさんが「楽しそう!」と喜んで選んでくれるプロダクトを作るために、常にユーザーファーストの気持ちを忘れずに、時には大胆にユーザーさんにボールを投げかけてみたりしてチャレンジしていきましょう!

Chaos Engineering に向けてレシピサービスの Steady State を追求する

こんにちは、今年ソフトウェアエンジニアとして新卒入社した @itkq です。社会人になってから 1 クールで見るアニメの本数がガクッと減っていることに気づいて最近は無力を感じています。さて、この開発者ブログで「Chaos Engineering やっていく宣言*1」が公開されたことは記憶に新しいと思います。私はインフラストラクチャー部 SRE グループに配属され、最近は Chaos Engineering に関わる取り組みも行っています。その中から今回は「レシピサービスの Steady State を追求する」取り組みについて、背景や現状も含めて紹介します。

Steady State とはなにか、なぜ必要か

一昔前の Web サービスといえば、様々な機能が 1 つのアプリケーション上に実装されたモノリシックアーキテクチャが一般的でした。その後サービスという単位で機能を切り出して別アプリケーションとして実装するサービス指向アーキテクチャを経て、オーナーシップを持って速度をもった開発を行うといった組織論の意味合いも含めたマイクロサービスアーキテクチャに変遷し今に至ることはもはや前提として良いでしょう。クックパッドにおけるアーキテクチャの変遷は、クックパッドとマイクロサービス*2 に詳しく書かれています。

アーキテクチャの変化に伴い、Web サービスにおける障害の質も変化しました。モノリシックアーキテクチャでは、データベースの接続に失敗するなどアプリケーションで致命的なエラーが発生した場合、当然ながらアプリケーションのすべての機能は利用できなくなります。一方で、マイクロサービスアーキテクチャでは、あるサービスが何らかの原因で利用できなくなった場合でも、別のサービスは正常に利用できることが起こりうります。複数のサービスが全体としてのサービスを構成しているため、あるサービスが障害に陥った場合に「ユーザから見える (全体としての) サービスは正常に動作しているのか?」という疑問に答えられる必要があります。ここで重要なことは、「あるサービスが障害になっても、サービス全体の機能が停止しない」というフォールトトレランスの考え方です。障害中のサービスを graceful に degradate するなどの手法により、ユーザは依然として目的のサービスを利用できる可能性があります。

Web サービスにおいてそのビジネスのために最も重要なことは、ユーザが快適にサービスを利用できているかどうかです。システムの裏側の内部がどうなっているかということはユーザにとって関心がありません。ゆえにシステムの内的な状態ではなく、ユーザの体験という外的な状態をもってシステムが正常であるかを判断できる必要があります。その判断基準となるものが Steady State です。Chaos Engineering においては、本番環境で意図的に障害を注入するような実験を行い、Steady State に変化が見られないという仮説を検証します。すなわちその障害がユーザの体験を損ねていないことを Steady State によって判断し、システムの回復性に自信を持つ、または未知だったシステムの弱点を修正することが目的です。

クックパッドでは、Envoy proxy (以下 Envoy) を用いたサービスメッシュを本格的に導入しており、マイクロサービスアーキテクチャにおいてクリティカルであるサービス間通信の Observability が確保されつつあります。詳細は Service Mesh and Cookpad*3 で述べられています。一方でクックパッドにおける各サービスの依存関係はますます複雑になっており、Chaos Engineering を起点としてシステム全体の Resiliency を高めていく必要がある段階であると意識し始めました。そこでクックパッドのシステムアーキテクチャ上での Chaos Engineering の仕組みや実装を検討すると同時に、Steady State の仮説検証も進めていくことにしました。Steady State を追求する取り組みは、Chaos Engineering の文脈でなくても、マイクロサービスアーキテクチャによるモダンな Web アプリケーションでは重要だと私は考えています。

レシピサービスの Steady State を考える

クックパッドでは現在、komerco*4, クックパッドマート*5 など数々の新規事業を進めていますが、事業の柱となっているのはやはりレシピサービス (cookpad.com) です。このレシピサービスは巨大な Rails アプリケーションでありますが、「お台場プロジェクト*6」の一環で、機能の切り出しが進められており、Envoy を通していくつかの別サービスと通信しているのが現状です。先述した Steady State が必要な背景と合わせて考慮し、まずレシピサービスの Steady State を定義することが先決という結論を出しました。

Steady State は Web サービスの歴史からするとまだまだ新しい概念で、Steady State を考えるにあたり、Netflix のソフトウェアエンジニアによって書かれた Chaos Engineering 本*7 を大いに参考にしました。しかし、Steady State は事業の性質によって全く異なり、また正解が 1 つに決まっているものではないことは少し考えただけで想像できました。具体的に Netflix のサービスと違う点として、課金していないユーザもレシピサービスを利用できる点が挙げられます。

どのユーザを対象とした Steady State を考えるべきなのか

Netflix のストリーミングサービスとクックパッドのレシピサービスの異なる点として、課金モデルが挙げられます。Netflix では課金しているユーザだけがストリーミングサービスを利用できますが、クックパッドでは課金していないユーザも一部機能を制限されながらレシピサービスを利用できます。

Chaos Engineering 本では、Steady State は “今顧客を失っていないか? という質問に答えられるようなビジネスに関わるメトリクスであること” とされています。クックパッドのレシピサービスは、課金ユーザだけでなく多くの課金していないユーザからも利用されている事実があります。「現時点」のビジネスメトリクスとするならば、Steady State の対象とするユーザは課金ユーザだけに絞るべきかもしれません。しかし、レシピサービスは月間約 5,500 万人が利用する*8、日本の家庭に根付いたものであるということができ、「顧客」は必ずしも課金ユーザに限定すべきではないと私は考えました。その裏側には、課金体系は月額のサブスクリプションのため、試しにプレミアムサービスを利用する障壁は低く、非課金ユーザのレシピサービスの体験が新たな課金ユーザの獲得、ひいてはレシピサービスの存続に関わる重要なものであるのではないかという思いがあります。この考えが適切かどうかに対する回答は未だ持っていません。しかし Steady State を考え始めるにあたって、対象とするユーザは「レシピサービスを利用するすべての人」という前提を置くことにしました。

この前提を元に、以下では 2 つの観点から Steady State となりうるメトリクスを選択し検証した結果を述べます。1 つ目は、レシピサービスのコア機能という観点です。しかし、レシピサービスの性質上そう単純にうまくいかないことが分かりました。この結果を踏まえ、2 つ目の観点としたのがユーザの定常な行動パターンです。こちらは結果的に 1 つ目の観点より妥当であることが分かりました。

(1) レシピサービスにおけるコア機能から考える

クックパッドのレシピサービスは、基本的にクックパッド側でレシピを追加するのではなく、レシピを投稿するユーザがいることによって成り立っており、レシピ投稿者は無くてはならない重要な存在といえます。一方で、レシピが投稿される数とレシピが閲覧される数を比較すると、圧倒的にレシピが閲覧される数のほうが多いです。ゆえに、ユーザにとってサービスが定常かどうかを考える上でユーザの体験に影響が現れやすいと考えられるレシピ閲覧にまず着目しました。レシピ閲覧以外の機能 (例えばレシピ検索やランキング) に障害が発生した場合でも、レシピ閲覧に紐付いていると考えられるものはレシピ閲覧数に影響を与えるはずと考え、記録するメトリクスはひとまずレシピ閲覧数だけで十分としました。

ある一週間における、レシピ閲覧数/sec のグラフが以下の図になります。集計はリバースプロキシ層のアクセスログをもとに行っています。先週の値と今週の値を比較できるように表示しています。最もよくレシピが閲覧されるのは夕方で、晩ごはんの献立を考えるためであることが推測できます。先週と今週の値にあまり変化がなく、定常といえる日が多い一方で、先週と比較して大きく値が変動している期間があります。この期間で障害とみなせる事象は発生していませんでした。実は、先週のこの期間は本州に台風が来ており、その影響で外食を控え家で自炊するケースが増えてこのような結果になったのだと推測しています。レシピサービスという性質上、台風だけでなく天候に大きく影響されることは事実です。アクセス数が通常と比較して増減するという意味で、システム目線では定常ではなくなっているのかもしれませんが、Steady State はユーザ側の視点で定常かどうかを表現するべきものであることを考慮すると、単純なレシピ閲覧数というメトリクスは適切ではないことが分かりました。

f:id:itkq:20181030211329p:plain
今週と先週における レシピ閲覧数/sec の比較

そこで、関連性のある複数の値の関係を相対値として表すことで、ユーザ視点とシステム視点の定常の差を縮めることを考えました。レシピサービスにおいては、天候などの外的要因に影響されて利用者数が増減したとしても、「レシピサービスを使う大半の人の行動パターン」に影響は無いのではないかという仮説を立てました。

余談

社内ブログでこの取り組みの共有をしたところ、予想より多くの人からリアクションがありました。サービス開発チームからはよりユーザに近い立場の目線のフィードバックをもらえたり、機械学習グループからは異常検知についてのコメントをもらうことができ、良い方向に進められている手応えを感じました。Steady State を含めた Chaos Engineering の取り組みは、全社的に導入するためにその必要性を広く周知していく必要があると考えており、以降も定期的な発信を積極的に行う予定です。

(2) ユーザの定常な行動パターンから考える

レシピサービスにとって最も重要な機能の 1 つといえるものが「レシピ検索」です。クックパッドを使って献立を決めたいユーザがとる行動の最も基本的な遷移は、

  1. 手元にある食材を把握する
  2. クックパッドで食材名をもとにレシピ検索
  3. いくつかレシピを見た上で料理するレシピを決める

といえるのではないでしょうか。この例では、レシピ検索とレシピ閲覧は密接に紐付いています*9。これを踏まえて、前回の仮説から次のようにアップデートしました。「ユーザは探しているレシピを閲覧できている」こと、もう一歩踏み込んで、ユーザが上で示した行動パターンを取れていることをもって Steady State とする、という仮説です。前回の失敗からの学びから、今回は相関すると考えられる 2 つのメトリクスの比を Steady State として使えないかを検討します。これは、台風が来てアクセスが増えた場合でもユーザの行動パターンは変化しないのではないかという考えに基づきます。また、このアイディアは同僚の @KOBA789 と雑談していたときに生まれたものです。雑談は大事ですね。

レシピ閲覧数と検索数の比を検討するにあたり、まず本番のデータからこの値を抽出・表示するのではなく、今回は過去のデータを使って妥当性を判断することにしました。クックパッドでは、Redshift を中心としたデータ基盤*10 が整っており、過去のレシピ閲覧数や検索数を SQL で抽出することができます。また SRE グループでは、障害が発生した後にその障害が与える影響・障害の原因・根本対処などを postmortem として記録する文化が根付いており、過去の障害とその影響も容易に検索することができるため、データ基盤の活用と合わせることでユーザの体験に影響を与えた実際の障害が発生していた区間のメトリクスを検証できます。Chaos Engineering 本において、Steady State を表せるようなメトリクスを検討する際は、そのメトリクスを取るために必要な労力のバランスを取る必要があると書かれていますが、過去のデータを元に検証する労力は、本番環境で新しくメトリクスを採取して時間経過をおいてから検証することに比べてはるかに低いことは明らかです。

以下の図は、ある 2 週間の iOS アプリケーションにおける レシピ検索 / レシピ閲覧 の数の比を示したものです。

f:id:itkq:20181030211355p:plain
レシピ閲覧数と検索数の比 (1)

オレンジ色で値が明らかに跳ねている期間で、実際にレシピサービスを使うユーザに影響があった障害が発生していました。青色で値が突出している部分は、テレビ放映によりアクセス数が増加した時間帯でした。この比の興味深いポイントは、次に示す別の 2 週間の図に表れています。1 つ前の図と同じクエリ・スケールです。このうち、実は大型の台風が来ていた期間があります。レシピ閲覧数は増加していますが、それに伴ってレシピ検索数も同じように増加しているため、値には大きな変化が表れていないと考えられます。

f:id:itkq:20181030211347p:plain
レシピ閲覧数と検索数の比 (2)

他にもレシピサービスに関係する過去の障害に対してこの比を計算してみたところ、1 枚目の図に近いスケールで値が跳ねていました。ところで、年間を通してクックパッドで最もアクセスの多い期間はバレンタイン周辺です。ある年のバレンタイン周辺の 2 週間について同様に描画したグラフが以下の図です。

f:id:itkq:20181030211404p:plain
レシピ閲覧数と検索数の比 (3)

バレンタインの周辺は、相対的に全体の値が下にシフトしていました。しかし、障害の時ほど明らかな外れ値は見られません。

以上のように、ユーザの定常な行動パターンを考え、基本的だと考えられる行動パターンに関係する 2 つのメトリクスの比を検討したところ、1 回目で試した「単純なレシピ閲覧数」よりもユーザから見たシステムの Steady State を表せていることが分かりました。そこで、現在ではレシピ閲覧数とレシピ検索数の比を遅延高々数十秒で記録・表示しています。それ以降ユーザに大きな影響を与えるような事象は (この記事を書いている時点では) 観測できていませんが、過去の事例を使った検証結果より、この値を記録していくことには意味があると考えています。

まとめ

Steady State とは何か、またそれが必要になった背景の説明と、クックパッドのレシピサービスの Steady State を追求する取り組みについて紹介しました。実サービスにおける Steady State に関する情報はあまり見当たらないため、参考になれば幸いです。Chaos Engineering 本を参考にしつつ、レシピサービスの Steady State を考える過程で、以下に挙げるいくつかの学びがありました。

  • Steady State はサービスの性質によって異なり、あらゆるサービスで唯一の正解となるメトリクスは存在しない
  • 仮設を立てながら Steady State となり得るメトリクスを地道に検証していく必要がある
    • そのためにメトリクスの収集・表示・アラーティングなどの環境が整っている必要がある
  • 過去の障害記録と当時のログデータやメトリクスは、妥当性のある Steady State の検証を効率的に行う助けとなる

クックパッドのレシピサービスは、ユーザの生活と密接に関係しており、ユーザの体験を損ねないことが重要です。Steady State の定義だけでなく、その先にある Chaos Engineering も用いるなどしてシステム全体の Resiliency のさらなる向上を目指していきたいと考えています。