SlideShare a Scribd company logo
大規模Node.jsを支える
ロードバランスとオートスケールの独自実装
2015/11/7
DaikiTaniguchi (@kidach1)
Akatsuki inc.
#nodefest2015
・Github https://github.com/kidach1
・Twitter https://twitter.com/kidach1
・Qiita http://qiita.com/kidach1
・Akatsuki Inc.
・Node / JavaScript /TypeScript
 Ruby / Rails / Android
 Dvorak Keyboard
kidach1
http://qiita.com/kidach1/items/b75882edd4f715ebc213
事前資料
アジェンダ
・作ったもの
・アーキテクチャ
 ・経緯
 ・ロードバランス
 ・オートスケール
・負荷試験
・その他
 ・FRP
 ・可用性
 ・監視
作ったもの
・2D横スクロールアクション
・マルチプレイ
 ・4人同時対戦
 ・座標同期型
 ・プレイヤーマッチング (Rating / Keyword)
作ったもの
• リアルタイム非同期4人同時プレイ
奪い合いアクションゲーム
• 動きやモーション、ダメージ、アイ
テム取得/使用などのイベントを4人
で連携しあう
Client:
 Cocos2d-x (c++)
Server:
 API Server:Rails
 Websocket Server:Node.js
詳しくは
スマホアプリにおけるマルチプレイアクションゲーム開発の実例紹介
http://www.slideshare.net/aktsk/ss-52126411/1
システム概要
・同時一万接続を想定
 → 常時数十∼百数十台規模の軽量インスタンスが稼働
・柔軟なオートスケール
 → 負荷に応じて柔軟に自律的に伸縮してくれるような
インフラにしたい
システム規模 / 要件
Architecture
Realtime
Cluster
LB Cluster
API
Cluster
Redis
Cluster
A. 各Cluster/各Nodeの状態を毎秒監視
B. Node毎の重み付けを毎秒更新
C. Clusterの状態に応じてオートスケール
D. LB間でのプロセス監視&自動FailOver
①② LobbyNode取得
③ Lobby接続
④ マッチングとroom_idの決定
⑤ room_id返却
⑥⑦ start(REST API)(GameNode取得)
⑧ GameNodeとroomを指定の上 GameServer接続
⑨ finish(REST API)
Architecture
本構成に至った経緯
立ちはだかる壁
Websocket / Socket.ioは(E)LBと相性悪いらしい
※ 正確には、「LBがクライアントからのリクエストを受け
付け、配下のサーバ群へ振り分ける形式」との相性
・Websocketと(E)LBの相性 ✕
 Websocketは一度接続するとサーバー/クライアント
間のセッションを張りっぱなしにするため、コネクショ
ン確立時以外LBを挟むメリットがない。むしろコネク
ション数が肥大化し、ボトルネックになり得る
立ちはだかる壁
・Socket.ioとELBの相性 ✕ ✕
 ELBのTCP Listenerを使った場合StickySessionがサポー
トされていないため、Socket.ioのhandshakingが通らず
コネクションが確立できない
立ちはだかる壁
大規模Node.jsを支える ロードバランスとオートスケールの独自実装
今回はNodeやwsに乗る場面じゃなかったか・・?
しかし最近のNode・JavaScript界隈の目覚ましい進化や、
npmの資産は魅力的
→もう少し過去事例を調べる
 ・ELBの下にNginxやHAProxyを立ててip-hashでバランスし
stickinessを担保する
   
過去事例1
 Load-balancing Websockets on EC2 — Medium
 https://medium.com/@Philmod/load-balancing-
websockets-on-ec2-1da94584a5e9
→しかし、ELBの下にさらにproxy立てて、はどうみ
ても辛い
・運用コスト増大(LBとProxy)
・そもそもupstreamの動的変更が出来ない(※)ため、ぶら下が
るec2インスタンスの変更には手動対応が必要
  → オートスケール実現不可
 ※ 実際はNGINX Plusの購入をすれば可能だが、多数のインスタンスを柔軟に追
