Upload
flashscope
View
444
Download
1
Embed Size (px)
DESCRIPTION
다음의 슬라이드를 번역한 자료입니다. 古閑学/@_mamehiko_さんのslideを翻訳したものです。 http://www.slideshare.net/manabukoga39/ss-31004722
Citation preview
서버 미경험자가 소셜게임을 통해 알게된 서버에 대한것
サ〡バ〡未経験者がソ〡シャルゲ〡ムを通して知ったサ〡バ〡の事 http://www.slideshare.net/manabukoga39/ss-31004722
주식회사gumi 코가 마나부(古閑学)/@_mamehiko_
2014/2/8 게임서버공부회
© All Rights Reserved
자기소개
코가 마나부/@_mamehiko_
주식회사 gumi 동경오피스 엔지니어 2013/12월로 3년째 이름뿐인 스페셜 리스트
최근은 cocos2d-x로 클라이언트 엔지니어
이전은 콘슈머에서 프로그래머를 8년정도
2딸의 아빠
회사 밖에서 말하는것은 처음
自己紹介gumiって?gumi란?
ㅇ 自己紹介
上記サーバーサイドの開発をしてました。騎士道とドラゴンジェネシスでは元リードエンジニア
2011 2012 2013
自己紹介(gumiでは)자기소개(gimi에서)
위의 서버 사이드의 개발을 했습니다. 기사도와 드래곤제네시스에서는 전 리드 엔지니어
サーバー未経験からソーシャルゲームを通して得た経験をさらけ出します。コード失敗事例とか当時の思い込みとか
今日のお話
上級者
初心者
インフラ 開発
今日のお話
서버 미경험자로부터 소셜 게임을 통해 얻은 경험을 들춰냅니다. 코드 실패 사례던지 당시의 생각이던가
오늘 이야기
개발인프라
초급자
상급자
前提
トライアル&エラー編2011~2012~
ギルドバトル編マスターデータバトルマッチング
最後にキャッシュRedis
まとめ
アジェンダアジェンダ아젠다
전제
시도&에러 편
길드 배틀편마스터 데이터 배틀 매칭
마지막으로캐시
정리
前提
トライアル&エラー編2011~2012~
ギルドバトル編マスターデータバトルマッチング
最後にキャッシュRedis
まとめ
アジェンダアジェンダ아젠다
전제
시도&에러 편
길드 배틀편마스터 데이터 배틀 매칭
마지막으로캐시
정리
言語python2.7
WebフレームワークDjango1.4以上
DataBaseMySQL5.5
前提前提전제언어
웹프레임워크Django1.4 이상
前提
トライアル&エラー編2011~2012~
ギルドバトル編マスターデータバトルマッチング
最後にキャッシュRedis
まとめ
アジェンダアジェンダ아젠다
전제
시도&에러 편
길드 배틀편마스터 데이터 배틀 매칭
마지막으로캐시
정리2011~
初めてのソーシャルゲーム처음하는 소셜 게임
2011~
TokyoTyrant
AppサーバーMySQL
ロードバランサ
memcached
構成구성
로드밸런서 App서버
マスターデータ
プレイヤーデータ
ギルドデータ
などが一つのDBに
2011~RDS(MySQL)마스터 데이터
플레이어 데이터
길드 데이터
등등이 하나의 DB에
マスターデータ
プレイヤーデータ
ギルドデータ
などが一つのDBに
2011~
つまり全部入り
RDS(MySQL)마스터 데이터
플레이어 데이터
길드 데이터
등등이 하나의 DB에
즉 전부 다 넣음
なんか、クエリってのを減らした方がいいらしい
後、KVSってのがあるらしい
뭔가, 쿼리라는걸 줄이는게 좋다고 하더라
그리고 KVS라는게 있다고 하더라
雰囲気でやってた時代!
なんか、クエリってのを減らした方がいいらしい
後、KVSってのがあるらしい
※あくまで個人の発言です
뭔가, 쿼리라는걸 줄이는게 좋다고 하더라
그리고 KVS라는게 있다고 하더라
분위기로 하던 시대!
어디까지나 개인의 발언입니다.
KVS(Key-Value Storage)
2011~
APサーバーロードバランサ
memcached
TokyoTyrant
MySQL
KVS(TokyoTyrant)
로드밸런서 App서버
データの選定데이터의 선정
プレイヤーには体力がある
体力を消費してクエストを進める
クエストを進めると経験値が入る
経験値が入るとレベルアップする
2011~例えばこんなゲーム예를들면 이런 게임
플레이어에게는 체력이 있음
체력을 소비해서 퀘스트를 진행
퀘스트를 진행하면 경험치가 들어옴
경험치가 들어오면 레벌업 함
プレイヤーには体力がある
体力を消費してクエストを進める
クエストを進めると経験値が入る
経験値が入るとレベルアップする
2011~
あるあるソーシャルゲーム
例えばこんなゲーム예를들면 이런 게임
플레이어에게는 체력이 있음
체력을 소비해서 퀘스트를 진행
퀘스트를 진행하면 경험치가 들어옴
경험치가 들어오면 레벌업 함자주있는 소셜게임
プレイヤーには体力がある
体力を消費してクエストを進める
クエストを進めると経験値が入る
経験値が入るとレベルアップする
2011~
SQL減らしたいしね!
更新の高いものをKVSへ갱신이 많은것을 KVS로
플레이어에게는 체력이 있음
체력을 소비해서 퀘스트를 진행
퀘스트를 진행하면 경험치가 들어옴
경험치가 들어오면 레벌업 함SQL줄이고 싶네!
うまくいった잘 되었다.
ようにみえたが。。。라고 보였으나…
2011~
��:BkCYejRPSdju>34�t����������^hMa0ByxK��������� �������� ����������������^hMa0B{��LW^������� ����� �� �� �� �� �� ���������Ne0�8<G��Ki0g]WP���������������������� �� ���������@9JD���v/{��7�5I/����������������������
体力→KVS 経験値→DB
例えばこんなコード
※実際のコードとは異なります
예를들면 이런 코드이 안은 트랜잭션 안이라는 가정
플레이어의 체력을 소비
플레이어의 경험치 업
에러가 발생하면 DB롤백
문제없으면 DB갱신. 경험치가 늘어난다.
체력 경험치실제 코드랑은 다릅니다.
��:BkCYejRPSdju>34�t����������^hMa0ByxK��������� �������� ����������������^hMa0B{��LW^������� ����� �� �� �� �� �� ���������Ne0�8<G��Ki0g]WP���������������������� �� ���������@9JD���v/{��7�5I/����������������������
2011~
←ここでエラー
体力→KVS 経験値→DB
例えばこんなコード예를들면 이런 코드이 안은 트랜잭션 안이라는 가정
플레이어의 체력을 소비
플레이어의 경험치 업
에러가 발생하면 DB롤백
문제없으면 DB갱신. 경험치가 늘어난다.
체력 경험치
여기서 에러
どうなるか어떻게 될까?
2011~
体力は消費される経験値付与でエラーが起きる
��:BkCYejRPSdju>34�t����������^hMa0ByxK��������� �������� ����������������^hMa0B{��LW^������� ����� �� �� �� �� �� ���������Ne0�8<G��Ki0g]WP���������������������� �� ���������@9JD���v/{��7�5I/����������������������
どうなる?어떻게 되?
체력은 소비된다. 경험치 부여에서 에러가 발생
2011~
体力は消費される経験値付与でエラーが起きる
体力だけが消費されるユーザーの不利益となる
��:BkCYejRPSdju>34�t����������^hMa0ByxK��������� �������� ����������������^hMa0B{��LW^������� ����� �� �� �� �� �� ���������Ne0�8<G��Ki0g]WP���������������������� �� ���������@9JD���v/{��7�5I/����������������������
どうなる?체력은 소비된다. 경험치 부여에서 에러가 발생
체력만 소비 된다. 유저의 불이익이 된다.
어떻게 되?
単純にバグッてる
アクセス過多
サーバーが息をしていないetc...
2011~原因は様々원인은 여러가지
단순히 버그임
엑세스 과다
서버가 숨을 쉬지 않는다 etc…
単純にバグッてる
アクセス過多
サーバーが息をしていないetc...
2011~
想定外の事が起きるんです
原因は様々원인은 여러가지
단순히 버그임
엑세스 과다
서버가 숨을 쉬지 않는다 etc…
상정외 일들이 일어나요
回避策회피책
2011~��:BkCYejRPSdju>34�t����������^hMa0ByxK��������%!�+�&��$#')"��* (�! (+��������^hMa0B{��LW^������� ����� �� �� �� �� �� ���������Ne0�8<G��Ki0g]WP���������������������� �� ���������@9JD���v/{��7�5I/������������������������^hMa0ByxK~rA����� �������� ����������
DB更新後に移動
順番を変える순서를 바꾼다.이 안은 트랜잭션 안이라는 가정
플레이어의 체력을 소비
플레이어의 경험치 업
에러가 발생하면 DB롤백
문제없으면 DB갱신. 경험치가 늘어난다.
플레이어의 체력을 마지막에 소비
DB갱신후로 이동
ユーザー視点で考える 2011~
変更前 2.体力だけが減り、経験値は増えない
エラーケース
1.体力も減らないが、経験値も増えない
유저의 시점에서 생각한다.에러 케이스
갱신전1.체력은 줄지않지만 경험치도 늘지 않는다. 2.체력만 줄고 겸험치는 늘지 않는다.
2011~
変更前 2.体力だけが減り、経験値は増えない
2.体力は減らないが、経験値は増える
エラーケース
1.体力も減らないが、経験値も増えない
エラーケース
1.体力も減らないが、経験値も増えない変更後
ユーザー視点で考える
ユーザーにはお得!!
유저의 시점에서 생각한다.에러 케이스
갱신전1.체력은 줄지 않지만 경험치도 늘지 않는다. 2.체력만 줄고 경험치는 늘지 않는다.
에러 케이스
갱신후1.체력은 줄지 않지만 경험치도 늘지 않는다. 2.체력은 줄지 않지만 경험치는 늘어난다.
유저에게는 득!
根本解決ではないが、回避のテクニック근본 해결은 아니지만 회피 테크닉
2011~
DBとKVSの整合性は難しい
学んだこと배운것
DB와KVS의 정합성은 어렵다.
さらにクエリを減らす더욱 쿼리를 줄인다.
2011~
TokyoTyrant
APサーバーRDS
ロードバランサ
memcached
構成구성
로드밸런서 App서버
マスターデータ
プレイヤー
プレイヤーのカードとか
2011~参照の多いデータ참조가 많은 데이터
마스터 데이터
플레이어
플레이어 카드 등
マスターデータ
プレイヤー
プレイヤーのカードとか
2011~
軽くする=キャッシュしかないと思ってた
参照の多いデータ참조가 많은 데이터
마스터 데이터
플레이어
플레이어 카드 등
가벼워진다 = 캐시하지 않는다로 생각했었음
更新したはずが昔のデータを参照している
キャッシュ削除忘れ
2011~あるあるキャッシュバグ자주 있는 캐시 버그
갱신했을터인 옛 데이터가 참조하고 있다.
캐시 삭제 까먹음
回避策회피책
2011~
��^hMa0X0UK��6G|���� ������� ���� ����� ����� �����������
更新箇所ではDBから取得갱신장소에는 DB로부터 취득
플레이어 데이터를 DB로부터 획득
DBで不整合を起こす率は減った
ただ、キャッシュから取得している所ではタイミング次第で表示ずれが起きる
2011~
��^hMa0X0UK��6G|���� ������� ���� ����� ����� �����������
更新箇所ではDBから取得갱신장소에는 DB로부터 취득
플레이어 데이터를 DB로부터 획득
DB에서 부정합을 일으킬 확률이 줄었다.
단지 캐시로부터 취득하고 있는 곳에서는 타이밍에따라 표시의 차이가 생긴다.
2011~
キャッシュを多用するとバグりやすいし、バグも見つけにくい
学んだこと배운것
캐시를 많이 쓰면 버그가 쉽게 발생하고 버그를 찾기도 힘들다.
2011~
KVSの基本的な使い方を学ぶ
2011年まとめ2011년 종합
KVS의 기본적인 사용 방법을 배움
前提
トライアル&エラー編2011~2012~
ギルドバトル編マスターデータバトルマッチング
最後にキャッシュRedis
まとめ
アジェンダアジェンダ아젠다
전제
시도&에러 편
길드 배틀편마스터 데이터 배틀 매칭
마지막으로캐시
정리2012~
ユーザーが順調に増えてきた유저가 순조롭게 늘기 시작했다.
2012~
おぉ、いいっすね!
○日後に広告打つんでさらにユーザー増えますよ!
さらに게다가0일 후에 광고를 때릴거니까 더욱 유저가 늘거에요!
오오 좋네요!
2012~
大丈夫です(震え声)
負荷大丈夫ですよね?フカ!
おぉ、いいっすね!
○日後に広告打つんでさらにユーザー増えますよ!
さらに게다가0일 후에 광고를 때릴거니까 더욱 유저가 늘거에요!
오오 좋네요!
부하 괜찮겠죠? 부하!
괜찮아요(떨리는 목소리)
2012~
Redis
Appサーバー
RDS
ロードバランサ
memcached
色々きつくなるかも여러여러 힘들어 질지도
로드밸런서
App서버
2012~
Redis
Appサーバー
RDS
ロードバランサ
memcached
追加は容易
負荷対策を考える부하 대책을 생각한다.
로드밸런서
App서버
추가는 쉽다
2012~
Redis
Appサーバー
RDS
ロードバランサ
memcached
使用方法の見直し
負荷対策を考える부하 대책을 생각한다.
로드밸런서
App서버
사용 방법을 재검토
問題はRDS문제는 RDS
관계형 DB
スケールアップサーバーそのものを増強。CPUとかメモリとか。増強する性能に限界がある
スケールアウトサーバーの台数を増やす事で処理性能をあげる
2012~負荷対策を考える부하 대책을 생각한다.
스케일 업 서버 그자체를 증강. CPU던지 메모리던지 증강하는 성능에는 한계가 있다.
스케일 아웃 서버 대수를 늘림으로써 처리성능을 올린다.
2012~
Redis
Appサーバー
RDS
ロードバランサ
memcached
色々きつくなるかも여러여러 힘들어 질지도
로드밸런서
App서버
どれくらいかがわからない。。어느정도일지 모르겠음…
スケールアップサーバーそのものを増強。CPUとかメモリとか。増強する性能に限界がある
スケールアウトサーバーの台数を増やす事で処理性能をあげる
2012~負荷対策を考える
採用
規模不明だし
부하 대책을 생각한다.
스케일 업 서버 그자체를 증강. CPU던지 메모리던지 증강하는 성능에는 한계가 있다.
스케일 아웃 서버 대수를 늘림으로써 처리성능을 올린다.
채용
규모 불명이니…
2012~
マスターデータ
ギルド
プレイヤー
イベント
初期構成초기 구성
마스터 데이터
길드
플레이어
이벤트
2012~
マスターデータ
ギルド
プレイヤー
イベント
スケールアウト(垂直)스케일 아웃(수직)
마스터 데이터
길드
플레이어
이벤트
2012~
マスターデータ
ギルド
イベント
スケールアウト(水平)
プレイヤー1 プレイヤー2 プレイヤー3 プレイヤー4
스케일 아웃(수평)
마스터 데이터
길드
플레이어1
이벤트
플레이어2 플레이어3 플레이어4
2012~
マスターデータ
スケールアウト(水平)
プレイヤー0
ギルド
イベント
プレイヤー1 プレイヤー2 プレイヤー3〃4 〃5 〃6 〃7〃8 〃9 〃10 〃11〃12 〃13 〃14 〃15
シャードを分割
스케일 아웃(수평)
마스터 데이터
길드
이벤트
플레이어0 플레이어1 플레이어2 플레이어3
샤드로 분할
2012~
��^hMa0��Cc[0P=2In7s�%!�+�&� ����,��"'%�"���-
����@\WSbw�@?=��A;.S`0ZBo��=�HK�FI������%!�+�&B��B�S`0Z����1 B�7|�l�I%!�+�&����#)"��&������'��%!�+�&� ������
シャードの決定
※実際のコードとは異なります
플레이어ID는 유니크하다는것이 전제
샤드의 결정
적당한 해시함수로 수치로 만들고, 샤드의 분할수로 나머지를 구한다.16 = player의 DB의 총 사드 수0~15값을 획득 가능
실제 코드와는 다릅니다.
うまくいった잘 되었다.
ようにみえたが。。。라고 보였으나…
2012~
マスターデータ
障害
プレイヤー0
ギルド
イベント
プレイヤー1 プレイヤー2 プレイヤー3〃4 〃5 〃6 〃7〃8 〃9 〃10 〃11〃12 〃13 〃14 〃15
장해
마스터 데이터
길드
이벤트
플레이어0 플레이어1 플레이어2 플레이어3
ある処理だけ分割が効いていなかった
初期化に入れていた空文字が特定のシャードを指していた
2012
��^hMa0��Cc[0P=2In7s�%!�+�&� ����,-
���6B�������%!�+�&� ������(�$�����!'���������B�z�����%!�+�&� �7--BEE�������%!�+�&����#)"��&������'��%!�+�&� ������
原因원인어느 처리부분만 분할이 되질 않았다.
초기화에 사용되었던 공백문자가 특정 샤드를 지시하고 있었다.플레이어ID는 유니크하다는것이 전제
뭔가의 조건:
잘못된 처리… player_id가 “”인 채
2012~どうなる?プライマリキーがAUTO INCREMENTのIDの場合、同構成のテーブルでも、各シャードで同じIDが存在する
player_idが空文字列で上書きされ、元々持っていたユーザーからは特定できなくなる
어떻게 됨?
Primary 키가 AUTO INCREMENT의 ID인 경우, 같은 구성의 테이블이라도 각 샤드에 같은 ID가 존재한다.
player_id가 공백문자열에 덮어쓰기되어져 원래 갖고있던 유저로부터 특정할수 없게됨
2012~どうなる?プライマリキーがAUTO INCREMENTのIDの場合、同構成のテーブルでも、各シャードで同じIDが存在する
player_idが空文字列で上書きされ、元々持っていたユーザーからは特定できなくなる
つまり、データが消える!!
어떻게 됨?
Primary 키가 AUTO INCREMENT의 ID인 경우, 같은 구성의 테이블이라도 각 샤드에 같은 ID가 존재한다.
player_id가 공백문자열에 덮어쓰기되어져 원래 갖고있던 유저로부터 특정할수 없게됨
즉 데이터 사라짐!!
2012~
プレイヤーの行動ログから、想定されるデータの洗い出し
ただ、残っていないログもあり、完全な復活は難しかった
復活부활
플레이어의 행동 로그로부터 상정되는 데이터를 다시 꺼냄
하지만 남아 있지 않은 로그도 있어서 완전한 부활은 어려웠다.
2012~
スケールアウトは原因の特定が困難な事も入念なデバッグと、ログを仕込もう
学んだこと배운것
스케일아웃은 원인 특정이 힘들다는 것을 유념해서 디버그와 로그를 심자.
引き続き分割(おまけ)계속해서 분할(덤)
2012~ユーザー数の減少。。유저수 감소…
2012~ユーザー数の減少。。負荷は下がる
유저수 감소…
부하는 준다.
2012~ユーザー数の減少。。
コストがかかる!!
負荷は下がる
が
부하는 준다.
하지만
비용이 든다!!
2012~
マスターデータ
RDSはコストかかる。。
プレイヤー0
ギルド
イベント
プレイヤー1 プレイヤー2 プレイヤー3〃4 〃5 〃6 〃7〃8 〃9 〃10 〃11〃12 〃13 〃14 〃15
RDS는 돈이 든다…
마스터 데이터
길드
이벤트
플레이어0 플레이어1 플레이어2 플레이어3
2012~
マスターデータ
統合
プレイヤー0
ギルド
イベント
プレイヤー1 プレイヤー2 プレイヤー3〃4 〃5 〃6 〃7〃8 〃9 〃10 〃11〃12 〃13 〃14 〃15
コスト削減
シャードそのまま
통합
마스터 데이터
길드
이벤트
플레이어0 플레이어1 플레이어2 플레이어3
샤드는 그대로
코스트 감소
逆を言えば역으로 말하면
2012~
マスターデータ
分割も楽
プレイヤー0
ギルド
イベント
プレイヤー1 プレイヤー2 プレイヤー3〃4 〃5 〃6 〃7〃8 〃9 〃10 〃11〃12 〃13 〃14 〃15
シャードそのまま
アプリのソースに変更いらず
분할도 쉽다.
마스터 데이터
길드
이벤트
플레이어0 플레이어1 플레이어2 플레이어3
샤드는 그대로
앱의 소스 수정 필요 없음
2012~
負荷が少なくとも、スケール可能な設計にしよう
学んだこと배운것
부하가 적어도 스케일 가능한 설계를 하자
2012~
DBの分割について学ぶ
2012年まとめ2012년 정리
DB의 분할에 대해 배움
ここまでが主なトライアル&エラー여기까지가 주요 트라이얼&에러
前提
トライアル&エラー編2011~2012~
ギルドバトル編マスターデータバトルマッチング
最後にキャッシュRedis
まとめ
アジェンダアジェンダ아젠다
전제
시도&에러 편
길드 배틀편마스터 데이터 배틀 매칭
마지막으로캐시
정리
集大成집대성
ギルドバトル
おぉ、いいっすね!
25人vs25人のギルドバトルをしたいんだけど
いつもの会話언제나의 대화25인VS25인 길드 배틀을
하고 싶은데요
오오 좋네요!
ギルドバトル
大丈夫です(震え声)
負荷大丈夫ですよね?フカ!
おぉ、いいっすね!
25人vs25人のギルドバトルをしたいんだけど
いつもの会話25인VS25인 길드 배틀을
하고 싶은데요
오오 좋네요!
부하 괜찮겠죠? 부하!
괜찮아요(떨리는 목소리)
언제나의 대화
ギルドvsギルド
プレイヤーにはHP、行動力、攻撃力等がある
行動力を消費して別のプレイヤーを攻撃する
対象プレイヤーは一人の時もあれば複数もある
与えたダメージはギルドにポイントとして入る
ギルドバトル例えばこんなバトル예를 들면 이런 배틀
길드vs길드
플레이어에게는 HP, 행동력, 공격력 수치가 있음
행동력을 소비해서 다른 플레이어를 공격한다.
대상 플레이어는 한사람일때도 있고 여럿도 있다.
데미지를 준것은 길드 포인트로 들어온다.
マスタデータ
マスターデータ
基本構成
プレイヤー0
ギルド
プレイヤー1 プレイヤー2 プレイヤー3〃4 〃5 〃6 〃7〃8 〃9 〃10 〃11〃12 〃13 〃14 〃15
기본 구성
마스터 데이터
길드
플레이어0 플레이어1 플레이어2 플레이어3
改善개선
マスタデータ
マスターデータ
基本構成
プレイヤー0
ギルド
プレイヤー1 プレイヤー2 プレイヤー3〃4 〃5 〃6 〃7〃8 〃9 〃10 〃11〃12 〃13 〃14 〃15
昔からあるこれ
기본 구성
마스터 데이터
길드
플레이어0 플레이어1 플레이어2 플레이어3
예전부터 있는 이것
今まではjsonをマスターDBにいれて参照
キャッシュがあれば、キャッシュから取得
参照度は一番高い
マスタデータマスターデータ
Appサーバーでのメモ化とかも
마스터 데이터
지금까지는 json을 마스터DB에 넣어서 참조
캐시가 있으면 캐시로부터 획득
참조도가 가장 높다.
App서버에서 메모리화 한것도
マスタデータ
Appサーバー マスターデータ
ロードバランサ
memcached
① Appサーバーのメモリにアクセス② キャッシュにアクセス③ DBにアクセス
①②
③
マスターデータ마스터 데이터
로드밸런서
App서버마스터데이터
1. App서버의 메모리에 접근 2. 캐시에 접근 3. DB에 접근
というのが2012まで이렇게 한게 2012년 까지
マスタデータ
Appサーバーマスターデータ
ロードバランサ
memcached
① Appサーバーにマスターデータがある!!
①
(マスターデータ)
マスターデータ마스터 데이터
로드밸런서
App서버 마스터 데이터 마스터데이터
1. App서버에 마스터 데이터가 있음!!
マスタデータどういうこと?
2. DBにアクセスしてデータを取得1. jsonの内容をDBに保存
以前
어떻다는 거야?
이전 1. json내용을 DB에 보존 2. DB에 접근해서 데이터 획득
マスタデータどういうこと?
2. DBにアクセスしてデータを取得1. jsonの内容をDBに保存
以前
jsonをAppサーバーに展開今
어떻다는 거야?
이전 1. json내용을 DB에 보존 2. DB에 접근해서 데이터 획득
지금 json을 App서버에서 전개
マスタデータ
Appサーバー
ロードバランサ全てがマスターデータを持つ
Appサーバーで完結するので高速
マスターデータ마스터 데이터
App서버
로드밸런서
App서버에서 완결하는것이 고속
전부다 마스터 데이터를 가짐
Appサーバーでのプロセスが大きくなる
が、約1年運用した結果でも今の所問題なし
マスタデータデメリット?
デプロイ時にメモリは解放されます
디메리트?
App서버의 프로세스가 커짐
하지만 약 1년 운용한 결과 지금까지는 문제 없음
디플로이시 메모리는 해방됩니다.
というわけで그래서
マスタデータ
マスターデータ
プレイヤー0
ギルド
プレイヤー1 プレイヤー2 プレイヤー3〃4 〃5 〃6 〃7〃8 〃9 〃10 〃11〃12 〃13 〃14 〃15
マスターデータのDBを使わなくなった
実際はソースの名残で一部使ってますが...
基本構成기본 구성
길드
플레이어0 플레이어1 플레이어2 플레이어3
실제는 기존 소스의 잔재로 일부 남아있지만…
마스터 데이터의 DB를 사용하지 않게 되었다
前提
トライアル&エラー編2011~2012~
ギルドバトル編マスターデータバトルマッチング
最後にキャッシュRedis
まとめ
アジェンダアジェンダ아젠다
전제
시도&에러 편
길드 배틀편마스터 데이터 배틀 매칭
마지막으로캐시
정리
今まで通りにやると。。。지금까지 처럼 하면…
バトル単体攻撃
プレイヤー0
ギルド
プレイヤー1 プレイヤー2 プレイヤー3〃4 〃5 〃6 〃7〃8 〃9 〃10 〃11〃12 〃13 〃14 〃15
Attack!!
1인 공격
길드
플레이어0 플레이어1 플레이어2 플레이어3
バトル複数攻撃
プレイヤー0
ギルド
プレイヤー1 プレイヤー2 プレイヤー3〃4 〃5 〃6 〃7〃8 〃9 〃10 〃11〃12 〃13 〃14 〃15
Attack!!x16
最大17箇所へのアクセス!
복수 공격
길드
플레이어0 플레이어1 플레이어2 플레이어3
최대 17장소에 접근!
さらに、ギルドバトルだと더욱이 길드 배틀이면
バトル同時に起きる可能性も
これでもまだ半分以下
동시에 일어날 가능성도
최대 17장소에 접근!최대 17장소에 접근!
이것도 아직 절반 이하
見るからにきつい보기에 힘들다
対象のDBが多いと、管理が難しくなる
アクセスが大変。というかしたくない
バトル問題点문제점
대상 DB가 많으면 관리가 힘들어 진다.
접근이 힘듬. 랄까 하고싶지 않음
対応策대응책
バトルギルドバトル専用DB
プレイヤー0
ギルド
プレイヤー1 プレイヤー2 プレイヤー3〃4 〃5 〃6 〃7〃8 〃9 〃10 〃11〃12 〃13 〃14 〃15
〃3〃5〃7
ギルドバトル1〃4〃6〃8
ギルドバトル2 New!!
길드 배틀 전용 DB
길드
플레이어0 플레이어1 플레이어2 플레이어3
길드 배틀1 길드 배틀2
バトル
ギルド
ギルドメンバーのレベル
ギルドメンバーの職業
ギルドメンバーのカード
ギルドメンバーのカードのレベルとかとか
必要なデータの選定필요한 데이터 선정
길드
길드 멤버의 레벨
길드 멤버의 직업
길드 멤버의 카드
길드 멤버의 카드의 레벨 등등
バトル
ギルド
バッチサーバー
バトルの数十分前にcronでバッチが流れる対戦ギルドの組み合わせを決める
プレイヤー
マッチング매칭
길드
플레이어
Batch서버
배틀 수십분 전에 cron으로 배치를 실행 대전 길드의 조합을 정한다.
バトル
ギルド
バッチサーバー
対戦の組み合わせごとにマッチングID(UUID)を発行する
��_WVjQ��Bpm"�(�� #�� ����)) ����
プレイヤー
マッチング매칭
길드
플레이어
Batch서버
대전 조합을 만들때마다 매칭ID(UUID)를 발행한다.
매칭 ID발행
バトル
ギルド
バッチサーバー
マッチングIDを元にギルドバトルDBを選択し、スナップショットを取る
スナップショット
分割特定はプレイヤーDBの特定と同じロジック
プレイヤー
ギルドバトル
マッチング매칭
길드
플레이어
Batch서버
매칭 ID를 기준으로 길드배틀DB를 선택해 스냅샷을 만든다.
길드 배틀
스냅샷
분할특정은 플레이어DB의 특정과 같은 로직
バトル閉じた戦い
ギルドA ギルドB
ギルドC
ギルドE
ギルドD
ギルドF
ギルドバトルDB
닫친 전투
길드A
길드C
길드E
길드B
길드D
길드F
길드 배틀 DB
うまくいった잘 되었다
が가
一つのDBに集まったとはいえ、同時に攻撃した場合に問題が起きる
レース・コンディション
バトルまだ問題が아직 문제가
하나의 DB에 모았다고 해도 동시에 공격한 경우에는 문제가 발생
레이스 컨디션
バトル
体力100 体力100
hikoに攻撃
mame hiko
save()
save()
mameに攻撃
レースコンディション
mameとhikoのデータを取得
mameとhikoのデータを取得
레이스 컨디션
mame와 hiko의 데이터를 획득
체력100
mame와 hiko의 데이터를 획득
hiko에게 공격
mame에게 공격
체력100
mame視点
ここで攻撃したから
hikoの体力は100未満(のはず)
hikoに攻撃
mame hiko
save()
save()
mameに攻撃
mameとhikoのデータを取得
mameとhikoのデータを取得
バトル
体力100 体力100
mame시점
mame와 hiko의 데이터를 획득
mame와 hiko의 데이터를 획득
hiko에게 공격
mame에게 공격
체력100
여기서 공격했으니
hiko의 체력은 100미만(일것)
체력100
バトル一方。。
体力100のデータを取得ここで攻撃
したから
hikoの体力は100未満(のはず)
hikoに攻撃
mame hiko
save()
save()
mameに攻撃
mameとhikoのデータを取得
mameとhikoのデータを取得
体力100のままsave
体力100 体力100
한편…
mame와 hiko의 데이터를 획득
mame와 hiko의 데이터를 획득
hiko에게 공격
mame에게 공격
체력100
여기서 공격했으니
hiko의 체력은 100미만(일것)
체력100
체력 100의 데이터 획득
체력 100인 채로 저장
バトル実際は。。
攻撃が無かった事に
なる!体力100のデータ
を取得ここで攻撃したから
hikoの体力は100未満(のはず)
hikoに攻撃
mame hiko
save()
save()
mameに攻撃
mameとhikoのデータを取得
mameとhikoのデータを取得
体力100のままsave
体力100 体力100
실제로는
mame와 hiko의 데이터를 획득
mame에게 공격
체력100
체력 100의 데이터 획득
체력 100인 채로 저장
공격이 없었던
것이 된다!
対応策대응책
バトル唯一の共通オブジェクト
ギルドA ギルドB
GuildBattleManagermatching_id
실제로는
길드A 길드B
更新処理は必ずManagerを通す
Managerで行ロックをかける
共通オブジェクトなのでデッドロック無し
バトル唯一の共通オブジェクト유일한 공통 오브젝트
갱신 처리는 반드시 Manager를 통한다.
매니저에서 행 록을 건다.
공통 오브젝트이므로 데드락은 없음
バトル
Manager
hikoに攻撃
mame hiko
save()
mameとhikoのデータを取得
一旦処理が止められ
順番体力100 体力100
순번
체력100 체력100
mame와 hiko의 데이터를 획득
hiko에게 공격
일단 처리가 멈춘다.
バトル
Manager
hikoに攻撃
mame hiko
save()
mameとhikoのデータを取得
save()
mameに攻撃
mameとhikoのデータを取得攻撃を受けた後のデータが
取得される
mameの処理終了後に流れ出す
順番体力100 体力100
mame와 hiko의 데이터를 획득
hiko에게 공격
mame와 hiko의 데이터를 획득
mame에게 공격
mame의 처리 종료후 움직인다.
체력100 체력100
공격을 받은 후의 데이터를 획득
순번
バトル
Manager
hikoに攻撃
mame hiko
save()
mameとhikoのデータを取得
save()
mameに攻撃
mameとhikoのデータを取得攻撃を受けた後のデータが
取得される
mameの処理終了後に流れ出す
トランザクションは必須
順番体力100 体力100
mame와 hiko의 데이터를 획득mame와 hiko의 데이터를 획득
mame에게 공격
mame의 처리 종료후 움직인다.
체력100 체력100
공격을 받은 후의 데이터를 획득
순번
트랜젝션은 필수
うまくいった잘 되었다.
本当に!정말로!
これで全てが終わったかに見えた이걸로 전부 끝났다고 보였다.
前提
トライアル&エラー編2011~2012~
ギルドバトル編マスターデータバトルマッチング
最後にキャッシュRedis
まとめ
アジェンダアジェンダ아젠다
전제
시도&에러 편
길드 배틀편마스터 데이터 배틀 매칭
마지막으로캐시
정리
マッチング
日ごとに増えるユーザー
日ごとに増えるデータ
日ごとに延びるマッチング時間
日ごとに短くなる睡眠時間
終わらないマッチング끝나지 않는 매칭
매일 늘어나는 유저
매일 늘어나는 데이터
매일 늘어나는 매칭 시간
매일 짧아지는 수면 시간
マッチング
ギルド
バッチサーバー
スナップショット
バッチサーバーから直接ギルドバトルDBにコピーしていた
プレイヤー
ギルドバトル
改善개선길드
플레이어
길드배틀
Batch서버
스냅샷
Batch서버로부터 직접 길드배틀 DB에 복사해왔다.
マッチング
ギルド
バッチサーバー
Redisに対戦ギルドの組み合わせのIDのみのリスト
を入れる
プレイヤー
改善
Redis
��OgZ��Bq}fTY�) !�� �'���������������� ����
개선
길드
플레이어 Batch서버
Redis에 대전 길드의 조합 ID만 리스트에 넣는다.
길드ID의 대전 리스트
マッチング
ギルド
バッチサーバー
Redisに対戦リストが入っていないかを常に問い合わせる
プレイヤー
改善
Redisジョブサーバー
개선
길드
플레이어Job서버
Redis에 대전 리스트가 들어있는지 아닌지 항상 물어본다.
マッチング
ギルド
バッチサーバー
Redisに入っている対戦リストから組み合わせのIDをポップし、並列でスナップショットを取る
プレイヤー
改善
Redis ジョブサーバー
ギルドバトル
スナップショット
[1,2][3,4][5,6]
Batch서버 Job서버 스냅샷
길드
플레이어
길드 배틀
Redis에 들어있는 대전 리스트로부터 조합ID를 POP해서 병렬로 스냅샷을 만든다.
개선
マッチング
Redisのデータ操作はアトミック性が保証されている
対戦リストが増えて処理が終わらなくなったらジョブサーバーを増やす
終わるマッチング끝나는 매칭
Redis의 데이터 조작은 원자성이 보장되어있다.
대전 리스트가 늘어서 처리가 끝나지 않게 되면 Job서버를 늘린다.
マッチング時間が5分の1に
俺が泣いた
매칭 시간이 1/5로
내가 울었다.
前提
トライアル&エラー編2011~2012~
ギルドバトル編マスターデータバトルマッチング
最後にキャッシュRedis
まとめ
アジェンダアジェンダ아젠다
전제
시도&에러 편
길드 배틀편마스터 데이터 배틀 매칭
마지막으로캐시
정리
最後に
余り使っていない
キャッシュが残るバグは今でもある
今までは重いクエリをごまかしていた
それよりもDBのindexを適切に張る
キャッシュ캐시
별로 사용하지 않음
캐시가 만드는 버그는 지금도 있음
지금까지는 무거운 쿼리를 어물어물 넘기고 있었다.
그것보다도 DB의 index를 적절하게 붙인다.
最後にJetprofiler
最近は使ってないかもしれないですが、、
重いクエリを検知してくれる
indexミスなのでアクセス障害が起きた時などに重宝した
무거운 쿼리를 검지해준다. index 미스등의 접근 장해가 일어났을때 중요했다.
최근에는 쓰이지 않을지도 모르겠지만…
ランキングや1日1回フラグなどに使用
expireを設定するとメモリの節約にもなる
消えても痛くないデータだが、なるべく永続的に残したいもの
最後にRedis
랭킹이나 1일1회 플래그등에 사용
expire를 설정하면 메모리 절약도 된다.
없어져도 아프지 않은 데이터지만 가능한 영속적으로 남기고 싶은 것들
前提
トライアル&エラー編2011~2012~
ギルドバトル編マスターデータバトルマッチング
最後にキャッシュRedis
まとめ
アジェンダアジェンダ아젠다
전제
시도&에러 편
길드 배틀편마스터 데이터 배틀 매칭
마지막으로캐시
정리
DBは規模によらずスケールアウト前提で
最初からKVSに手を出さないDBで効率が悪そうなもので考える
キャッシュは使わないという選択肢
まとめ まとめ
色々あるけどまとめきれず
정리
DB는 규모에 상관없이 스케일 아웃을 전제로
처음부터 KVS에 손을 대지 않는다. DB에서 효율이 나빠 보이는 걸로 생각한다.
캐시는 사용하지 않는다는 선택지여러가지 있지만
다 정리하지 못하고…
ご清聴ありがとうございました들어주셔서 감사합니다.
서버 미경험자가 소셜게임을 통해 알게된 서버에 대한것
サ〡バ〡未経験者がソ〡シャルゲ〡ムを通して知ったサ〡バ〡の事 http://www.slideshare.net/manabukoga39/ss-31004722
주식회사gumi 코가 마나부(古閑学)/@_mamehiko_
2014/2/8 게임서버공부회