狠狠撸

狠狠撸Share a Scribd company logo
Confidential & Proprietary
Open Match Deep Dive
Based on v0.2.0 (as of Nov 2018)
● OSS のマッチメーキングサービス
https://github.com/GoogleCloudPlatform/open-match
● 特徴
○ Kubernetes
○ 柔軟性
○ 拡張性
○ スケール
● 実績
○ Globally scaling the Halloween multiplayer Doodle with Open
Match on Google Cloud
■ 65時間で1億プレイヤー
■ 62ヵ国
■ Max CCU 50万
Open Match とは?
Open Match Deep Dive
マイクロサービスアーキテクチャ
Orchestrator
Frontend
API
Backend
API
MMF
Redis
Director
Open Match
Evaluator
MMLogic API
カスタム
コード
● Frontend API
クライアントからのマッチングリクエストを受けるエンドポイント
● Backend API
専用サーバからマッチングのプロファイルとリクエストを受けるエンドポイント
● Orchestrator - MMF や Evaluator を実行するサービス
● MMLogic API - MMF と Redis の通信プロトコル
● MMF - マッチングのロジック
● Evaluator - マッチングの競合管理のロジック
マイクロサービスの一覧
● MMF - Matchmaking function = マッチングのロジック
● Roster - あるゲームセッションに参加するプレイヤーリスト(チーム)
● Profile - マッチングのパラメータを持つ JSON blob
● Match Object - マッチングの結果を持つ JSON blob
○ Backend API はこちらのオブジェクトを受け、マッチングの結果を更新してから返す
● MMFOrc - Matchmaking Function Orchestrator = カスタムのマッチングロジックと Evaluator を
トリガーするプロセス
● Evaluator - プレイヤーがオーバーラップするマッチング結果から最適のマッチングを判断する
プロセス
● State Storage - Open Match が利用するストレージ(デフォルトで Redis)
● Assignment - プレイヤーを専用サーバに割り当てること
○ Assignment が行われたら、サーバのコネクション情報( IP/Port)がクライアントに渡されます
● DGS - Dedicated Game Server = マルチプレイ用の専用サーバ
● Director - DGS を管理するプロセス( Open Match には含まれていません、 Agones のようなサービスをお
すすめします)
Glossary
Frontend API
Frontend API
Orchestrator
Backend
API
Director
Evaluator
MMF
MMLogic API
Redis
Frontend
API
● Frontend API
クライアントが接続するエンドポイント
● Frontend API が提供する gRPC サービス
service API {
rpc CreateRequest(Group) returns (Result) {}
rpc DeleteRequest(Group) returns (Result) {}
rpc GetAssignment(PlayerId) returns (ConnectionInfo) {}
rpc DeleteAssignment(PlayerId) returns (Result) {}
}
Frontend API
Frontend
API
Redis
● Request (リクエスト)はクライアントが OM に「相手を探して」というリクエスト
● Assignment (割り当て)はゲームサーバが OM に「プレイヤーをちょうだい」というリクエスト
Request & Assignment
Frontend
API
Backend
API
Redis
Director
CreateRequest() CreateAssignments()
● Group と PlayerId の属性
message Group {
string id = 1; // By convention, string of space-delimited playerIDs
string properties = 2; // By convention, a JSON-encoded string
}
message PlayerId {
string id = 1; // By convention, a UUID
}
● Group の Properties 属性はマッチングの決断に必要となる属性(ラ
ンク、キャラクラス、武器、レイテンシ、など)
Group & PlayerId
● Frontend API の役割
○ クライアント、またはロビーサーバからマッチングの
リクエストを受信して、 Redis にプレイヤーの情報を書き込む
○ マッチングが成功してら
■ MMF が Redis に結果を書き込む
■ クライアントに接続先の情報を返す
Frontend API
Frontend
API
Redis
Frontend
API
Lobby
CreateRequest(Group)
GetAssignment(PlayerId)
Frontend
API
CreateRequest(Group)
GetAssignment(PlayerId)
Frontend API の使用パターン
シングルプレイヤーのマッチングリクエスト グループからのマッチングリクエスト
Group には1人だけの
プレイヤー情報を渡す
Group には4人のプレイヤー
情報を渡す
Frontend
API
CreateRequest(Group)
GetAssignment(PlayerId)
プレイヤーの情報は Redis に保存
PlayerId Rank Latency Connstring
Samir 23 30 NULL
add
watch
Connstring (サーバの接続先) が更新されるまで、
Frontend API はプレイヤーのキーを Watch する
CreateRequest() は Redis にリクエストしたプレイヤーの情報を保存する( PlayerId が Key)。マッチン
グのロジックはこの Key (情報)を参照して、マッチングを決める
Backend API
Backend API
Orchestrator
Frontend
API
Director
Evaluator
MMF
MMLogic API
Redis
Backend
API
● Backend API
専用サーバが接続するエンドポイント
● Backend API が提供する gRPC サービス
service Backend {
// MMF を1回実行する。プロファイルに基づいた結果(Match Object)を変えす。
rpc CreateMatch(messages.MatchObject) returns (messages.MatchObject) {}
rpc ListMatches(messages.MatchObject) returns (stream messages.MatchObject) {}
rpc DeleteMatch(messages.MatchObject) returns (messages.Result) {}
rpc CreateAssignments(messages.Assignments) returns (messages.Result) {}
rpc DeleteAssignments(messages.Roster) returns (messages.Result) {}
}
Backend API
Backend
API
Redis
● Backend API の役割
○ MMF をトリガーするAPIです
○ マッチングプロファイルを受信して、 Redis に保存
○ 専用サーバがゲームセッションの AssignmentをリクエストするAPI
Backend API
Backend
API
Redis
CreateMatch(Match
Object)
CreateAssignments()
Step 1 - プロファイルを渡す
● CreateMatch(MatchObject) をコール
○ Input: マッチングのプロファイルを含め
た MatchObject
○ Output: マッチングされたプレイヤー情
報を含めた MatchObject
● ListMatches(MatchObject) は CreateMatch
と同じAPIだが常時接続系のものです
Step 2 - Roster が決まったら
● CreateAssignments() でマッチングされたプ
レイヤーにゲームサーバの接続先を伝える
(具体的には Redis にマッチングされたプレイ
ヤーレコードを更新、クライアントは Frontend
API 経由でそのレコードを watch)
Backend API
Backend
API
Director
Key=Profile name
Value=Profile
● Profile はマッチングのパラメータとロースター(チー
ム)の構成を持つ JSON blob
○ JSON ファイルに定義して、 Backend APIをコー
ルするアプリケーションに読ませるのが一般の
使い方
● Profile は Match Object の Properties に保存
Profile
● Match Object はマッチメークに関する情報を持つオブジェクト
● Backend API をコールする時に渡すパラメータでもある
● Protobuf による MatchObject の定義
type MatchObject struct {
Id string `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"`
Properties string `protobuf:"bytes,2,opt,name=properties" json:"properties,omitempty"`
Error string `protobuf:"bytes,3,opt,name=error" json:"error,omitempty"`
Rosters []*Roster `protobuf:"bytes,4,rep,name=rosters" json:"rosters,omitempty"`
Pools []*PlayerPool `protobuf:"bytes,5,rep,name=pools" json:"pools,omitempty"`
}
● Id はユニークの ID
● Properties はプロファイルを持つ属性
Match Object
Orchestrator + MMF + Evaluator
Orchestrator
Frontend
API
Backend
API
Director
Evaluator
MMF
MMLogic API
Orchestrator
Redis
● Orchestrator
○ Redis にあるマッチングリクエスト Queue を watch して、
○ マッチングリクエストが追加されたら、 MMF を実行するサービス。
○ MMF の実行が終了し、マッチングの提案 Queue にマッチング提案が追
加されていたら、Orchestrator は Evaluator をトリガーする。
○ Evaluator はマッチングの競合管理をするプロセス
● Orchestrator の役割
○ MMF と Evaluator をトリガーする役割
Orchestrator
Orchestrator
Redis
MMLogic API + MMF (Matchmaking Function)
Orchestrator
Frontend
API
Backend
API
Director
Evaluator
MMF
Redis
MMLogic API
● MMLogic API
○ MMF が Redis からプロファイルを取得したり、マッチングの結
果を Redis に書き込むためのエンドポイント
● MMLogic API が提供する gRPC サービス
service MmLogic {
rpc GetProfile(messages.MatchObject) returns (messages.MatchObject) {}
rpc CreateProposal(messages.MatchObject) returns (messages.Result) {}
rpc GetPlayerPool(messages.PlayerPool) returns (stream messages.PlayerPool) {}
rpc GetAllIgnoredPlayers(messages.IlInput) returns (messages.Roster) {}
rpc ListIgnoredPlayers(messages.IlInput) returns (messages.Roster) {}
}
● MMLogic API は、MMF を書きやすくする役割です
○ Python MMF の例
MMLogic API
MMF
Redis
MMLogic API
● MMF
マッチングのロジック
Kubernetes の ジョブでもある
注意点:MMF のジョブは実行後に自動的に削除されないので、 削
除する仕組みを実装する必要があります
● MMF の役割
○ プロファイルを Redis から読み込んで、マッチングのロジック
を実行し、プレイヤーをマッチングする
○ Evaluator が利用されていない場合、マッチングが成功した
ら、結果を Redis に結果を書き込む
○ Evaluator が利用されている場合、 Proposal(提案) の Key
に結果を書き込む
MMF (Matchmaking Function)
MMF
Redis
MMLogic API
Evaluator
Orchestrator
Frontend
API
Backend
API
Director
MMF
MMLogic API
Evaluator
Redis
● Evaluator
マッチング結果の競合管理するプロセス
Kubernetes の ジョブでもある
注意点:Evaluator のジョブは実行後に自動的に削除されないの
で、削除する仕組みを実装する必要があります
● Evaluator の役割
○ Redis から提案のマッチング結果を読み込み、競合管理のロ
ジックを実行する
○ 最適なマッチングが見つかったら、 Redis にある提案結果のレ
コードの Key を最終結果の Key に変更する
● Evaluator はオプショナルなコンポーネントです
Evaluator
Evaluator
Redis
マッチングの流れ
マッチングの Flow chart (1/3)
Frontend
API
Key=PlayerA
Connstring=NULL
Player A
CreateRequest(PlayerA)
GetAssignment(PlayerA)
Key=PlayerB
Connstring=NULL
Player B
CreateRequest(PlayerB)
GetAssignment(PlayerB)
Key=PlayerC
Connstring=NULL
Player C
CreateRequest(PlayerC)
GetAssignment(PlayerC)
Key=PlayerD
Connstring=NULL
Player D
CreateRequest(PlayerD)
GetAssignment(PlayerD)
write
watch
write
watch
write
watch
write
watch
マッチングの Flow chart (2/3)
Orchestrator
queues.profile.name
queues.proposals.name
queue
Key=Request_ID
Value=Matching_result
Key=Proposal_ID
Value=Matching_proposal
Key=Profile name
Value=Profile
Evaluator
watch for
result
watch
Director
trigger MMF read
profile
triggerEvaluator
MMF
receive
result
write
profile
write
results
read
read
proposal
Backend
API
queue
approve
results
Director
CreateMatch()
マッチングの Flow chart (3/3)
Director
CreateAssignments()
Key=PlayerA
Connstring=ip:port
Key=PlayerB
Connstring=ip:port
Key=PlayerC
Connstring=ip:port
Key=PlayerD
Connstring=ip:port
Update
connection
string
Backend
API
Player A
Player D
Player C
Player B
Frontend
API
watch
&
send
Confidential & Proprietary
Thank you