加削除するには、結局追加モジュールを書く必要がありそう
過去事例1
 ・ELBはセッション確立時のみ、もしくはELBなしでロード
バランスするケース
   
過去事例2
WebSocket on AWS (ロードバランサと
Socket接続を使用したイベント通知サー
バの負荷分散)
http://www.slideshare.net/
AmazonWebServicesJapan/socket-15753751
TV連動サービスのリアルタイム通知を支
える技術
http://www.slideshare.net/tsuyoshitorii5/
public-43549341
・なるほど!これだ
 やはりクライアントとsocket.ioクラスタの間にはLB置かないべき
・AutoScalingは想定していないようだったので、その仕組みを追
加するように拡張していく方向で決定
過去事例2
LoadBalance
・EC2のtagをもとに、各クラスタ(lobby/game server)の各
ノードごとのコネクション数を毎秒取得
・RedisのSortedSetで保管/更新
・APIサーバーからリアルタイムで最も接続数の少ないノー
ドを読み出し、クライアントにendpointを返却
LoadBalance
LB visualization
・インスタンスはコア数が少ないものを大量に横に並べる方針
 ・SingleThreadで動くNodeとは相性が良い
 ・コア数を増やしてClusterModuleを利用する方法もあるが、
(同一コアへのバランスなど)実装が複雑化するので避ける
Point
・CPU使用率やLoadAverageといった指標ではなく、socket.ioプロセス
(アプリケーションレイヤー)でのコネクション数を見てバランス
 →サーバー自体はhealtyなのにプロセスは死んでいた、等を排除
 ※ websocket/socket.ioを用いる場合、httpと比べて「OSレイヤーの指標と
アプリケーションのプロセスの生死」が直結していない印象だった(正確
には、その部分に対する勘所がなかった)ため
Point
Autoscaling
・Game/Lobby各Clusterの状態を毎秒監視
・設定した閾値に応じてサーバーを自動で追加/縮小
・スケールアウトは最短で3分に一度、スケールインはよりシビ
アに1時間に一度のスパンに制限(任意の値を設定可能)
Autoscaling
・ゼロダウンタイム
 ・サーバープロセスが立ち上がり接続が確認できるまでLB
側で有効なノードとして認識しない
 ・縮小時は、ノードへの接続がない状態でしかトリガーさ
れない
Autoscaling
・Clusterの状態変化をシームレスにスケーリングイベントに
繋げるため、FRPのパラダイムを利用
 ・Reactive-Extensions/RxJS
 ・詳細後述(時間の限り)
Point
・スケーリングのツールはCloudFormation
 ・だが、次の課題を吸収するためRubyラッパーである
kumogataを利用
Point
・socket.ioプロセスベースでコネクション数を監視、閾値に応じて
柔軟に増減台数を決定したい
→ 監視と増減台数決定部分はNode(前述のFRPの箇所)で、台数
に応じたスケーリングはCloudFormationで実現したい
→ CloudFormation単体(JSON)では力不足
Cloudformation
・kumogata
 winebarrel/kumogata
 https://github.com/winebarrel/kumogata
・cloudformationをRubyで。
 →任意のインスタンス数
  指定ロジックの記述
kumogata
・インスタンス50台同時起動
$ INSTANCE_NUM=50 kumogata create cloudformation/kumogata.rb prod-
realtime
→ LobbyServer / GameServer 25台ずつのクラスタが生成される
kumogata
・同時1万Connectionをシミュレートしたい
・攻撃サーバー1台ではマシンパワー不足
LoadTesting
LoadTesting
newsapps/beeswithmachineguns
https://github.com/newsapps/beeswithmachineguns jmeter内包 = httpのみ・・
・結局自分で作る
socketio/socket.io-clientベース
https://github.com/socketio/socket.io-client
LoadTesting
・kumogataで複数攻撃サーバー同時立ち上げ
 $ kumogata create cloudformation/bees-kumogata.rb bees
