19
Copyright © DeNA Co.,Ltd. All Rights Reserved. スケーラブル GCP アーキテクチャ February 10, 2017 - DeNA TechCon 2017 Yuki Furuyama Alliance System Gr. Open Pla@orm Dept. DeNA Co., Ltd.

スケーラブル GCP アーキテクチャ

Embed Size (px)

Citation preview

Page 1: スケーラブル GCP アーキテクチャ

Copyright©DeNACo.,Ltd.AllRightsReserved.

スケーラブルGCPアーキテクチャ

February10,2017-DeNATechCon2017

[email protected].,Ltd.

Page 2: スケーラブル GCP アーキテクチャ

Copyright©DeNACo.,Ltd.AllRightsReserved.

⾃⼰紹介

!  古⼭祐樹!  オープンプラットフォーム事業本部システム開発部アライアンスシステムグループ

!  DeNA!  2014/04新卒⼊社!  2014/09~Mobageの新プラットフォーム(NextBrowserPlatform)・ゲーム招待サービスの開発

!  2015/04~グローバルマーケット向けの⼤規模ゲーム⽤プラットフォーム開発

!  @addsict!  github.com/addsict

2

Page 3: スケーラブル GCP アーキテクチャ

Copyright©DeNACo.,Ltd.AllRightsReserved.

このトークで話すこと

!  GoogleAppEngineをベースにスケーラビリティの⾼いアーキテクチャを構成する時のポイントとなる点を説明します

!  特にAppEngineとCloudPub/Subの組み合わせ⼿法を重点的に話します

3

Page 4: スケーラブル GCP アーキテクチャ

Copyright©DeNACo.,Ltd.AllRightsReserved.

GoogleAppEngine

4

Page 5: スケーラブル GCP アーキテクチャ

Copyright©DeNACo.,Ltd.AllRightsReserved.

GoogleAppEngine(GAE)とは

!  Googleが2008年(約10年前!)から提供しているWebアプリケーション実⾏プラットフォーム

!  特徴!  アプリケーションより下側は⼀切気にしなくていい

!  広義のServerlessArchitecture!  トラフィックに応じてインスタンス数が⾃動で柔軟にスケール!  GCPの様々なサービスとの連携が容易

!  アプリログはStackdriverLoggingに!  BigQueryやCloudPub/Subなどとの認証もGAEのデフォルトの

アクセストークンを⽤いることで容易に呼び出せる

5

Page 6: スケーラブル GCP アーキテクチャ

Copyright©DeNACo.,Ltd.AllRightsReserved.

GAEでスケールさせるためには何に気をつけるべきか?

1.  Datastore!  特性を知りそれに⾒合った設計を⾏なう!  特にインデックス

2.  ⾮同期タスク!  時間のかかる処理は⾮同期に実⾏する!  外部システムに引きづられないように

6

Page 7: スケーラブル GCP アーキテクチャ

Copyright©DeNACo.,Ltd.AllRightsReserved.

GAEでスケールさせるためには何に気をつけるべきか?

1.  Datastore!  特性を知りそれに⾒合った設計を⾏なう!  特にインデックス

2.  ⾮同期タスク!  時間のかかる処理は⾮同期に実⾏する!  外部システムに引きづられないように

7

今⽇はこちらを紹介

Page 8: スケーラブル GCP アーキテクチャ

Copyright©DeNACo.,Ltd.AllRightsReserved.

⾮同期タスク-リクエストの処理を分離してスケールさせる

!  リクエストを!  同期的に処理する部分!  ⾮同期的に処理する部分!  に分離して実⾏する

!  得られる様々なメリット!  より素早くレスポンスを返すことができる!  1つの処理を複数の処理単位に分離して独⽴して実⾏できる!  処理の特性に⾒合ったインスタンスを⽤意できる

!  もちろんGAE以外の組み合わせも可能!  外部システムの調⼦に⼤きく引きづられないようになる

!  緩衝材としての⾮同期化

8

システム全体をスケールさせるためには⾮同期化が不可⽋

Page 9: スケーラブル GCP アーキテクチャ

Copyright©DeNACo.,Ltd.AllRightsReserved.

TaskQueue-GAEの⾮同期タスク実⾏環境

!  ⾮同期タスクを実⾏するためのジョブキューシステム!  特徴

!  2種類のQueue!  PullQueue:Worker⾃⾝がジョブを取りに⾏く!  PushQueue:Workerに対してジョブがプッシュされてくる

!  PushQueue+GAEだと、⽤意したエンドポイントにHTTPリクエストが送られてくる!  PushQueueへのジョブ登録はHTTPリクエストを送るかのように⾏なう

!  メソッドを指定して〜(POST)!  URLを指定して〜(/user/events)!  ヘッダを指定して〜(X-My-Header:1,2,3)!  ボディを指定して〜({“eventId”:“123”})

!  DatastoreのトランザクションにTaskQueueのキューイングを含めることが可能

9

Page 10: スケーラブル GCP アーキテクチャ

Copyright©DeNACo.,Ltd.AllRightsReserved.

TaskQueue-⾮同期HTTPクライアントとして使う

!  HTTPでジョブが送られてくる!  →⾮同期HTTPクライアントとして使える(+リトライ付き!)

!  使い所!  AppEngineのサービス間通信をTaskQueueを介して⾏なう

!  「GAETaskQueueをマイクロサービスのサービス間通信として使う-addsict'sblog」

10

App Engine

Task Queue

App Engine

Enqueue PushPOST/eventsHTTP/1.1

Page 11: スケーラブル GCP アーキテクチャ

Copyright©DeNACo.,Ltd.AllRightsReserved.

TaskQueue-スケーラビリティの問題

!  AppEngineとの相性は抜群だが課題も・・・!  TaskQueue(Push型)の実⾏レート

