Architecture Example ③:自販機公衆WiFi&サイネージ・システム


本記事はMakuake Product Team Advent Calendar 2018の23日目の記事です。
今日は僕の誕生日です。誕生日の7時間をかけて書きました。笑
最後に、ちょっと組み込み機器が混ざった、リアルマイクロサービスか?とも言える様なシステム・アーキテクチャを紹介しましょう。 簡単に解説すると、自販機に液晶ディスプレイを組み込み、広告映像を配信するシステムです。 いくつかある主要な機能要件の中でこのアーキテクチャの肝となるのは以下の5つです。
  • 動画配信のための自販機組み込みプレイヤー(自販機のオープンスペース格納でき、余剰電力で稼働できるハードウェア)
  • 配信動画のスケジューリング・配信最適化アルゴリズム(これは後に動画Adとの連携により自動化されました)
  • 4G to WiFi Transform router
  • 閲覧者の判別と log management
  • アップデートと保守(点在した端末の管理)
全体としては以下の様な構造になってます。 ||| 構造図 |||
ハードプェアっぽい生理になっているが、本当はシステム・アーキテクチャとしての整理方針に揃えた方が見やすいかも。後日差し替えるかもしれません。

ポイント1:組み込みプレイヤー

まず、変えられない前提条件から見ていきましょう。 世の中の映像フォーマットのほとんどがh.264の時代でした。これは変更がきかない前提条件です。 また自販機は結構電力を食う上に、外気温に大きく左右されますから、実のところ組み込み前提の平均余剰電力って20W/hくらいしかなく、これで機能できるハードウェアとOSを積むことになります。 そして、最も辛いのは「ダメな時は落ちる」が前提になっていることです。当然プレイヤーもそれに付き合うことになります。 今だとこんな構成になるでしょう。
SBCROCK641080pを無理なく再生できるGPUを積んで10W程度で稼働できる SBCはいくつかありますが、コスパの面でこれになります
エンコーダーなし当時はハードウェアエンコーダを積みましたが、今ではSBCのGPUで十分ですね。
モニターOCB型低温高音・多湿などにも対応できる環境耐性のあるものを選択する必要があります。これは車載用ディスプレイとほぼ同じ機能要件です。ディスプレイ業界の進化は本当にすごい
電源モバイルバッテリー簡易UPSとしてモバイルバッテリーを利用します。これで瞬断どころか1~2時間の停電くらいであれば自販機は死んでもネットワークとサイネージのみが生き残りますし、基本的には自販機は災害でもない限り瞬断と入れ替え停止のみで済むので、停電時計測ノイズは無視できます。できない場合はUPS必須。
DatabaseH2Calculated Algorismをハンドリングするために、SQLiteよりは少し複雑なSQLを叩ける必要があり、PostgreSQL互換のこいつを採用しています。この案件は2011年ころのものですが、今でも組込系なら他に選択肢ないんじゃないかなぁ
Application Lang.jphpH2のせいでJREを積む羽目になる+アプリケーションはシンプルなので、ランタイム分の容量節約の意味も込めてJPHPを利用します。今だったらjrubyでもjythonでも何でもいいですね
記録媒体USBメモリ安価に調達できるものの中ではSDカードに次いでに低電力です。個体差がないのもとても扱いやすい のと、データレート的にも十分です。SDカードはスロットがSBCに採用されるケースが少ないので、必然的にUSBメモリとなります
CameraUSBカメラ動画視聴中の人を判別するためのカメラです。性別・年齢・ライフステージ・存在時間を計測するだけですが、24時間計測になるため、できるだけ暗所に強いものが求められます

ポイント2:配信動画のスケジューリング

端末は1,200台ありました。 それぞれに定常時の再生スケジュールと、来客時の配信アルゴリズムを設定してあげる必要があります。 このスケジューリング・配信最適化アルゴリズムを1台1台入れ替え流のは不可能なので、必然的に遠隔保守を構築する必要があります。 また、SBCにアルゴリズム計算をやらせると当然すぐに電力過多+自己発熱で死んでしまうので、基本的にはSBCの中ではCalculatedなデータとしてパースするだけで済む様に構成してあげる必要があります。こうすることで、アルゴリズム計算をホストサービス上で実装することができ、非力で便利なCircuitRunを使える様になります。 ※独自アルゴリズムは3年目で動画Adネットワークに接続されることで不要になりましたが、Calculatedパターンは組み込み配信では必須で、これは継続となりました。 | 配信アルゴリズム | CircuitRun(Python) | 

ポイント3:4G to WiFi Transform router