・ansibleでsocke.io-clientの攻撃スクリプトを複数台同時実行
 $ ansible-playbook -i ./hosts/develop/ec2.py bees.yml —private-
key=<key_path>
LoadTesting
LoadTesting
・Websocket/Socket.ioとELBの相性の問題
 → 消滅
実装してみて
・LBが直接ユーザーからのコネクションを受けることがない
ため、単一障害点になるリスクが低い。
実運用において、
 ・直接的な障害無し
 ・緊急対応的な手動オペレーション無し
 (事前に必要とわかっているデプロイ/メンテ等を除く)
実装してみて
・本質的な部分(※)の実装は薄く、モジュール化可能
 ※各ノードの任意の状態(コネクション数やCPU使用率など)を常時監視
し、設定した閾値に応じて任意のスクリプトをトリガー
・今回のsocket.ioのようなニッチなケースに限らず、http以外
のプロトコルでAutoscaleさせたい時にも使えるかもしれない
 ・SPDY/HTTP2やwebRTC etc..
実装してみて
Appendix
・4人同時対戦
 → GameServerはマッチした4人を同一ノードに送り込む仕組み
 → ノード間の協調が不要、実装がシンプルに
・全国マッチング
 → LobbyServerは全ノード間でユーザーのセッション情報の協調
が必要
 → socketio/socket.io-redisを利用
LB Point
Availability
Lobby & Game Cluster
・Multi-AZ
・擬似FailOver
 ・各クラスタ最低構成台数を持っておき、この閾値を下回る
とAutoscaleが発火
  ・AutoscaleでFOの機能をざっくり吸収
  ・状態を持たないdisposableな設計のため実現しやすかった
Availability
LoadBalancer & Autoscaling Server
 → SPOFになるとしたらこちら(直接リクエストを受け付けること
がないのでリスクは少ないが、稼働台数が少ないため)
・Multi-AZ
・FailOver
 ・Lobbyクラスタ用LB、Gameクラスタ用LB それぞれがお互いを
Socket.ioプロセスベースで監視し合う
 ・障害発生時に一方が片方の機能を吸収する形で自動でFailOver
 ・インスタンスが復旧した時点で自動でFailBack
Availability
 ・監視
  ・CloudWatch
  ・Slack連携
   ・破壊的なイベント発生時やサーバーの状態を定期的
にSlackで通知
Monitoring
Autoscaling
Redis内で刻々と更新されていくインスタンス毎のコネク
ション数をもとに、オートスケールの発火を管理する
Point
_人人人人人_
> F R P <
 ̄Y^Y^Y^Y ̄
・Redisから取得したデータを基軸とした一本のストリーム
・ストリームに対して様々な制御(オペレーション)
・スケーリングイベントの発火
Design
Autoscaling
オートスケールの発火条件
・負荷(※今回は接続数)に応じてトリガー
・指定時刻にトリガー
・事前に設定したクラスタごとの最低稼働台数を下回った際トリガー
Design
Implementation
Implementation
Implementation
Implementation
Anti Pattern
冗長なストリーム
Redundant Stream
大規模Node.jsを支える ロードバランスとオートスケールの独自実装
大規模Node.jsを支える ロードバランスとオートスケールの独自実装
Anti Pattern
・ Not DRY
・ Fat I/O
Observable
Hot / Cold
Hot / Cold
・Cold -> Observable : Observer = 1 : 1
・Hot -> Observable : Observer = 1 : n
・特定のオペレータ(publish等)を使うと
 Cold→Hotに変換可能
・特定のオペレータ(connect等)を使うと
 HotObservableの値がObserver達に一斉通知