!  1つのキューあたり500tasks/secまでに制限される!  それ以上の速度でタスクが登録されると処理が追いつかなくなる

!  解決策!  シャーディング!  秒間1万タスクが想定される場合:20個のキューを⽤意

!  my_queue_01,my_queue_02,...,my_queue_20!  管理が煩雑&マニュアル対応が⼊りスケールしない

11

Page 12: スケーラブル GCP アーキテクチャ

Copyright©DeNACo.,Ltd.AllRightsReserved.

CloudPub/Sub

12

Page 13: スケーラブル GCP アーキテクチャ

Copyright©DeNACo.,Ltd.AllRightsReserved.

CloudPub/Subとは

!  GCPの提供する汎⽤Pub/Subミドルウェア!  特徴

!  ⾼いスケーラビリティ!  秒間100万(!)メッセージの処理(https://cloud.google.com/pubsub/での公表値)

!  Push型とPull型!  TaskQueueと同じ概念

!  GoogleAppEngineとの⾼い親和性!  特別なエンドポイント:POST/_ah/push-handlersで認証された

メッセージを受け取れる

13

Page 14: スケーラブル GCP アーキテクチャ

Copyright©DeNACo.,Ltd.AllRightsReserved.

TaskQueueからCloudPub/Subへ

!  両者は⾮常に似ている!  HTTPでタスク(=メッセージ)がPushされる!  200系のレスポンスを返すことでタスクが完了、削除される

!  CloudPub/SubはTaskQueueの上位互換となり得るか?!  PushされるHTTPリクエストを柔軟に設定できない...

!  エンドポイントはSubscription毎に固定!  アプリケーション独⾃のHTTPヘッダも付けられない

!  Datastoreのトランザクションに含めることが出来ない...!  Pub/Subへのリクエストだけ失敗したらどうする?

14

App Engine

App Engine

Publish PushCloud Pub/Sub POST/_ah/push-handlers

Page 15: スケーラブル GCP アーキテクチャ

Copyright©DeNACo.,Ltd.AllRightsReserved.

CloudPub/Sub-柔軟にHTTPリクエストをPushさせる

!  柔軟にHTTPリクエストを設定するために1.  attributesと呼ばれるkey/valueペアにHTTPリクエストの情報を埋め込む

2.  リクエストのハンドリングを⾏なうコードの前にメッセージをほどき、HTTPリクエストを復元1.  アプリケーションから⾒て通常のHTTPリクエストと透過的にする

3.  Pub/Subが判別可能なレスポンスコードへの変換1.  “202Accepted”→“200OK”への変換など

15

{ “attributes”: { “method”: “PUT”, “path”: “/events/100”, “headers”: “{\”X-My-Header\”: \”1,2,3\”}” }, “data”: “eyJmb28iOiAiYmFyIn0=” }

PUT /events/100 HTTP/1.1 Content-Type: application/json X-My-Header: 1,2,3

{“foo”: “bar”}

encode

decode

HTTPPubsubMessage

Page 16: スケーラブル GCP アーキテクチャ

Copyright©DeNACo.,Ltd.AllRightsReserved.

CloudPub/Sub-確実にPublishするために

!  TaskQueueにはあったDatastoreとのトランザクションがない!  基本的にPub/Subへのリクエストはリトライを数回⾏なうことで⾼い確率で成功する!  (実測値)150msのタイムアウトでは99.96%の確率で1回で成功!  失敗しても1度リトライを挟むだけで99.998%まで上がる

!  それでも失敗した場合は!  TaskQueueにフォールバックさせる!  流れ:GAE→(TaskQueue→GAE)→Pub/Sub→GAE

!  トランザクションではないが実⽤には耐えうる

16

Page 17: スケーラブル GCP アーキテクチャ

Copyright©DeNACo.,Ltd.AllRightsReserved.

CloudPub/Sub-インスタンス爆発を防ぐためのフロー制御

!  外部システムに引きづられインスタンス爆発を引き起こす危険性がある!  GAEでは「ユーザのリクエスト」と「⾮同期タスクのリクエスト」を同じインスタンスで処理する設計を取ることがあるため

!  例.!  ⾮同期に通信しているAの調⼦が悪くてリクエストが遅い!  →ユーザからのリクエストを処理できるインスタンスが減る!  →インスタンスを増やして対処する!  →Aが回復しないのでインスタンスが際限なしに増えていく

!  解決策:Pub/Subのフロー制御をする!  “window”という設定値をDatastoreに持ち、どの程度Pub/Subからのリクエストを受け付けるかを定義する!  windowに収まるようにランダムに失敗レスポンスを返す

!  Pub/Subのslowstartな再送ロジックをうまく活⽤する!  ある程度「わざと失敗させる」ことでインスタンス数は安定してくる

17

Page 18: スケーラブル GCP アーキテクチャ

Copyright©DeNACo.,Ltd.AllRightsReserved.

CloudPub/Sub-フロー制御の例

18

App Engine

Cloud Pub/Sub

1.Push

Datastore

外部 システム

2.現在のwindowサイズを確認

3.windowサイズ⼩さい→4xxレスポンスを返却

なんだか調⼦が悪い…

3.windowサイズ⼤きい→実際の処理を実⾏

Page 19: スケーラブル GCP アーキテクチャ

Copyright©DeNACo.,Ltd.AllRightsReserved.

最後に

!  AppEngineとCloudPub/Subを使った⾮同期タスク処理を組み合わせることで、スケーラビリティの⾼いアーキテクチャを実現する⼯夫を紹介しました!  他にもDatastoreやAppEngineの中でも紹介したいTipsはありますが、それらはまた次回に!

!  GCPの各サービスは⽇々改善されているため、本トークで話した課題がすぐに解決されていることもありうることに注意です

19