ゲームサーバ勉強会に参加しました。

第二回ゲームサーバ勉強会

 

こちらに参加してきました。

 

先日Unityの記事を書いたりもしましたが、ゲーム関連は大変興味があったのと、
今の仕事に活かせる物がなにかしらあるんじゃないかな?と思い参加してきましたので、
そのあたりのまとめです。
 
■データベースの再入門
講演者:@nsegaさま

■データベースを使った使用事例
講演者:株式会社gumi 清水さま
 
■MMOのサーバについて「剣と魔法のログレス 〜いにしえの女神〜」での実装例
講演者:株式会社Aiming 山藤 智之様
 
 
で、以下は各セッションの要約と感想です。
 
 
■データベースの再入門
・DBについて
DML,DDL,DCL
=>このへんの役割ちゃんと理解しときたい
=>何かいい本とかあるかな?
DB使う意味
=>大量データをメモリ空間に展開するときになんでDBの方がいいの?
インデックス
=>インデックスってどういう風につくられるのか?
=>マスタとスレーブ構成
=>スレーブ間のデータ整合性とかってどうやって担保してる?
 
RDBとNoSQL
RDBの得意なこと
=>トランザクションがある(整合性担保できる)
=>枯れてる
=>テーブル結合とかできる
RDBだと厳しい
=>大量データの書き込み
=>インデックスとかテーブル耕造の変化に弱い
=>トランザクションがある(遅い)
NoSQL
=>キーバリュー、ドキュメントベース、カラムファミリーとか。いろいろある
=>データを分散させやすい
=>大量データの書き込みがらく
=>スケールしやすい
=>なぜ???
NoSQLだとだめなとこ
=>CAPの中の、三つ全部担保できない
RDBとNoSQL
=>戦わせる必要はない
=>お互いの得意なところをカバーする
ログインセッションのキャッシュ
タイムライン形式のアプリ
リアルタイム処理
ページごとのアクセス数
 
・テーブル設計
=>概念、論理、物理の順でモデリング
=>データの正規化ってけっこう難しいけど、どうやってる?
分類
=>マスタ系とトランザクション系で分類してる
=>基本的にマスタ系はセレクトしかされない感じ?
=>このへんのデータの性質によってDB変えたりする?
レビュー観点
=>命名規則おかしくないか
=>カラムの型の精度
=>データ量は考慮されているか
=>テーブルのCRUDを説明できるか
=>主キーは適切か
=>ある程度汎用的な構成になっているか
現場でのノウハウ
=>実行コストもちゃんと見る
=>ORマッパーのデメリットも考慮する
=>パフォーマンステストでもわかるけど、先につぶせるとこはつぶす
 
=>DBを分割する(垂直、水平)
=>性能、管理しやすさはあがるが、設計で考慮しないといけない内容が増える
=>JOINしないといけなくなったり、最悪2回引かないといけなくなる
 
=>担当をクライアントサーバでわけない?(タスクの分割のやりかた?)
=>個人の技術力による
 
まとめ
=>クライアントだけでなくサーバも理解しておけば、開発効率がよくなるよ!
 
・質問
PostgresとMongoDBを採用した理由
=>Postgresは最初からあった
=>Mongoは採用当時(2年くらい前)に一番情報の公開が活発であった
逆に今から選び直すとしたら
=>正直なところわからない、その時に状況に寄る
=>そんなにキャッチアップしてない?
レビューできる人がいない、時間がない、はじめてやるって場合はどうしたらいい?
=>とりあえずやってみればいいのに
RDBMSとNoSQLへのデータ移行は?
=>自分でスクリプト組めばいい
 
・感想
DBとは?というところから、若干駆け足であったが実際に運用のノウハウまでの話
目新しい内容はなかったが、実践ノウハウが聞けたのが面白かった
また、Postgres -> mongoの流れがうちと同じで親近感がわいた
NoSQLはまだまだ枯れてない技術なので、これからもリサーチは必須かなと思う
個人的にはKV型以外のやつを使ってみたいので、Cassandraとかつかってみて、Mongoとどのくらいパフォーマンスに差が出るのか調べてみたい
 
 

■データベースを使った使用事例
分割と整合性をがんばる話
radis
rabbitsq
使ってる
 
負荷対策の話
=>サービスがヒット
=>更新処理が限界に
=>どのくらいアクセスきたの?
=>DBを垂直分割して、負荷を分散させた
=>いっきにやったのではなくて、性能の限界に打ち当たるたびに少しずつ分割していった
=>1機能に負荷が集中すると結局だめ
=>また、同時に使う機能は分割しても意味ない
=>ユーザ数に比例して水平分割して解決させた
=>スケールにアプリケーション側が対応できてなかっただけ?
=>水平分割する際には、主キーの扱いに気をつける
 
