Slide 1

Slide 1 text

車両位置情報データの圧縮による Cloud Pub/Subのコスト削減 2023.05.31 牧瀬 芳太郎 GO株式会社

Slide 2

Slide 2 text

© GO Inc. 2 自己紹介 GO株式会社 ソフトウェアエンジニア / 牧瀬 芳太郎 タクシーアプリ『GO』データ基盤開発・運用などを担当 Go言語でバックエンド開発もしています 最近はゼルダの伝説ToKをプレイしていますが、寄り道しすぎてクリ アに3ヶ月くらいかかりそう

Slide 3

Slide 3 text

© GO Inc. 3 車両位置情報の収集 ▪ アクティブ車両台数: 数万台 ▪ 車両から送られる情報: GPS位置、方角、速度、メーター情報、etc. = 動態(車両動態) ▪ 約9億レコード/日 何に使われる? ▪ 配車 ▪ 機械学習を使ったサービス ▪ 到着時間予測 (DeNA TechCon 2022 にて紹介) ▪ お客様探索ナビ (MoT TechTalk #10 にて紹介) ▪ AI予約 ▪ etc. ▪ サービス改善のための分析

Slide 4

Slide 4 text

© GO Inc. 4 『GO』アプリ 動態パイプラインの全体図 MoT TechTalk #7 技術書典頒布 のタクシーアプリ『GO』アーキ テクチャ図録を一挙解説 にて紹介 今回の話

Slide 5

Slide 5 text

© GO Inc. 5 『GO』アプリ データ基盤のコスト ▪ BigQuery についで Pub/Sub, Dataflow のコストが大きい ▪ その中でも車両動態が多くを占める ▪ データ流量に応じてかかるコストがあり、流量が多いためコス トが高くなっている ▪ 提携タクシーの増加に伴い、動態の流量は徐々に増加

Slide 6

Slide 6 text

© GO Inc. ▪ Pub/Sub 経由で BigQuery に投入 ▪ Pub/Sub のペイロードは動態 1レコードの JSON 6 従来構成 (MoT TechTalk #12 にて紹介) ここの流量を減らしたい!

Slide 7

Slide 7 text

© GO Inc. ▪ Pub/Sub のペイロードを Protobuf + Zstandard に変更 7 新構成

Slide 8

Slide 8 text

© GO Inc. 8 新構成 Protobuf スキーマ ※実際より簡略化 // 車両動態 message AnalyticalThing { uint32 car_id = 1; // 車両ID double raw_lat = 2; // GPS緯度 double raw_lon = 3; // GPS経度 double speed = 4; // 速度 Status.MeterStatus meter_status = 5; // メーター状態 google.protobuf.Timestamp sampled_at = 6; // 取得日時 ..... }

Slide 9

Slide 9 text

© GO Inc. 9 技術選定理由 データ形式 Protocol Buffersを採用 ▪ Google社製のシリアライゼーションフォーマット ▪ 動態配信システムから来るデータが元々 Protobuf 形式なので、そのまま流 せば処理コストが少ない ▪ 後段で圧縮するとしても、JSON より Protobuf を圧縮する方が最終的なサ イズが小さくなる 他に検討に上がった選択肢 ▪ Parquet, Avro 等 → 動態配信システムから来るデータが元々 Protobuf 形式なので、わざわざ 変換するのは余計な処理が増えるだけなので不採用 仮に動態配信システムから来るデータが Parquet や Avro 形式であったなら 採用していた

Slide 10

Slide 10 text

© GO Inc. 10 技術選定理由 圧縮アルゴリズム Zstandardを採用 ▪ Meta(Facebook)社製の可逆圧縮アルゴリズム ▪ リアルタイム処理性能を重視しており、GZIP と同程度の圧縮率で、よ り高速 ▪ JSON を Protobuf にするだけだとデータサイズ削減量が少ないため利用 ▪ 複数レコードをまとめて圧縮する。1台の車両からの動態データをある程度 まとめて送ってもらっているため、似たようなレコードが多く効率的に圧縮 できる 他に検討に上がった選択肢 ▪ GZIP → やや古いアルゴリズム。最近は同程度の圧縮率で、より高速なものがある

Slide 11

Slide 11 text

© GO Inc. 11 Protobuf のレコードをまとめるときの工夫 課題 ▪ Protobuf のレコードは可変長のバイナリ データ ▪ レコード自体には区切りとなる情報がない 工夫 ▪ レコードの長さを先頭に付与して連結する ▪ トータルのレコード件数がいくつであって も、単にバッファ or ファイルの後ろに追 記していけば良いため、ストリーミング処 理と相性が良い

Slide 12

Slide 12 text

© GO Inc. 12 実装 Pub/Sub に投げる側: Go言語で書かれた内製ワーカー ▪ 今までは Protobuf を JSON に変換していたが、Protobuf のまま複数レ コードまとめて圧縮し publish するように変更 ▪ 圧縮処理は並列動作するように実装 Pub/Sub から読み出す側: Dataflow ▪ Mercari Dataflow Template を参考に独自にフレームワークの実装を行い、 YAML 記述により様々な Beam API を呼び出せるようにし、柔軟にパイプラ イン定義ができるようにしている ▪ 今回追加: Protobufデコード処理、ZStandard展開処理 ▪ フレームワークさえ修正すれば、各ジョブ定義自体はYAMLの書き換えだけ で済む。YAMLの修正例は次ページにて説明

Slide 13

Slide 13 text

© GO Inc. 13 実装: ジョブ定義YAMLの修正例 --- laplace-vehicle-analytics-log-collector.yaml 2023-05-11 17:08:20 +++ laplace-vehicle-analytics-v2-log-collector.yaml 2023-03-13 12:13:31 @@ -2,10 +2,13 @@ - name: pubsub module: pubsub parameters: - subscription: "projects/my-project/subscriptions/laplace-vehicle-analytics-subscription" - format: string + subscription: "projects/my-project/subscriptions/laplace-vehicle-analytics-v2-subscription" + format: pbpack + compression: ZSTD transforms: - - name: parsejson - module: parsejson + - name: parseprotobuf + module: parseprotobuf input: pubsub parameters: + descriptorFile: ../proto/laplace/common.pb + messageName: laplace.AnalyticalThing .....

Slide 14

Slide 14 text

© GO Inc. 14 成果 ▪ 高いデータ圧縮率 ▪ 約1/15 (JSON→Protobuf で 1/3、ZStandard でさらに 1/5) ▪ コスト削減 ▪ 動態の Pub/Sub, Dataflow 流量コスト: 93% 削減 ▪ データ基盤全体のコスト: 10% 削減 ▪ エンコード/デコードの処理が高速化 ▪ 2,000 レコードの処理が 43ms → 18ms (エンコード側) ▪ CPU負荷が低い = マシンスペックが低く抑えられる

Slide 15

Slide 15 text

© GO Inc. 15 まとめと所感 まとめ ▪ 車両動態を Pub/Sub に流すフォーマットを JSON → Protobuf+Zstandard に変更することにより データ量を 1/15 にし、大幅なコスト削減を達成 所感 ▪ Pub/Sub は流量が多いとコストがかさみやすい ▪ (最近は BigQuery Subscriptions もあるが) あえて Dataflow を利用 しデータ圧縮を行うことで流量を削減し、コストを抑えられるケース がある

Slide 16

Slide 16 text

文章・画像等の内容の無断転載及び複製等の行為はご遠慮ください。 © GO Inc.