無人コンビニ600を支える技術

岡前直由 氏(以下、岡前):それでは「IoTと監視」と題しまして600株式会社の岡前が発表させていただきます。よろしくお願いいたします。

最初に、弊社のサービスについて簡単にご紹介させていただきます。

簡単に言うと、無人決済型の冷蔵ショーケースです。ちょうど会場にあるのでデモンストレーションをさせていただきますが、これが筐体です。

クレジットカードリーダーが付いていて、クレジットカードを通すと、中の電子錠がアンロックされて扉が開きます。

扉が開いて、商品にRFIDタグが貼り付けられており、RFIDアンテナを使って取り出した商品を検出し、自動で決済する仕組みです。ここにアンドロイドタブレットが貼り付けられていて、これがユーザとのインタラクションや各デバイスのコントローラー的な役割を担っています。

ビジネスとしては「半径50メートル商圏」と言っているんですが、スーパーマーケットが半径5,000メートル、コンビニが半径500メートルと言われているらしいんですね。弊社ではそれをより狭めた半径50メートル商圏という新しい市場の開拓を狙っているサービスです。20年でうまくいけば10兆円の市場規模にならないかなというところで事業を展開しております。

簡単に自己紹介ですが、私は大学でこういった分野を専攻していまして、一番長かったのが前職のリブセンスという会社です。

SREや機械学習エンジニアをやっていました。その当時はIoTにはまったく触れていなくて、ちょうど1年前の去年の9月に600に所属しまして、そこで始めてIoTに触れました。現在ProductQualityチームのマネージャーをやっておりまして、ここでは主に品質の管理とか品質の向上を仕事としてやっております。

好きな言語はTypeScriptとKotlin、型が好きです。

「冷蔵庫の監視」を行うための技術スタック

今日の内容なんですが「『冷蔵庫を監視する』ってどういうこと?」ということで、たぶんみなさん大抵はサーバの監視をイメージされる方が多いと思いますが、サーバの監視と冷蔵庫の監視は何が違うのか、もっと言うとサーバの監視で生きたスキルがIoTの場面でどうやって生かせるのかという話を伝えられればと思います。

具体的にPrometheusを使って筐体の監視をしているのですが、筐体監視事例を紹介できればと思います。

ご存知の方も多いと思いますが、Prometheusはオープンソースのシステムモニタリングツールです。特長として、アーキテクチャがとてもシンプルです。Go言語のワンバイナリで動いていて、簡単に起動ができます。複数のコンポーネント群から成り立っていまして、コンポーネントと周辺ツールですね。サードパーティ製も含めてかなりやっています。それらを組み合わせて監視を行って、あとは可視化、グラフ化やダッシュボード化、アラーティングの管理も行うことができます。

Prometheusのアーキテクチャでこれはだいぶ概略図ですが、かいつまんでご説明します。真ん中のPrometheus Serverがメインのサービスです。ここにメトリクスを蓄えています。右側のGrafanaというのが、データのグラフ化やダッシュボード化のツールです。PromQLと書いてあるんですが、Prometheusのサーバに対してPromQLというクエリ言語を使ってメトリクスの取得や集計結果の取得を行っています。もう1つ重要なのが左のTargetsが監視対象のサーバやエッジデバイスなんですが、基本的にPrometheusは監視対象に対してPullでメトリクスを取得しています。これに関してはまた後ほど説明します。

PrometheusをIoTで使うためのポイント

このPrometheusをIoTで使う上で、ポイントが2つあります。1つ目がサブコンポーネントのPushgatewayを利用することです。2つ目がメトリクスの設計です。先ほどチラッといいましたが、PrometheusはPull型ということで、監視対象自身がメトリクス取得用のHTTPエンドポイントを持っています。

それはexporterと呼ばれており、Prometheusがそこを定期的にスクレイピングをするというかたちです。スクレイピングすることにより、Pullでメトリクスを取得しています。

ただ、IoTのエッジデバイスの場合はインターネットにつながっているのですが、Pullが地味に難しいというか、おそらくがんばればできるんですが、ちょっと難しいです。具体的に言うと例えばグローバルIPアドレスの管理やサービスディスカバリーってどうやるの? とかそういうところですね。その煩わしさを置いておいて、Push型で監視をしたいと思ったときにPushgatewayというコンポーネントを使います。

これを使うと、ターゲットはPushgatewayに対してメトリクスをPushすればいい。Prometheusは変わらずPushgatewayに対してPullするというかたちです。真ん中に中継的に入っていまして、弊社ではこれを使っています。

続いてメトリクス設計ですが、これは最も重要な部分です。サーバ監視の一般的な用途であれば、例えばリクエスト数やエラー数など、そういった基本的なメトリクスを組み込んだexporterがあらかじめ用意されています。ただ、IoTやエッジデバイスの場合は多様性があって決して一般的ではありません。ということで、当然exporterはありませんので、自前でメトリクスを設計する必要があります。

そこをどうやってやっていくかという話ですが、どうやってもいいんですが「筐体が正常稼働をしている条件は何だろう」という条件をブレイクダウンしていく。例えば1つはAndroidアプリが起動していること、あとはタブレットのバッテリーが充分であること、クレジットカードが読み込める、クレジットカードのカードリーダーが故障していないといったことですね。

そういったことをブレイクダウンして、これらをPrometheusで表現できるメトリクスの値として設計しています。

使用するメトリクス

具体的なメトリクスの例に移る前に、Prometheusが用意しているメトリクスの型が大きく2つあります。本当はもうすこし種類があるんですが主にCounterとGaugeの2つを使っています。