お気づきかと思いますが、アーキテクチャのポイントは一貫して低電力環境でいかにしてシステム駆動を実現するかです。 ネットワーク機器はハンドリングをミスると電力マネジメントに致命的な影響を及ぼしますので、非常に重要なポイントになります。 また、routerと映像再生は全く違う性能傾向を持つ(Computing resourceの使い方が違う)ので、まぜるな危険(いざという時にカーネルチューニングができる範囲が少なくなる)です。 端末を別で設計する際の着目点は性能傾向です。これはマイクロサービス設計にも通じる点です。
SBCROCK64WiFiモジュールを積んでいるのが1つの条件です。自販機WiFiは範囲が狭くていいので、SBCのWiFiモジュールで性能的には十分です
RouterOSMikroTikRouterOSはいくつか選択肢がありますが、保守性とSBCへの対応状況を考えると1つの最適解はMikroTik社のものになります。I/Fやコマンド系統にもクセがなく、扱いやすいです
4G今ならLPWA / eDRX4Gは通信規格よりは「その土地の電波状況」に大きく消費電力が左右されるので、幅広めの通信規格に対応しているものを選びます。
また、Router SBC と 動画配信SBCを WiFiでつないでいるのは、動画データのやり取りなどをするHigh MTU環境下では有線 to WiFiのスプリットコストが高いためです。 常時接続の安定性を求めない限りは、消費電力の点でも有利です。 2016年の論文ですが、最適な動画データやり取り時のMTUを算出する上でもかなり有用な考察になるので、参考掲載

ポイント4:閲覧者の判別と log management

LogデータはOpenCVベースに作られたアプリケーションで採取します。
  1. プロファイルデータを現在配信すべき映像の選定に用いる
  2. 閲覧興味度・滞在時間・滞在時刻などをフィードバック
が主な目的です。 ここでのポイントは「リトライ」と「不明」の取り扱いです。
リトライの話
SBCなどがアーキテクチャに入ってくるモデルの場合、SBCの環境がシビアであればあるほどSBC側の責務は疎通までにするのがいいと思います。 SBCから音沙汰があった場合、反応・応答が完了するまでリトライするのはホストサービスの役割にすべきです。 SBCの方が圧倒的に「予期しないエラー」に見舞われる可能性が高いからです。 これはQueueの概念をアーキテクチャに持ち込むときの責務関係の実装方針を決める際にもほとんど同じモデルでの検討になります。
不明の話
「不明」はデータなのか、データではない(エラー)なのか は、OpenCVなどが出てきて「測定がファジーな状態になってしまう」ことが当たり前な時代になって真剣に考えられる様になってきた側面ですが、一昔前は「不明とはできるだけあってはならない」というバイアスがありましたので、この当時のシステムでも、「できるだけ近い傾向に寄せる」という方針で「不明なし」という設計方針で実装されました。 しかし、最近はAIなどもシステムアーキテクチャのキャラクターとして出てくる様になって「どのくらい不明なのか」という指標もセット「不明なものは不明」という、もう少し論理的な「不明」に対する取り扱いが求められる様になってきました。 もう少ししたら、多くのプログラミング言語には、「null = 価値が存在しない」の様に「unknown = 不明」という概念が1つの型として追加されてくるかもしれません。 「不明」はベロシティを持つ概念として今絶賛研究されていて、データストラクチャとして新しい概念なのです。

ポイント5:アップデートと保守(点在した端末の管理)

ネットワークと動画配信を別な機器(別サービス)にした理由の大きな一つが、このアップデートと保守の考え方です。 1,200台のアップデートを4G回線を使って行うとなると、当時の回線試算で1台あたり3.5時間程度はかかる見込みでした。1,200台同時にアップデートも、1台1台アップデートも、ローリングデプロイも、どれも現実的な解になりえませんでした。 その多くはデイリーで行われるログのフィードバックと動画データの入れ替えによるネットワーク通信の待機時間で、Releaseそのものは数秒で済んでしまうという環境でしたので、当時はLocal BitTorrentを用いた波状型のデータトランスファ方式を用いました。 それでも数台はエラーが起きますので、そうした際には当時はリトライしか方法がありませんでしたが、今であれば検証性の検証にTemporary (Forked) blockchainなどの応用も有効かもしれません。

まとめ

ちょっとWEBから外れた話題が多い組み込み系の話なのですが、両方やっている身からすると、マイクロサービスの設計と組み込み系機器の構成の設計は「制約条件の確認」→「性能傾向のアレンジ」という初期の方針策定プロセスが非常によく似ていますので、紹介しました。

この記事はシリーズです。

一緒に「世界をつなぎ、アタラシイを創る」エンジニアを募集しております。ご興味持っていただけた方は、「各種エンジニア募集! クラウドファンディングMakuake」からご連絡ください。