Slide 1

Slide 1 text

WinTicketにおける リアルタイム性と⾼負荷を考慮した アーキテクチャ 株式会社サイバーエージェント 江頭 宏亮

Slide 2

Slide 2 text

江頭 宏亮 えがしら ひろあき • 2018年4⽉ 株式会社サイバーエージェント⼊社 CATS(CyberAgent Advanced Technology Studio)
 • WinTicket - 公営競技事業 バックエンド テックリード hiro _hiro

Slide 3

Slide 3 text

本⽇の内容 • WinTicketとは • 全体アーキテクチャ • 情報のリアルタイム性の実現 • 投票券の購⼊‧精算時の負荷対策

Slide 4

Slide 4 text

WinTicketとは

Slide 5

Slide 5 text

WinTicket • オンライン競輪投票サービス • ウェブとiOS‧Androidアプリを提供 • いつでも投票券を購⼊可能 • 全国43会場のライブ映像を配信 • AbemaTVの競輪チャンネルと連動

Slide 6

Slide 6 text

全体アーキテクチャ

Slide 7

Slide 7 text

技術選定

Slide 8

Slide 8 text

No content

Slide 9

Slide 9 text

Kubernetes マイクロサービスアーキテクチャ • 36種類のマイクロサービスが稼働 • ゲートウェイ パターン • アンバサダー パターン • オートスケール

Slide 10

Slide 10 text

• 可⽤性の向上に貢献 Outlier Detection, Circuit Breaking Load Balancing, Retry, etc • ロギングなどを任せることで ロジックの開発に集中 Envoy サービスメッシュを構成

Slide 11

Slide 11 text

Cloud Spanner ⽔平スケール可能なリレーショナル データベース

Slide 12

Slide 12 text

• 選定理由
 ⾦銭の取引があるのでトランザクション必須
 購⼊できないと(ダウンタイムは)事業的損失が⼤きい
 レースの締切直前と結果確定直後に書き込み負荷が⼤きい • 性能(1インスタンスあたり)
 リード:最⼤10,000 QPS, ライト:最⼤2,000 QPS Cloud Spanner ⾼可⽤性 SLA . %

Slide 13

Slide 13 text

リアルタイム性

Slide 14

Slide 14 text

最新の情報を すぐに届ける必要がある

Slide 15

Slide 15 text

競輪決済システムのプロキシではない

Slide 16

Slide 16 text

投票システムのプロキシではない 購⼊‧払い戻しの全ての責任を負う • 競輪システムから取得できる情報は出⾛表とオッズと結果ぐらい • 取得できた情報をもとに販売可能な投票券と払い戻す投票券を判断 • 競輪システムには投票券の販売状況を定期的に報告 誤販売を防ぐために情報のリアルタイム性は重要

Slide 17

Slide 17 text

リアルタイム性 最新の情報をすぐにユーザーへ届ける必要がある • 変わりやすい‧すぐに届けたい情報
 オッズ、出⾛表、レース結果 • 情報量が多い
 レース詳細情報を取得するAPIのレスポンスは約 KB

Slide 18

Slide 18 text

Fastly Instant Purgeが決め⼿ • ms以内にキャッシュをパージできる • レスポンスヘッダーにサロゲートキーを設定することで
 そのキー単位でパージできる • VarnishベースなのでVCLで設定できる • 導⼊した結果 ⼿元の環境では 20KB超えAPIも20msほどのレイテンシに抑えられている データベースへの負荷も抑えられた

Slide 19

Slide 19 text

singleflight 関数の重複呼び出しを抑制するメカニズム • キャッシュミス時のオリジンアクセスの負荷を抑えられる • キーに対して同時に1つの実⾏しか⾏わない • 重複した関数呼び出しは最初の実⾏を待ち、その結果を返す • 時間的局所性がある場合に効果的

Slide 20

Slide 20 text

⾼負荷

Slide 21

Slide 21 text

負荷がかかるタイミング • レース締め切り直前 締め切りギリギリに購⼊が集中する • レースの結果確定直後 結果確定後にすぐにユーザーへ払い戻しを⾏わないといけない 最短で約20分おきにレースが発⾛する できるだけ早く払い戻し処理を完了させた⽅が良い

Slide 22

Slide 22 text

事業的な要件 • 購⼊リクエスト 1,000 rps を処理 • 3分以内に 30万ユーザーに払い戻し

Slide 23

Slide 23 text

⾼負荷 購⼊は Spannerのスケールアウトで対応 Spannerとsingleflightで問題なく捌けた

Slide 24

Slide 24 text

Queue-Based Load Leveling 払い戻しは キューイングしてワーカーで処理

Slide 25

Slide 25 text

Cloud PubSub GCPのフルマネージド メッセージング ミドルウェア • Topic/Subscription • At least once 配信 • Ack/Nackでリデリバリー可能

Slide 26

Slide 26 text

Queue-Based Load Leveling メリット • ワーカーの数を調整することでDB負荷を抑えることができる • スケールアウト‧インが容易 • エラーが発⽣してもNackを返すことでリデリバリーされ⽋損しない

Slide 27

Slide 27 text

Queue-Based Load Leveling もしキューイングせずに処理すると… • DBなどへの負荷がスパイクして障害につがなるおそれがある • KubernetesはPodの再配置を⾃動的に⾏うので⻑時間の処理中にスケ ジューリングされると処理が中断され⽋損につながるおそれがある • Podで処理するとそのリソースが性能限界になりスケールしにくい

Slide 28

Slide 28 text

Queue-Based Load Leveling 負荷試験の結果 • 1秒間に1,000ユーザー分 払い戻しできた
 → 3分間で18万ユーザーという結果に

Slide 29

Slide 29 text

Queue-Based Load Leveling 様々な処理で利⽤している • お知らせ送信(メール‧プッシュなど) • ユーザーステージの更新 • ポイント精算 など…

Slide 30

Slide 30 text

ありがとうございました