Counterは単調増加する値ですね。サーバであれば合計リクエスト数やエラー数。Gaugeはそれと対照的に任意に値が上下するものです。メモリの利用量や温度ですね。この2つの型を使って、ほしい情報を監視していくことを考えます。

例えばAndroidタブレットのバッテリー残量の監視です。実際、ケーブルの接続不良でタブレットの電源が落ちてしまったりしたことが、初期の頃はたくさんありました。それで監視に加えたのですが、バッテリー残量を表すときはシンプルにGaugeのメトリクスを使います。

バッテリー残量を取得する具体的なクエリがどうなるかと言うと、こんな感じです。

device_battery_percentというメトリクスの名前にsatellite_idというIDが600社内の用語で筐体を識別するIDを指定してあります。たしか600cd1というのが、この筐体のIDなのですが、この端末のバッテリーがリアルタイムに監視できています。

Prometheusは時系列データベースを持っているのでこんな感じで、これは横軸が時間です。8月24日から2週間分ぐらいのデータを可視化しています。この可視化のツールが先ほど説明したGrafanaですね。それでグラフ化したものです。

続いてAndroidアプリの稼働率です。Androidアプリが落ちていないことを知りたいというときに何をするかなんですが、ここにはちょっとだけ工夫が必要です。

GaugeとCounterを使うので、Counterでアプリの累積起動時間を記録しています。具体的にはアプリが起動している限り5分おきにCounterをインクリメントするというメトリクスを管理しています。

どうやってそれを取得するかなんですが、基本的にPromQLではメトリクス名で取得できるんですが、aplication_alive_totalという部分ですね。右側の「2w」とありますよね。あれが2週間分のレンジで取得するという意味になっています。Prometheusの関数を使ってincreaseという関数を使うと、2週間のレンジで何回インクリメントされたかを取ることができます。

これは割り算をしていて、分母の場合は2週間フルでインクリメントされた場合は何回かというところですね。これを使うと稼働率を取ることができます。当然これは100パーセントに近いほうが良くて、デモ用の筐体で場所を移動したり検証用に使ったりいろいろあって8割ぐらいに落ちているというのがわかります。

最後にクレジットカード読み取り成功率の例ですね。知りたいのはクレジットカードリーダーが故障していないことです。今回もCounterを使います。具体的に取る値は、カードスワイプの累積成功数と失敗数ですね。これを使ってまたincrease関数で何回成功したか、何回失敗したかを記録しています。

複雑なように見えてすごく単純です。1行目は分子なんです。これは割り算をしていて、1行目が成功回数ですね。3日間のクレジットカードスワイプ成功数です。それから下が成功+失敗の回数を取っています。これでトータルのクレジットカードスワイプ数÷成功回数を取ることで、どれぐらいの割合でカードスワイプ数が成功したかを取ることができています。

例えばここでしきい値を設けて、何割でもいいんですが、例えば4割のしきい値を設けてここを割ったタイミングでアラートを鳴らして故障対応を出すといったことをやっています。

ここまで紹介したように、Prometheusでシンプルなメトリクスから、PromQLの関数を使って一般的なこれらの指標を表現することができます。他にも、例えば故障回数や平均故障間隔、平均修理時間といったものを簡単に表現できます。

これが弊社で使っているダッシュボードの例です。小さくて申し訳ないんですが、ここで平均故障間隔が27日と出ています。これは単独のデモ用の状態なのでもうちょっと違うと良いですが、ネットワーク速度を取ったり、ショーケース内にある商品数を記録したりできます。

IoT監視とサーバー監視は似ている?

ここまでご説明して、Webサーバ監視とIoT監視で似ているところがけっこう多いかなと思った方も多いと思います。例えばモニタリングツールを導入します。グラフ化やダッシュボード化をしてアラートを定義して、アラートが入るとオンコール対応という感じです。ここまでは似ているんですが、大きく違うのが運用の部分です。

ここでだいぶ王道なんですが、最近ではWebサーバは基本的に1台落ちてもサービスの影響はないことが多いです。なぜそうできているかと言うと、サービスが冗長構成されているからです。対照的に、IoTエッジデバイスは、例えばこの筐体のAndroidや電子錠は、故障すると即サービス影響がでます。なぜかと言うと冗長化が難しいからです。タブレットを2つ貼る手もないこともないですが、やりませんよね。

ということで、アラートを減らそうと思ったら部品の品質を高めて故障率自体を下げていくしかない、というところがWeb系と感覚が違う場所かなと思っています。故障率を下げていくために、こういった監視データを基に故障原因や頻度を分析していきます。それで解決すべき課題を優先度付けをして日々改善しています。

監視のおもしろいところなんですが、やった改善をすごく可視化できるんですね。なのでProductQualityチームの「この改善でこれだけ上がりました」という成果が可視化できています。

具体的に直近1ヶ月のトータルの平均故障間隔のグラフなんですが、1.5倍強伸びているという状態を続けてはいますが、まだ品質が高くなくて、これから展開していく上でもっと品質を上げていかなければいけない状況です。

終わりですね。

「600で一緒にIoTしませんか?」ということで、半径50メートル商圏の先行プレイヤーとして、あと最近Twitterでバズった話なんですが……。

(会場笑)

週休3日制をやってます。水曜日と土日が休みなんですけど、今日は休みでした(注:当日は水曜日)。一応今日は出社扱いで、業務扱いなので代休がもらえます。という状況なのですが、エンジニアリングの課題が山積みで、Webサービス系のスキルを持った方でも取り組んでいただきたい課題がたくさんあるので、ぜひ興味があればお声掛けください。

ありがとうございました。

(会場拍手)