Upgrade to Pro — share decks privately, control downloads, hide ads and more …

車両動態管理システムCariotの リアルタイム性を実現する技術 / cariot-mobil...

Cariot
February 06, 2025
95

車両動態管理システムCariotの リアルタイム性を実現する技術 / cariot-mobility-night2

2025年2月6日に開催されたMobility Night #2 - 車両管理 -の発表資料です。

https://mobility-night.connpass.com/event/340431/

Cariot

February 06, 2025
Tweet

Transcript

  1. 2 自己紹介 2 • 遠藤 匠 • 株式会社キャリオット プロダクト開発 部長

    – Mission「クルマがつながる、シゴトが変わる」 – ソラコムの子会社 • 役割 – エンジニアリングマネージャー – プロダクトマネージャー • 経歴 – 2007/4〜 SIer – 2015/2〜 フレクト – 2024/10〜 キャリオット(事業承継による転籍)
  2. 5 Cariotの機能一覧 クルマに関わる業務の課題を解消して、収益向上や費用削減につながる各種機能を提供します。 コラボレーション (リアルタイム) 管理業務DX データ活用・ 業務効率化 安全運転管理 車両予約

    車両・ドライバー台帳 運転業務報告 配送計画 車両日常点検 アルコールチェック DriveView (リアルタイム情報活用) DriveCast (リアルタイム情報共有)
  3. 11 AWS Cloud アーキテクチャ Kinesis Analytics SQL Application Amazon DynamoDB

    Amazon Athena Amazon Kinesis Data Streams Amazon Elastic Container Service (Amazon ECS) AWS Lambda AWS Lambda Amazon EventBridge Amazon Simple Storage Service (Amazon S3) Amazon Data Firehose
  4. 12 AWS Cloud アーキテクチャ Kinesis Analytics SQL Application Amazon DynamoDB

    Amazon Athena Amazon Kinesis Data Streams Amazon Elastic Container Service (Amazon ECS) AWS Lambda AWS Lambda Amazon EventBridge Amazon Simple Storage Service (Amazon S3) Amazon Data Firehose リアルタイム ニアリアルタイム(ウインドウ) バッチ集計
  5. 14 データが詰まらないようにするためのスケーリング戦略 GetRecords Amazon Kinesis Data Streams AWS Lambda サービス成長に応じてデータの量も行う仕事も増える

      急加速・急ブレーキ検出、方向判定、ジオフェンス、到着時間予測、仮想オドメータ算出、Webhook送信など 様々な外部リソースへのアクセス   AWS内(DynamoDB, RDS, Redis), AWS外(Google Maps Platform, Salesforce Platform) IoT, デバイス故の特性も加味   データの遅延、到着順の逆転、フラッディング、異常値 考慮点
  6. 15 Kinesis × Lambdaのスケーリングの選択肢 Lambdaのメモリを増やす シャード数を増やす ParallelizationFactor (シャードあたりの同時 バッチ)を増やす 拡張ファンアウト

    メモリ割り当てに応じてvCPU コア数が1〜6まで増加 シャードの数を増やして Lambda側もスケールアウト 1シャードあたりの同時バッチ を1〜10の範囲で処理可 シャード内のデータを複数のコ ンシューマに配信 ❌ 実際のボトルネックは Lambdaの計算処理ではなく、 その他のリソースであることが 多く効果が薄い ❌ コスト効率が悪い ❌ 1回データが詰まってしまう と、詰まったデータは吐き切ら ないと効果効果がない (ユースケースに応じて使用す る) (ユースケースに応じて使用す る)
  7. 16 AWS Cloud Cariotでのアプローチ:Lambda側の仕事はECS側にオフロード Amazon Kinesis Data Streams AWS Lambda

    Amazon ECS Amazon DynamoDB Lambdaは基本的に 横流し(交通整理) リアルタイムデータ処理は全て バックエンド側が行う ✅ コアロジックはECS側のJavaアプリケーションに集約されていた ✅ 問題発生時の切り分けや性能解析がしやすい ✅ 交通整理しやすい(全て終わったか終わってないか、異常データの吐き捨て)
  8. 18 AWS Cloud リアルタイム情報の取得 Amazon ElastiCache Client Amazon API Gateway

    Amazon ECS Amazon DynamoDB リアルタイム情報の取得は、REST APIを公開し、ポーリング形式で定期的に更新。 Redis OSS互換の Amazon ElastiCacheを 使用してキャッシュ制御
  9. 19 Redis ソート済みセット型(Sorted Set) スコアを含んだセット型。 キー=デバイスの識別情報、スコア=イベント時刻とする。 スコア=イベント時刻 (UNIX timestamp) Value

    1738823136 { “lat”: 35.674364, “lon”: 139.770223, “speed”: 34.3 } 1738823139 { “lat”: 35.674198, “lon”: 139.770598, “speed”: 35.1 } 1738823142 { “lat”: 35.673874, “lon”: 139.770966, “speed”: 33.4 } 1738823145 { “lat”: 35.673604, “lon”: 139.770753, “speed”: 32.1 } 1738823148 { “lat”: 35.673308, “lon”: 139.770622, “speed”: 30.9 } ✅ ランクやスコアの範囲指定による削除操作が可能。最新N件のデータの保存・取得ができる。 ランク 0 1 2 3 4 key = device_log:123
  10. 20 Redis JSON型 JSONデータを格納・取得・操作するための型  ✅ 部分的な更新が可能   ・JSONの一部フィールドのみを更新できる。    全体を上書きせずに変更できる。   ・ネットワーク負荷が少ない。  ✅

    検索・クエリが協力   ・JSONPathを使ったデータの検索ができる。  ✅ データ構造の柔軟性  ✅ 複数のキーを1回の通信リクエストで取得可(MGET) https://zenn.dev/cariot_dev/articles/52d2aef79c92b7
  11. 21 Cariotでのアプローチ:SortedSet型とJSON型の併用 位置情報更新 サービス ジオフェンス サービス 停車時間判定 サービス MGET snapshot:123

    書き込み 読み込み ElastiCache for Redis { “location”: { “lat”: 35.674364, “lon”: 139.770223, “speed”: 34.3 }, “geo_state”: { “current”: { … } “next”: { … } }, “stop_state”: { … } } 1回のコマンドで 複数の車両の 必要な情報だけを まとめて取得 SortedSet型で最新1件のタイムスタンプの一致を確認後、JSON型の値を更新
  12. 22 最適化にあわせてAPIも再設計 Location API Geo API Event API Snapshot API

    テーブルとリソースが1:1に対応 BFF (左のパターンを混ぜただけ) BFF (適正化) Full Snapshot API フロントエンド側の実装をシンプルに保つためBFF(Backend For Frontend)の要素を取り入れてAPIも整理
  13. 25 Google Maps JavaScript APIを利用 車両アイコンといえばマーカーだが、標準APIでA地点からB地点になめらかに動かす 手段はない。 たとえば下記のコードではA地点からB地点にマーカーが瞬間移動する形になる。 const marker

    = new google.maps.Marker({ position: { lat: 35.6521014, lng: 139.7581003 } , // A地点 map, title: "Hello World! }); marker.setPosition({ lat: 35.66295616, lng: 139.75703496 }); // B地点へ移動 ※ 現在非推奨になっている旧Markerでの表記
  14. 26 Cariotでのアプローチ:OverlayView google.maps.OverlayView 独自のオーバーレイを地図上に表示するためのクラス。 継承して独自の車両マーカークラスを実装。 自由なHTML要素を表示できる (要素自体はReact, Vueの世界に分離) @keyframes iconPulseAnimation

    { 0% { opacity: 0; transform: scale(0.1); } 50% { opacity: 0.5; } 75% { opacity: 0; transform: scale(2); } 100% { opacity: 0; transform: scale(2); } } .pulse { &::before, &::after { content: ''; display: block; position: absolute; border: 3px solid rgba(0, 0, 255, 0.7); left: -20px; right: -20px; top: -20px; bottom: -20px; border-radius: 50%; pointer-events: none; opacity: 0; animation: iconPulseAnimation 2s linear infinite; } &:after { animation-delay: 0.5s; } } エフェクト表現 = CSSアニメーション const projection = this.getProjection() if (!projection) return const position = this._position const { x: px, y: py } = projection.fromLatLngToDivPixel(position) const x = px - this._element.clientWidth / 2 const y = py - this._element.clientHeight / 2 this._element.style.cssText = ` position: absolute; left: 0; top: 0; height: 0; transform: translateX(${x}px) translateY(${y}px); transition: transform 3000ms linear; z-index: ${this._zIndex || 'auto'}; ` } なめらかな移動の表現 = CSS transition
  15. 27 その他の方法との比較 方法 特徴 メリット デメリット setTimeout / setInterval 一定間隔ごとに座標を更新

    実装がシンプル ややカクつく requestAnimationFrame ブラウザのリフレッシュレートに最適化 して描画 スムーズなアニメー ションが可能 実装がやや手間 OverlayView + CSS カスタムHTML要素を地図上に配置 カスタマイズ性が高い 実装がやや手間 マーカーのデザインをリッチにする余地を残したい意味でもOverlayViewを利用。 検討中 = Advanced Marker(高度なマーカー), Web Animation API
  16. 29 まとめ ・サーバ負荷を抑える ・効率よく取得(データ量・速度) ・リアルタイム感を出すための演出 収集 処理 保存 参照 表示

    リアルタイム動態管理の要件 ・スケールしやすい構成にする ・欠損、異常値、順序保証がない ・データの処理遅延(詰まり)を  起きにくくする
  17. 30 まとめ ・スケールしやすい構成にする ・欠損、異常値、順序保証がない ・データの処理遅延(詰まり)を  起きにくくする ・サーバ負荷を抑える ・効率よく取得(データ量・速度) ・リアルタイム感を出すための演出 収集

    処理 保存 参照 表示 リアルタイム動態管理の要件 Kinesis + Lambdaを基本に ECSでオフロード Redis JSON型による部分更新な キャッシュ機構 Google Maps OverlayViewとCSS Transitionで演出 アプローチ