=>不整合の問題が残っている
=>100万ユーザ対応できるような設計を求められた
=>負荷は水平分割で対応
=>XA Transaction(複数テーブルにまたがったトランザクション
=>prepareはcommitの成功を保証する?
=>ロックによる排他制御
=>複数ユーザ(テーブル)にまたがる処理に関しては適当な分割しない
=>マスタデータはjsonファイル化?
=>自動回復系のステータスもトランザクション管理するようにした(ユーザの資産に直結するため)
=>RDBにもたせて、実装でカバーした
=>データの正規化をすごくがんばった
=>インデックスの貼り忘れで若干事故った
 
=>インデックス貼ってないとこに対してロックかけると、ロック範囲が全体になったりする
=>分割したDB間のデッドロックが検知できなくて死んでた
=>ロックする順番を決めることで解決させた
=>大きめにロックをとるのも手
=>参照に更新が混じっているとけっこう危ない
 
まとめ
=>ちゃんとしてあげればRDBだけでもなんとかできる
=>NewRelicとJetProfilerはなかなかいい
=>適切なインデックスを貼る
=>SQLアンチパターンはいい本
 
感想
使っていたのがMySQLだったが、負荷の問題に関しては共感できた
で、それに対する解決策が水平分割でありそれなりに成果が出ていたようなので、社内で共有してみたいと思った
逆に、現在社内でそれができていない理由が知りたくなった
予算の問題か、そもそも設計上それが不可能なのか?
また、XA Transactionに関して(というかTransactionそのものに関しても)はまだまだ知らないことが多いので調べてみる
 
 
 
■MMOのサーバについて「剣と魔法のログレス 〜いにしえの女神〜」での実装例
サーバ構成
=>階層わけて冗長化、横のつながりはない
=>フロント:独自実装の通信方式と、HTTPを使い分けている
=>バックエンド:ゲームサーバと常時接続
=>ぜんぶC++で書いてる
=>Socket:サーバからのプッシュが必要な場合、レスポンス速度重視、常時接続、差分更新
=>上記でない場合はHTTP
=>Socketは毎回コネクションを貼り直す必要がないし、一回の送受信量が少なくてすむ
=>しかし、バッテリ消費多くなったり回線切れに弱いし、スケールしにくい
 
実装
=>通信範囲、という考え方
=>一定の範囲内に入っているユーザ同士でしか、データのやりとりをする必要がない
=>移動のデータフロー
=>キャラクタ移動の際、サーバ側との通信を待たないで先に移動させる(通信待ちがストレスになるから)
=>その後サーバ側で移動先などを確認し、他のクライアントへ通知する
=>チャット
=>キャラクタ上に表示されているメッセージはSocketで、チャットログはHTTPで実装されている
=>過去の発言でも見れるように、HTTPになっている
 
問題と対応
=>クライアントが接続してるサーバが切り替わった場合の、サーバ側のコストが高かった
=>サーバ側得をスケールさせることで解決
 
質問
WebSocket使わなかったのなんで?
=>オンラインの通信関連に強い人が多かった
=>新しいものを導入するのが大変だった
=>よくわからないもの使うよりかは、隅から隅まで全部わかるものを自分で作る方がいいんじゃないか、となった
=>仮に今からやり直すのであれば、十分選択肢には入ってくる
 
感想
あんまり深い内容はなかったが、だいたい、どういう風に実現しているのかがわかった
特にチャットのやり取りで、ログはHTTP、メッセージはSocketでやっているっていうのは、適材適所な感じでいいなと思う
 
 
 
最近サーバサイドのことあんまりやっていなかったので、とても楽しかったです。
DBも楽しいですが、こんどはApacheやnginxとかのミドルウェアの話を聞いてみたいと思いました。
大量のアクセスをさばいたり、レスポンスをコンマ一秒でも早くするためには、みたいなノウハウを聞いてみたいです。
まあそのためにも、まずは自分でやってみないと、ですね。
とりあえずAmazonEC2借りて、サーバ立てて遊んでみるべしです。
 
あとはサーバサイドのプログラミング言語で、Java以外の何かを勉強してみよう。
この勉強会で「Pythonいいよ!かわいいよ!」って話を聞いたので、それも楽しそうですし、あとは会社で使ってるscalaをちゃんと勉強したいなと思います。
 
ま、ちょっとずつ楽しくやってこう。
Enjoy。