More Related Content

Open Match Deep Dive

  • 1. Confidential & Proprietary Open Match Deep Dive Based on v0.2.0 (as of Nov 2018)
  • 2. ● OSS のマッチメーキングサービス https://github.com/GoogleCloudPlatform/open-match ● 特徴 ○ Kubernetes ○ 柔軟性 ○ 拡張性 ○ スケール ● 実績 ○ Globally scaling the Halloween multiplayer Doodle with Open Match on Google Cloud ■ 65時間で1億プレイヤー ■ 62ヵ国 ■ Max CCU 50万 Open Match とは?
  • 5. ● Frontend API クライアントからのマッチングリクエストを受けるエンドポイント ● Backend API 専用サーバからマッチングのプロファイルとリクエストを受けるエンドポイント ● Orchestrator - MMF や Evaluator を実行するサービス ● MMLogic API - MMF と Redis の通信プロトコル ● MMF - マッチングのロジック ● Evaluator - マッチングの競合管理のロジック マイクロサービスの一覧
  • 6. ● MMF - Matchmaking function = マッチングのロジック ● Roster - あるゲームセッションに参加するプレイヤーリスト(チーム) ● Profile - マッチングのパラメータを持つ JSON blob ● Match Object - マッチングの結果を持つ JSON blob ○ Backend API はこちらのオブジェクトを受け、マッチングの結果を更新してから返す ● MMFOrc - Matchmaking Function Orchestrator = カスタムのマッチングロジックと Evaluator を トリガーするプロセス ● Evaluator - プレイヤーがオーバーラップするマッチング結果から最適のマッチングを判断する プロセス ● State Storage - Open Match が利用するストレージ(デフォルトで Redis) ● Assignment - プレイヤーを専用サーバに割り当てること ○ Assignment が行われたら、サーバのコネクション情報( IP/Port)がクライアントに渡されます ● DGS - Dedicated Game Server = マルチプレイ用の専用サーバ ● Director - DGS を管理するプロセス( Open Match には含まれていません、 Agones のようなサービスをお すすめします) Glossary
  • 9. ● Frontend API クライアントが接続するエンドポイント ● Frontend API が提供する gRPC サービス service API { rpc CreateRequest(Group) returns (Result) {} rpc DeleteRequest(Group) returns (Result) {} rpc GetAssignment(PlayerId) returns (ConnectionInfo) {} rpc DeleteAssignment(PlayerId) returns (Result) {} } Frontend API Frontend API Redis
  • 10. ● Request (リクエスト)はクライアントが OM に「相手を探して」というリクエスト ● Assignment (割り当て)はゲームサーバが OM に「プレイヤーをちょうだい」というリクエスト Request & Assignment Frontend API Backend API Redis Director CreateRequest() CreateAssignments()
  • 11. ● Group と PlayerId の属性 message Group { string id = 1; // By convention, string of space-delimited playerIDs string properties = 2; // By convention, a JSON-encoded string } message PlayerId { string id = 1; // By convention, a UUID } ● Group の Properties 属性はマッチングの決断に必要となる属性(ラ ンク、キャラクラス、武器、レイテンシ、など) Group & PlayerId
  • 12. ● Frontend API の役割 ○ クライアント、またはロビーサーバからマッチングの リクエストを受信して、 Redis にプレイヤーの情報を書き込む ○ マッチングが成功してら ■ MMF が Redis に結果を書き込む ■ クライアントに接続先の情報を返す Frontend API Frontend API Redis
  • 13. Frontend API Lobby CreateRequest(Group) GetAssignment(PlayerId) Frontend API CreateRequest(Group) GetAssignment(PlayerId) Frontend API の使用パターン シングルプレイヤーのマッチングリクエスト グループからのマッチングリクエスト Group には1人だけの プレイヤー情報を渡す Group には4人のプレイヤー 情報を渡す
  • 14. Frontend API CreateRequest(Group) GetAssignment(PlayerId) プレイヤーの情報は Redis に保存 PlayerId Rank Latency Connstring Samir 23 30 NULL add watch Connstring (サーバの接続先) が更新されるまで、 Frontend API はプレイヤーのキーを Watch する CreateRequest() は Redis にリクエストしたプレイヤーの情報を保存する( PlayerId が Key)。マッチン グのロジックはこの Key (情報)を参照して、マッチングを決める
  • 17. ● Backend API 専用サーバが接続するエンドポイント ● Backend API が提供する gRPC サービス service Backend { // MMF を1回実行する。プロファイルに基づいた結果(Match Object)を変えす。 rpc CreateMatch(messages.MatchObject) returns (messages.MatchObject) {} rpc ListMatches(messages.MatchObject) returns (stream messages.MatchObject) {} rpc DeleteMatch(messages.MatchObject) returns (messages.Result) {} rpc CreateAssignments(messages.Assignments) returns (messages.Result) {} rpc DeleteAssignments(messages.Roster) returns (messages.Result) {} } Backend API Backend API Redis
  • 18. ● Backend API の役割 ○ MMF をトリガーするAPIです ○ マッチングプロファイルを受信して、 Redis に保存 ○ 専用サーバがゲームセッションの AssignmentをリクエストするAPI Backend API Backend API Redis
  • 19. CreateMatch(Match Object) CreateAssignments() Step 1 - プロファイルを渡す ● CreateMatch(MatchObject) をコール ○ Input: マッチングのプロファイルを含め た MatchObject ○ Output: マッチングされたプレイヤー情 報を含めた MatchObject ● ListMatches(MatchObject) は CreateMatch と同じAPIだが常時接続系のものです Step 2 - Roster が決まったら ● CreateAssignments() でマッチングされたプ レイヤーにゲームサーバの接続先を伝える (具体的には Redis にマッチングされたプレイ ヤーレコードを更新、クライアントは Frontend API 経由でそのレコードを watch) Backend API Backend API Director Key=Profile name Value=Profile
  • 20. ● Profile はマッチングのパラメータとロースター(チー ム)の構成を持つ JSON blob ○ JSON ファイルに定義して、 Backend APIをコー ルするアプリケーションに読ませるのが一般の 使い方 ● Profile は Match Object の Properties に保存 Profile
  • 21. ● Match Object はマッチメークに関する情報を持つオブジェクト ● Backend API をコールする時に渡すパラメータでもある ● Protobuf による MatchObject の定義 type MatchObject struct { Id string `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"` Properties string `protobuf:"bytes,2,opt,name=properties" json:"properties,omitempty"` Error string `protobuf:"bytes,3,opt,name=error" json:"error,omitempty"` Rosters []*Roster `protobuf:"bytes,4,rep,name=rosters" json:"rosters,omitempty"` Pools []*PlayerPool `protobuf:"bytes,5,rep,name=pools" json:"pools,omitempty"` } ● Id はユニークの ID ● Properties はプロファイルを持つ属性 Match Object
  • 22. Orchestrator + MMF + Evaluator
  • 24. ● Orchestrator ○ Redis にあるマッチングリクエスト Queue を watch して、 ○ マッチングリクエストが追加されたら、 MMF を実行するサービス。 ○ MMF の実行が終了し、マッチングの提案 Queue にマッチング提案が追 加されていたら、Orchestrator は Evaluator をトリガーする。 ○ Evaluator はマッチングの競合管理をするプロセス ● Orchestrator の役割 ○ MMF と Evaluator をトリガーする役割 Orchestrator Orchestrator Redis
  • 25. MMLogic API + MMF (Matchmaking Function) Orchestrator Frontend API Backend API Director Evaluator MMF Redis MMLogic API
  • 26. ● MMLogic API ○ MMF が Redis からプロファイルを取得したり、マッチングの結 果を Redis に書き込むためのエンドポイント ● MMLogic API が提供する gRPC サービス service MmLogic { rpc GetProfile(messages.MatchObject) returns (messages.MatchObject) {} rpc CreateProposal(messages.MatchObject) returns (messages.Result) {} rpc GetPlayerPool(messages.PlayerPool) returns (stream messages.PlayerPool) {} rpc GetAllIgnoredPlayers(messages.IlInput) returns (messages.Roster) {} rpc ListIgnoredPlayers(messages.IlInput) returns (messages.Roster) {} } ● MMLogic API は、MMF を書きやすくする役割です ○ Python MMF の例 MMLogic API MMF Redis MMLogic API
  • 27. ● MMF マッチングのロジック Kubernetes の ジョブでもある 注意点:MMF のジョブは実行後に自動的に削除されないので、 削 除する仕組みを実装する必要があります ● MMF の役割 ○ プロファイルを Redis から読み込んで、マッチングのロジック を実行し、プレイヤーをマッチングする ○ Evaluator が利用されていない場合、マッチングが成功した ら、結果を Redis に結果を書き込む ○ Evaluator が利用されている場合、 Proposal(提案) の Key に結果を書き込む MMF (Matchmaking Function) MMF Redis MMLogic API
  • 29. ● Evaluator マッチング結果の競合管理するプロセス Kubernetes の ジョブでもある 注意点:Evaluator のジョブは実行後に自動的に削除されないの で、削除する仕組みを実装する必要があります ● Evaluator の役割 ○ Redis から提案のマッチング結果を読み込み、競合管理のロ ジックを実行する ○ 最適なマッチングが見つかったら、 Redis にある提案結果のレ コードの Key を最終結果の Key に変更する ● Evaluator はオプショナルなコンポーネントです Evaluator Evaluator Redis
  • 31. マッチングの Flow chart (1/3) Frontend API Key=PlayerA Connstring=NULL Player A CreateRequest(PlayerA) GetAssignment(PlayerA) Key=PlayerB Connstring=NULL Player B CreateRequest(PlayerB) GetAssignment(PlayerB) Key=PlayerC Connstring=NULL Player C CreateRequest(PlayerC) GetAssignment(PlayerC) Key=PlayerD Connstring=NULL Player D CreateRequest(PlayerD) GetAssignment(PlayerD) write watch write watch write watch write watch
  • 32. マッチングの Flow chart (2/3) Orchestrator queues.profile.name queues.proposals.name queue Key=Request_ID Value=Matching_result Key=Proposal_ID Value=Matching_proposal Key=Profile name Value=Profile Evaluator watch for result watch Director trigger MMF read profile triggerEvaluator MMF receive result write profile write results read read proposal Backend API queue approve results Director CreateMatch()
  • 33. マッチングの Flow chart (3/3) Director CreateAssignments() Key=PlayerA Connstring=ip:port Key=PlayerB Connstring=ip:port Key=PlayerC Connstring=ip:port Key=PlayerD Connstring=ip:port Update connection string Backend API Player A Player D Player C Player B Frontend API watch & send