Autoscaling
・mainStreamをHotObservableに変換(publish)
・各observer(checkByXXX)に分岐した後にconnect
Hot Observable
手続き型との比較
大規模Node.jsを支える ロードバランスとオートスケールの独自実装
大規模Node.jsを支える ロードバランスとオートスケールの独自実装
FRP比:
・プリミティブな制御構造(今回は主に条件分岐)が
随所に登場し、全体の流れを俯瞰しにくい
FRP ver
FRPによって
・リストとして扱うことでオペレータ(filterやmapなど)
を適用でき、制御構造が抽象化/隠 される
・非同期処理もストリームの一部として違和感なく扱える
結果として「コード全体の見通し向上」
つまり「本質的な処理に集中」できる
・FPR→コードの見通し↑でなかなか良い
・インフラの制御はだいたいイベント駆動なので相性◎
・まずはRx眺めてみると良いかも
結論
http://qiita.com/kidach1/items/5fd764c18de7cdae24ca
WE ARE HIRING!
http://aktsk.jp/recruit/
or @kidach1
Thank you !
Questions

More Related Content

PDF
ゲームアーキテクチャパターン (Aurora Serverless / DynamoDB)
PDF
OpenAPI 3.0でmicroserviceのAPI定義を試みてハマった話
PPTX
脱RESTful API設計の提案
PDF
[Aurora事例祭り]Amazon Aurora を使いこなすためのベストプラクティス
PDF
Hadoop/Spark で Amazon S3 を徹底的に使いこなすワザ (Hadoop / Spark Conference Japan 2019)
PPTX
データ履歴管理のためのテンポラルデータモデルとReladomoの紹介 #jjug_ccc #ccc_g3
PDF
Data platformdesign
PDF
マルチテナントのアプリケーション実装〜実践編〜
ゲームアーキテクチャパターン (Aurora Serverless / DynamoDB)
OpenAPI 3.0でmicroserviceのAPI定義を試みてハマった話
脱RESTful API設計の提案
[Aurora事例祭り]Amazon Aurora を使いこなすためのベストプラクティス
Hadoop/Spark で Amazon S3 を徹底的に使いこなすワザ (Hadoop / Spark Conference Japan 2019)
データ履歴管理のためのテンポラルデータモデルとReladomoの紹介 #jjug_ccc #ccc_g3
Data platformdesign
マルチテナントのアプリケーション実装〜実践編〜

What's hot (20)

