狠狠撸

狠狠撸Share a Scribd company logo
MOVで実践したサーバーAPI実装
の超最適化
株式会社ディー?エヌ?エー
オートモーティブ事業本部
スマートタクシー事業部システム開発部 部長
惠良和隆
自己紹介
2002年新卒でコンシューマゲーム開発会社に入社し、家庭用ゲーム機向けゲームタイトルの
開発に携わりながら、開発環境やフレームワークの構築に従事する。
2013年10月、ゲーム以外のBtoCサービスに携わるべくDeNAに中途入社する。しかしながら、
スマホ向けゲームのネイティブアプリ化待ったなしの状況において、基盤技術の構築とゲーム
開発力向上のためにゲーム事業にフルコミットすることからスタートする。
2018年7月、オートモーティブ事業本部に異動。AWS IoTを使ったプローブデータ収集システ
ムの開発?保守、地図データ整備、移動体情報配信システムの開発などに携わる。
2019年4月MOVのシステム開発担当部門の部長に就任し、マネジメントしつつ自らも開発に
携わる(現在は、APIサーバーと乗務員アプリ)。
惠良 和隆(えら かずたか)
3
みなさん、
タクシーに乗ってますか?
MOVとは?
? DeNAが提供するタクシー配車アプリ
? ITのチカラでタクシー利用を進化させるサービス
? 神奈川、東京、大阪、京都にサービス展開
? 近くのタクシーがすぐに来る
? 車輌ステータスのモニタリングすることにより、
呼べるタクシー車輌を選んで配車している
4
※MOVのシステムの詳細は、DeNA TechCon2019 の
『次世代タクシー配車サービス「MOV」を支える車載ハードウェアとソフトウェアの話」
を参照ください
5
MOVでは、呼び出すタクシーを
どのように選択しているのか?
(1) ユーザーの指定した迎車地に近い車輌を見つける
6
X m
(2) 呼べる状態の車輌のみを選別
7
例:すでにお客様が乗
車中の車輌を除く
(3) 各車輌から迎車地までの到着予想時間を算出
8
10分
3分
12分
4分
8分
7分
(3) 各車輌から迎車地までの到着予想時間を算出
9
10分
3分
12分
4分
8分
7分
最も早く到着する車輌
に配車依頼を送信する
呼べる状態の車輌とは?
? 空車であること
? タクシーの所属する交通圏に迎車地が含まれていること
? 休憩中など、MOV配車受付停止中でないこと
? 駅などのタクシー乗り場で、お客様を待つ列に並んでいな
いこと(駅待ちしていないこと)
10
呼べる状態の車輌とは?
? 空車であること
? タクシーの所属する交通圏に迎車地が含まれていること
? 休憩中など、MOV配車受付停止中でないこと
? 駅などのタクシー乗り場で、お客様を待つ列に並んでいな
いこと(駅待ちしていないこと)
11
呼べる状態の車輌とは?
? 空車であること
? タクシーの所属する交通圏に迎車地が含まれていること
? 休憩中など、MOV配車受付停止中でないこと
? 駅などのタクシー乗り場で、お客様を待つ列に並んでいな
いこと(駅待ちしていないこと)
12
駅待ちしていないことをどうやって判断するか?
タクシー乗り場を含む特定エリア内にいるか?
13
このエリア内にいる場合は、
駅待ちしていると判断する
?OpenStreetMap contributors
14
タクシーを呼べない場所があるって
ご存知ですか?
タクシーを呼べない場所
? そもそも車が進入できない場所
? 車輌侵入禁止区域
? 歩行者天国となっている道路
? お祭りや花火などのイベントによる交通規制区域
? 駅や空港、病院などの施設のタクシー乗り場
? すべてのタクシーが乗り入れることが出来ない場所もある
? 交通渋滞緩和のための自主規制
? お客様を乗せる順番は、タクシーの並び順に従うのが通常であり、
呼ばれたからと言って列に並ばずにお客様を乗せるとトラブルの
原因になりかねない
15
MOVでの対応は?
? 迎車地点として設定できないようにしている
16
アプリ内で迎車地として
指定できないエリアを表
示して、その旨を利用者
にお知らせする
タクシー配車における必須処理
? ポリゴンで定義された配車禁止エリアに、タクシー車輌や
迎車地が含まれるかどうか?
? そもそも迎車地がサービス圏内かどうか?
17
Point-In-Polygon判定
ポリゴンの中に任意の点が含まれるかどうか
本日お話する内容
? タクシー配車における必須処理
? Point-In-Polygon判定のための方法
? 超最適化の手法
? まとめ
18
Point-In-Polygon判定の手法
? アルゴリズムには様々なものがあるが、いずれかを自前実
装する or 実装されたライブラリを利用する
? ElasticsearchのGeolocation機能を利用する
? PostGIS(PostgreSQLのExtension)の機能を利用する
? 様々なサービスが提供しているWeb APIを利用する
19
MOVでのPoint-In-Polygon実装(1)
? リリース最初期は、AWSのElasticsearch Serviceを利用
? Elasticsearchには、GIS向けの機能が提供されている
? データタイプ:geo-point、geo-shape
? geo-shapeとgeo-pointが交差しているかの判定や、両者の距離
などをクエリで利用できる
? タクシー車輌位置を示すgeo-pointと交差するgeo-shape
をもつドキュメントがインデックス内に存在するかどうか
? ユーザー位置を示すgeo-pointから半径Xm以内の距離にあ
るドキュメント(geo-shape)を取得する
20
21
その後???
22
Point-In-Polygon判定に
AWS Elasticsearch Service
を利用するのは止めた
MOVでのPoint-In-Polygon実装(1)
? MOVの構成(当時)
23
AWS IoT Core Amazon Elasticsearch
Service
Service API
App Engine
MySQL
Cloud SQL
AWS Cloud
Android AndroidiOS
乗務員アプリ ユーザーアプリ
MOVでのPoint-In-Polygon実装(1)
? MOVのサービスAPIは、GCP環境(GAE/go)で動作して
おり、AWSのマネージドサービスであるElasticsearch
Serviceにアクセスする際に、必ずAWS Sigv4の認証が入
り、GCP-AWS間のレイテンシも存在する
(インスタンス規模の割にスループットが出なかった)
? Elasticsearch Serviceはマネージドサービスではあるが、
オートスケールしてくれないので、急激な負荷の上昇など
に対応できない
24
25
代替手段として採用したのは???
26
MOVでのPoint-In-Polygon実装(2)
27
? PostgreSQLの拡張機能であるPostGISを利用する
? PostgreSQL@CloudSQLはPostGISをサポート
? Point-In-Polygon以外にも多種多様なGISオペレーション
をSQLで実現できる
? 単純なQPS性能はElasticsearchよりもかなり高い
? フロントエンドとしてGAE/pythonを採用し、APIとして
利用できるように実装
MOVでのPoint-In-Polygon実装(2)
? 性能評価結果
? クエリ実行元は、Google Compute Engine上のインスタンスとする
? クエリ内容はどちらも同様の結果が得られるものとする
? 試験対象インスタンスのCPU負荷が65%程度になるようにクエリを実行する
28
Product Instance Type vCPU Memory
[GB]
QPS Response
Time [ms]
Elasticsearch c4.2xlarge
.elasticsearch
8 15 1615.85 6.189
PostGIS N/A 16 15 46303.36 0.66
1インスタンスあたりの性能
MOVでのPoint-In-Polygon実装(2)
? 性能評価結果
? クエリ実行元は、Google Compute Engine上のインスタンスとする
? クエリ内容はどちらも同様の結果が得られるものとする
? 試験対象インスタンスのCPU負荷が65%程度になるようにクエリを実行する
29
1インスタンスあたりの性能
PostGISのvCPUを考慮しても、QPSとResponse Timeが圧倒的
Product Instance Type vCPU Memory
[GB]
QPS Response
Time [ms]
Elasticsearch c4.2xlarge
.elasticsearch
8 15 1615.85 6.189
PostGIS N/A 16 15 46303.36 0.66
30
その後???
31
(???まさか???ゴクリ)
32
Point-In-Polygon判定に
PostGIS
を利用するのは止めた
MOVでのPoint-In-Polygon実装(2)
? CloudSQLのPostgreSQLは、インスタンスのメモリ容量
が多いほど最大同時接続数が増加する
? CloudSQLインスタンスのメモリが少ないと、 GAE側でイ
ンスタンスがスケールしてもCloudSQLの最大同時接続数
に到達してしまい接続できなくなる
? 結果として、大量のメモリを積んだインスタンスを複数台
使用しなければならなくなり、コスト高に???
33
MOVでのPoint-In-Polygon実装(2)
? CloudSQLのPostgreSQLは、インスタンスのメモリ容量
が多いほど最大同時接続数が増加する
? CloudSQLインスタンスのメモリが少ないと、 GAE側でイ
ンスタンスがスケールしてもCloudSQLの最大同時接続数
に到達してしまい接続できなくなる
? 結果として、大量のメモリを積んだインスタンスを複数台
使用しなければならなくなり、コスト高に???
34
PostGISのせいじゃないじゃん???
MOVでのPoint-In-Polygon実装(2)
? PostGISを使った判定にも性能的な課題はあった
? 交通圏のポリゴンデータが多頂点ポリゴンとなっており、
PostGISでもPoint-In-Polygon判定だけで数msかかって
いた
35
特別区?武三交通圏(東京都)
36出典:政府統計の総合窓口(e-Stat)(https://www.e-stat.go.jp/)
京浜交通圏(神奈川県)
37出典:政府統計の総合窓口(e-Stat)(https://www.e-stat.go.jp/)
MOVでのPoint-In-Polygon実装(2)
? PostGISを使った判定にも性能的な課題はあった
? 交通圏のポリゴンデータが多頂点ポリゴンとなっており、
PostGISでもPoint-In-Polygon判定だけで数msかかって
いた
? PostGISが内部で利用しているGDALを直接利用して判定
しても1ms以上かかることが判明した
38
MOVでのPoint-In-Polygon実装(2)
? Point-In-Polygon判定は、ユーザーアクセス数が増加する
とそれに比例して増加するため、一定以上のキャパシティ
が必要だが、インフラ費用を無駄に消費するのは避けたい
? 数ms程度なら十分高速な部類ではあるが、様々なAPIで利
用されるものであり、より高速にするとサービスAPIのレ
イテンシを削減できる
? 何より???
元ゲーム開発者としては、1msでも十分遅い!!!!
39
40
そして、超最適化へ???
MOVでのPoint-In-Polygon超最適化
? GDALを利用して判定する
? ただし、最適化のための事前処理を行う
41
事前処理①:Polygonの細分化
42
出典:政府統計の総合窓口(e-Stat)(https://www.e-stat.go.jp/)
事前処理①:Polygonの細分化
43
出典:政府統計の総合窓口(e-Stat)(https://www.e-stat.go.jp/)
事前処理①:Polygonの細分化
44
絶対に交差する
交差する
かもしれない
絶対に交差しない
出典:政府統計の総合窓口(e-Stat)(https://www.e-stat.go.jp/)
事前処理①:Polygonの細分化
45
切り出した小さなポリ
ゴンとの判定を行う
交差する
かもしれない
出典:政府統計の総合窓口(e-Stat)(https://www.e-stat.go.jp/)
事前処理①:Polygonの細分化
46
圧倒的に頂点数が削減されるので、計算量も激減する
出典:政府統計の総合窓口(e-Stat)(https://www.e-stat.go.jp/)
事前処理①:Polygonの細分化
? ポリゴンを一定サイズのメッシュで分割し、各メッシュに
以下の情報をもたせる
? 絶対に交差するかどうかのBOOL値
? 交差するかもしれないメッシュは、切り出したポリゴンデータ
? 絶対に交差しないメッシュに関してはデータを持たない
? メッシュのIDと上記の情報のマッピングデータを事前計算
? 分割に使うメッシュの大きさはポリゴンのサイズに合わせ
てアダプティブに設定
? MOVでは地域メッシュを使って分割
47
事前処理②:ポリゴンのクラスタリング
? 交通圏以外のポリゴンは小さいけど大量にある
48
出典:政府統計の総合窓口(e-Stat)(https://www.e-stat.go.jp/)
事前処理②:ポリゴンのクラスタリング
? どのポリゴンがどのメッシュに含まれるかを事前計算
49
出典:政府統計の総合窓口(e-Stat)(https://www.e-stat.go.jp/)
事前処理②:ポリゴンのクラスタリング
? どのポリゴンがどのメッシュに含まれるかを事前計算
? ポリゴンが含まれるメッシュIDの配列をポリゴン情報に
含める
50
MOVでのPoint-In-Polygon超最適化
? GDALを直接利用して判定する
? ただし、最適化のための事前処理を行う
? 事前処理を行ったデータをすべてメモリにロードすることで全
計算をオンメモリで処理する
(protocol buffers形式のバイナリファイルをGCSに配置)
? 実装言語はgolang
? GDALをgolangで使用するためには、cgoが必須
?GAE/goは諦める
? GKE上にgolang実装されたWebサーバーを構築
51
MOVでのPoint-In-Polygon超最適化
? インフラ構成
52
Kubernetes Cluster
Container Engine
Ingress
Cloud Load Balancing
Preprocessed Data
Cloud Storage
Polygon Meta Data
Cloud SQL
Service API
App Engine
MOVでのPoint-In-Polygon超最適化
? 性能比較(交通圏判定API)
53
MOVでのPoint-In-Polygon超最適化
? 性能比較(交通圏判定API)
54
MOVでのPoint-In-Polygon超最適化
? 性能比較(配車禁止エリア判定API)
55
MOVでのPoint-In-Polygon超最適化
? 性能比較(配車禁止エリア判定API)
56
まとめ
? データに適切な事前処理を施すことにより、超効率的な
Point-In-Polygon判定処理を実装した
? 全データをオンメモリとすることで、交通圏判定や配車禁
止エリア判定を超高速化できた
? 実行性能が数百倍になったことでインスタンスあたりの性
能キャパシティが大幅に拡大した
? 結果として、GAE/goほどのスピンアップ速度がなくても
負荷上昇に十分耐えられるシステムになった
57
58
ご清聴ありがとうございました。

More Related Content

MOVで実践したサーバーAPI実装の超最適化について [MOBILITY:dev]