PPTX
Redis勉強会資料(2015/06 update)
PPTX
JavaScriptの仕組みと未来のJavaScript ~ESNextとは~
PPTX
[社内勉強会]ELBとALBと数万スパイク負荷テスト
PDF
YugabyteDBを使ってみよう(NewSQL/分散SQLデータベースよろず勉強会 #1 発表資料)
PDF
Dockerからcontainerdへの移行
PDF
君はyarn.lockをコミットしているか?
PDF
[CEDEC 2021] 運用中タイトルでも怖くない! 『メルクストーリア』におけるハイパフォーマンス・ローコストなリアルタイム通信技術の導入事例
PPTX
大規模データ活用向けストレージレイヤソフトのこれまでとこれから(NTTデータ テクノロジーカンファレンス 2019 講演資料、2019/09/05)
PDF
[JAWS DAYS 2019] Amazon DocumentDB(with MongoDB Compatibility)入門
PDF
REST API のコツ
PDF
マイクロにしすぎた結果がこれだよ!
PPTX
Redisの特徴と活用方法について
PPTX
イベント駆動プログラミングとI/O多重化
PDF
Docker入門-基礎編 いまから始めるDocker管理【2nd Edition】
PDF
実務で役立つデータベースの活用法
PPTX
分散トレーシングAWS:X-Rayとの上手い付き合い方
PDF
IoT向けプラットフォーム「SORACOM」とは? 他2本
PDF
Nginxを使ったオレオレCDNの構築
PDF
20210127 AWS Black Belt Online Seminar Amazon Redshift 運用管理
PDF
負荷試験入門公開資料 201611
Redis勉強会資料(2015/06 update)
JavaScriptの仕組みと未来のJavaScript ~ESNextとは~
[社内勉強会]ELBとALBと数万スパイク負荷テスト
YugabyteDBを使ってみよう(NewSQL/分散SQLデータベースよろず勉強会 #1 発表資料)
Dockerからcontainerdへの移行
君はyarn.lockをコミットしているか?
[CEDEC 2021] 運用中タイトルでも怖くない! 『メルクストーリア』におけるハイパフォーマンス・ローコストなリアルタイム通信技術の導入事例
大規模データ活用向けストレージレイヤソフトのこれまでとこれから(NTTデータ テクノロジーカンファレンス 2019 講演資料、2019/09/05)
[JAWS DAYS 2019] Amazon DocumentDB(with MongoDB Compatibility)入門
REST API のコツ
マイクロにしすぎた結果がこれだよ!
Redisの特徴と活用方法について
イベント駆動プログラミングとI/O多重化
Docker入門-基礎編 いまから始めるDocker管理【2nd Edition】
実務で役立つデータベースの活用法
分散トレーシングAWS:X-Rayとの上手い付き合い方
IoT向けプラットフォーム「SORACOM」とは? 他2本
Nginxを使ったオレオレCDNの構築
20210127 AWS Black Belt Online Seminar Amazon Redshift 運用管理
負荷試験入門公開資料 201611
Ad

Viewers also liked (20)

PDF
[Tokyo NodeFest 2015] Hardware Hacking for Javascript Developers
PPTX
The State of JavaScript (2015)
PDF
unassert - encourage reliable programming by writing assertions in production
PDF
Node.jsv0.8からv4.xへのバージョンアップ ~大規模Push通知基盤の運用事例~
PDF
スマホアプリにおけるマルチプレイアクションゲーム開発の実例紹介
PPTX
TV連動サービスのリアルタイム通知を支える技術
PDF
【CEDEC2013】20対20リアルタイム通信対戦オンラインゲームのサーバ開発&運営技法
PDF
마이크로소프트 앱 플랫폼을 이용한 어플리케이션 개발과 배포
PDF
Node.jsのオートスケールをFRPで管理する
PDF
Va tutorial
PDF
Android nodejs binary-transfer_130531ss
PDF
PPTX
Aws 2014 lt
PDF
OSC2010 TOKYO/Spring Asterisk Seminar
PDF
World Cup Marketing 2014
PPTX
冗長構成で定価100万以下バラクーダ ロードバランサー
PDF
Wakamonog6 “ISPのネットワーク”って どんなネットワーク?
PDF
Layer 4 Load Balancer (NAT, IP Tunnelling, DR)
PDF
Node.jsで対戦ゲーム作ったよ
PDF
What Teens Want Beinggirl Pres
[Tokyo NodeFest 2015] Hardware Hacking for Javascript Developers
The State of JavaScript (2015)
unassert - encourage reliable programming by writing assertions in production
Node.jsv0.8からv4.xへのバージョンアップ ~大規模Push通知基盤の運用事例~
スマホアプリにおけるマルチプレイアクションゲーム開発の実例紹介
TV連動サービスのリアルタイム通知を支える技術
【CEDEC2013】20対20リアルタイム通信対戦オンラインゲームのサーバ開発&運営技法
마이크로소프트 앱 플랫폼을 이용한 어플리케이션 개발과 배포
Node.jsのオートスケールをFRPで管理する
Va tutorial
Android nodejs binary-transfer_130531ss
Aws 2014 lt
OSC2010 TOKYO/Spring Asterisk Seminar
World Cup Marketing 2014
冗長構成で定価100万以下バラクーダ ロードバランサー
Wakamonog6 “ISPのネットワーク”って どんなネットワーク?
Layer 4 Load Balancer (NAT, IP Tunnelling, DR)
Node.jsで対戦ゲーム作ったよ
What Teens Want Beinggirl Pres
Ad

大規模Node.jsを支える ロードバランスとオートスケールの独自実装