게임 서버 1대에 동시접속자 1만명 넣기
DESCRIPTION
프라우드넷에서 MMO 게임 서버 프로세스 1개에서 멀티 코어를 효율적으로 사용하기 위해 어떠한 기술을 구사했는지 소개합니다.TRANSCRIPT
![Page 1: 게임 서버 1대에 동시접속자 1만명 넣기](https://reader033.vdocuments.site/reader033/viewer/2022061503/5588f81cd8b42a04688b456d/html5/thumbnails/1.jpg)
서버 프로세스 1 개에 동시접속자 1 만명 넣기
배현직Nettention
![Page 2: 게임 서버 1대에 동시접속자 1만명 넣기](https://reader033.vdocuments.site/reader033/viewer/2022061503/5588f81cd8b42a04688b456d/html5/thumbnails/2.jpg)
내 소개
突击 1941
• 1995 년부터 게임회사에서 근무• 토끼와 거북이 3D, Menticide 격투
게임• 오즈 월드 , 블리츠 1941
• Game Programming Gems 5,7
• ProudNet• KGC 2010, 2011, 독일 Quo Vadis
2012, 중국 CGDC 2012, 일본 CEDEC 에서 강연
![Page 3: 게임 서버 1대에 동시접속자 1만명 넣기](https://reader033.vdocuments.site/reader033/viewer/2022061503/5588f81cd8b42a04688b456d/html5/thumbnails/3.jpg)
• 로비형 MO 게임 – 쉽게 해결– 서버 머신 증설만 하면 됨
RoomServer
RoomServer
RoomServer
RoomServer
RoomServer
RoomServer
RoomServer
RoomServer
![Page 4: 게임 서버 1대에 동시접속자 1만명 넣기](https://reader033.vdocuments.site/reader033/viewer/2022061503/5588f81cd8b42a04688b456d/html5/thumbnails/4.jpg)
• 월드 개수가 고정된 MMO 게임– 쉽게 해결– CPU 개수만큼 월드 서버들을 띄우면 됨– 단 , 1 개 CPU 가 1 개 월드를 처리할 수 있으면
ZoneServer
ZoneServer
ZoneServer
ZoneServer
ZoneServer
ZoneServer
ZoneServer
ZoneServer
![Page 5: 게임 서버 1대에 동시접속자 1만명 넣기](https://reader033.vdocuments.site/reader033/viewer/2022061503/5588f81cd8b42a04688b456d/html5/thumbnails/5.jpg)
• 월드 서버 1 개가 CPU 한 개 사용량을 넘어가면 ?
• 서버 프로세스 로직의 병렬화가 필요 !
Zone Server
Zone Server
![Page 6: 게임 서버 1대에 동시접속자 1만명 넣기](https://reader033.vdocuments.site/reader033/viewer/2022061503/5588f81cd8b42a04688b456d/html5/thumbnails/6.jpg)
10,000 소켓 쉬움
그리고 일대일 통신 그럭저럭
그리고 일대다 통신 빡셈
Player_Move
Player_ShowM
ove
Player_ShowM
ove
Player_ShowM
ove
MMO 게임 서버는 이러함 !
![Page 7: 게임 서버 1대에 동시접속자 1만명 넣기](https://reader033.vdocuments.site/reader033/viewer/2022061503/5588f81cd8b42a04688b456d/html5/thumbnails/7.jpg)
용어 정의
![Page 8: 게임 서버 1대에 동시접속자 1만명 넣기](https://reader033.vdocuments.site/reader033/viewer/2022061503/5588f81cd8b42a04688b456d/html5/thumbnails/8.jpg)
Lock(X)
class MyType{ CritSec m_critSec; int a;}
MyType X;
void Something(){ CritSecLock lock(X.m_critSec); ...; }
![Page 9: 게임 서버 1대에 동시접속자 1만명 넣기](https://reader033.vdocuments.site/reader033/viewer/2022061503/5588f81cd8b42a04688b456d/html5/thumbnails/9.jpg)
컨텍스트 스위치
Thread 2Thread 1
컨텍스트 스위치
컨텍스트 스위치
![Page 10: 게임 서버 1대에 동시접속자 1만명 넣기](https://reader033.vdocuments.site/reader033/viewer/2022061503/5588f81cd8b42a04688b456d/html5/thumbnails/10.jpg)
Thread 1{ lock(A); A = A+1; lock(A);}
Thread 2{ lock(A); A = A * 2; unlock(A);}
Object A
Contention
CPU 1 CPU 2
CPU cache sharing!
![Page 11: 게임 서버 1대에 동시접속자 1만명 넣기](https://reader033.vdocuments.site/reader033/viewer/2022061503/5588f81cd8b42a04688b456d/html5/thumbnails/11.jpg)
granulation
A
B
C
D
A
B
C
D
리소스 분할
![Page 12: 게임 서버 1대에 동시접속자 1만명 넣기](https://reader033.vdocuments.site/reader033/viewer/2022061503/5588f81cd8b42a04688b456d/html5/thumbnails/12.jpg)
우리가 겪은 문제
![Page 13: 게임 서버 1대에 동시접속자 1만명 넣기](https://reader033.vdocuments.site/reader033/viewer/2022061503/5588f81cd8b42a04688b456d/html5/thumbnails/13.jpg)
목표
CPU %
동시접속자 + 트래픽
1 개 서버 프로세스가 모든 CPU 를 적절히
활용해야
![Page 14: 게임 서버 1대에 동시접속자 1만명 넣기](https://reader033.vdocuments.site/reader033/viewer/2022061503/5588f81cd8b42a04688b456d/html5/thumbnails/14.jpg)
𝑟=1
(1−𝑃 )+ 𝑃𝑆
처리의 40 %가 병렬화 (P = 0.4)2 배 성능으로 병렬화 (S = 2)
그러나 전체 성능은 겨우 25% 향상(r = 1.25)
Amdahl 의 법칙
![Page 15: 게임 서버 1대에 동시접속자 1만명 넣기](https://reader033.vdocuments.site/reader033/viewer/2022061503/5588f81cd8b42a04688b456d/html5/thumbnails/15.jpg)
Amdahl 의 법칙저주
빈공간이 Amdahl 의 저주
![Page 16: 게임 서버 1대에 동시접속자 1만명 넣기](https://reader033.vdocuments.site/reader033/viewer/2022061503/5588f81cd8b42a04688b456d/html5/thumbnails/16.jpg)
과거에 우리의 상황• 우리가 이러한 것들을 무시했다면
– 하위 호환성– 안정성
• 고객사들이 곤란했을 상황 !
마비노기 영웅전 마계촌 online S4 리그 러스티 하츠
그리고 다른 많은 고객사들
![Page 17: 게임 서버 1대에 동시접속자 1만명 넣기](https://reader033.vdocuments.site/reader033/viewer/2022061503/5588f81cd8b42a04688b456d/html5/thumbnails/17.jpg)
결국 해결 ! 어떻게 ?
![Page 18: 게임 서버 1대에 동시접속자 1만명 넣기](https://reader033.vdocuments.site/reader033/viewer/2022061503/5588f81cd8b42a04688b456d/html5/thumbnails/18.jpg)
APPLE MMLXXX][
]10 프로파일&분석]20 테스트 코딩과 엎어버리기의 반복 ]30 설계 문서 작성]40 구현]50 GOTO 10
]RUN
![Page 19: 게임 서버 1대에 동시접속자 1만명 넣기](https://reader033.vdocuments.site/reader033/viewer/2022061503/5588f81cd8b42a04688b456d/html5/thumbnails/19.jpg)
APPLE MMLXXX][
]10 프로파일&분석]20 테스트 코딩과 엎어버리기의 반복 ]30 설계 문서 작성]40 구현]50 GOTO 10
]RUN
![Page 20: 게임 서버 1대에 동시접속자 1만명 넣기](https://reader033.vdocuments.site/reader033/viewer/2022061503/5588f81cd8b42a04688b456d/html5/thumbnails/20.jpg)
![Page 21: 게임 서버 1대에 동시접속자 1만명 넣기](https://reader033.vdocuments.site/reader033/viewer/2022061503/5588f81cd8b42a04688b456d/html5/thumbnails/21.jpg)
가장 심한 병목• 비동기 socket I/O 함수 호출–WSASend, WSASendTo–WSARecv, WSARecvFrom
![Page 22: 게임 서버 1대에 동시접속자 1만명 넣기](https://reader033.vdocuments.site/reader033/viewer/2022061503/5588f81cd8b42a04688b456d/html5/thumbnails/22.jpg)
send(), recv() ( 블러킹이 일어남 )WSASend, WSARecv ( 블러킹 안 일어남 )
무지무지 긴 idle 시간짧은 CPU 시간
Q. 잠깐 , IOCP 가 최고 빠른 것 아니었어 ?
A. 최고 빠른 것 맞음 .다만 , 사용자 루틴에 비해 느리다는 것이 함정 .
그럼에도 불구하고이것이 병목 !
![Page 23: 게임 서버 1대에 동시접속자 1만명 넣기](https://reader033.vdocuments.site/reader033/viewer/2022061503/5588f81cd8b42a04688b456d/html5/thumbnails/23.jpg)
APPLE MMLXXX][
]10 프로파일&분석]20 테스트 코딩과 엎어버리기의 반복 ]30 설계 문서 작성]40 구현]50 GOTO 10
]RUN
![Page 24: 게임 서버 1대에 동시접속자 1만명 넣기](https://reader033.vdocuments.site/reader033/viewer/2022061503/5588f81cd8b42a04688b456d/html5/thumbnails/24.jpg)
![Page 25: 게임 서버 1대에 동시접속자 1만명 넣기](https://reader033.vdocuments.site/reader033/viewer/2022061503/5588f81cd8b42a04688b456d/html5/thumbnails/25.jpg)
A 를 스퀴즈
B 를 분할하기
![Page 26: 게임 서버 1대에 동시접속자 1만명 넣기](https://reader033.vdocuments.site/reader033/viewer/2022061503/5588f81cd8b42a04688b456d/html5/thumbnails/26.jpg)
Main
Remote host
P2P pair
P2P group
Etc.
이것을 스퀴즈해야 !
![Page 27: 게임 서버 1대에 동시접속자 1만명 넣기](https://reader033.vdocuments.site/reader033/viewer/2022061503/5588f81cd8b42a04688b456d/html5/thumbnails/27.jpg)
Main
Remote host
P2P pair
P2P group
Etc.
![Page 28: 게임 서버 1대에 동시접속자 1만명 넣기](https://reader033.vdocuments.site/reader033/viewer/2022061503/5588f81cd8b42a04688b456d/html5/thumbnails/28.jpg)
![Page 29: 게임 서버 1대에 동시접속자 1만명 넣기](https://reader033.vdocuments.site/reader033/viewer/2022061503/5588f81cd8b42a04688b456d/html5/thumbnails/29.jpg)
심장 심장 + 폐
뇌사 환자
![Page 30: 게임 서버 1대에 동시접속자 1만명 넣기](https://reader033.vdocuments.site/reader033/viewer/2022061503/5588f81cd8b42a04688b456d/html5/thumbnails/30.jpg)
Remote Ob-ject
Joined P2P group stateP2P pair relationship
Traffic status…
Socket handleSend buffer
Receive bufferOverlapped I/O status
…
Main
![Page 31: 게임 서버 1대에 동시접속자 1만명 넣기](https://reader033.vdocuments.site/reader033/viewer/2022061503/5588f81cd8b42a04688b456d/html5/thumbnails/31.jpg)
Remote Ob-ject
Joined P2P group stateP2P pair relationship
Traffic status…
Socket handleSend buffer
Receive bufferOverlapped I/O status
…
Main
![Page 32: 게임 서버 1대에 동시접속자 1만명 넣기](https://reader033.vdocuments.site/reader033/viewer/2022061503/5588f81cd8b42a04688b456d/html5/thumbnails/32.jpg)
잦은 잠금은 빡셈 !
안 잠궈진 객체가 살아있음을 어떻게 보증해 ?
![Page 33: 게임 서버 1대에 동시접속자 1만명 넣기](https://reader033.vdocuments.site/reader033/viewer/2022061503/5588f81cd8b42a04688b456d/html5/thumbnails/33.jpg)
Contention 과 잠금 비용과의 관계
Contention-less lockContention-
less lockContention-less lock
Contention-inten-sive lock<
Contention-less lock
Contention-less lockContention-
less lockContention-less lock
Contention-less lock
Contention-less lockContention-
less lockContention-less lock
Contention-less lock
Contention-less lock
![Page 34: 게임 서버 1대에 동시접속자 1만명 넣기](https://reader033.vdocuments.site/reader033/viewer/2022061503/5588f81cd8b42a04688b456d/html5/thumbnails/34.jpg)
잠금 방법에 따른 비용
non-blocking locknon-blocking
locknon-blocking lock
Blocking lock<non-blocking
lock
non-blocking locknon-blocking
locknon-blocking lock
non-blocking lock
non-blocking locknon-blocking
locknon-blocking lock
non-blocking lock
non-blocking lock
![Page 35: 게임 서버 1대에 동시접속자 1만명 넣기](https://reader033.vdocuments.site/reader033/viewer/2022061503/5588f81cd8b42a04688b456d/html5/thumbnails/35.jpg)
원자적 실행 명령어(Atomic operations)
• InterlockedIncrement• InterlockedExchange• InterlockedCompareExchange• InterlockedBlahBlah• InterlockedBlahBlah• InterlockedBlahBlah• InterlockedBlahBlah
![Page 36: 게임 서버 1대에 동시접속자 1만명 넣기](https://reader033.vdocuments.site/reader033/viewer/2022061503/5588f81cd8b42a04688b456d/html5/thumbnails/36.jpg)
Thread 1{ Get B from A; lock(B); do(B);}
Thread 2{ Get B from A; delete B;}
Object A
Object BObject B
CRASH!
![Page 37: 게임 서버 1대에 동시접속자 1만명 넣기](https://reader033.vdocuments.site/reader033/viewer/2022061503/5588f81cd8b42a04688b456d/html5/thumbnails/37.jpg)
Thread 1{ Get B from A; B.use_count+1; lock(B); do(B); unlock(B); B.use_count-1;}
Thread 2{ Get B from A; if(B.use_count=0) delete B;}
Object A
Object B Keep!
![Page 38: 게임 서버 1대에 동시접속자 1만명 넣기](https://reader033.vdocuments.site/reader033/viewer/2022061503/5588f81cd8b42a04688b456d/html5/thumbnails/38.jpg)
Main
Remote host
P2P pair
P2P group Etc.
비파괴 보장
![Page 39: 게임 서버 1대에 동시접속자 1만명 넣기](https://reader033.vdocuments.site/reader033/viewer/2022061503/5588f81cd8b42a04688b456d/html5/thumbnails/39.jpg)
Before squeeze
After squeeze
Lock(main)
Lock(remote#1)
Lock(main)
Lock(remote#2)
Lock(main)
Lock(remote#1)
Lock(main)
Lock(remote#2)
Lock(main)
Lock(remote#3)
Lock(main)
Lock(remote#4)
Amdahl’s Curse
Amdahl’s Curse
Am-dahl’s Curse
Am-dahl’s Curse
Am-dahl’s Curse
Lock(main)
![Page 40: 게임 서버 1대에 동시접속자 1만명 넣기](https://reader033.vdocuments.site/reader033/viewer/2022061503/5588f81cd8b42a04688b456d/html5/thumbnails/40.jpg)
APPLE MMLXXX][
]10 프로파일&분석]20 테스트 코딩과 엎어버리기의 반복 ]30 설계 문서 작성]40 구현]50 GOTO 10
]RUN
![Page 41: 게임 서버 1대에 동시접속자 1만명 넣기](https://reader033.vdocuments.site/reader033/viewer/2022061503/5588f81cd8b42a04688b456d/html5/thumbnails/41.jpg)
대부분의 경우• Lock(main)• r.use_count+1• Unlock(main)• Lock(r)• work(r)• Unlock(r)• r.use_count-1
Main
Remote host
P2P pair
P2P group
비파괴 보장
![Page 42: 게임 서버 1대에 동시접속자 1만명 넣기](https://reader033.vdocuments.site/reader033/viewer/2022061503/5588f81cd8b42a04688b456d/html5/thumbnails/42.jpg)
좀비 오브젝트 파괴• Lock(main)• if r.use_count=0
&& r 의 io 가 더 이상 없음이 체크되어 있으면
• r 제거• 그렇지 않으면 , 다음
기회에 다시 시도
Main
Remote host
P2P pair
P2P group
USE COUNT = 0?
![Page 43: 게임 서버 1대에 동시접속자 1만명 넣기](https://reader033.vdocuments.site/reader033/viewer/2022061503/5588f81cd8b42a04688b456d/html5/thumbnails/43.jpg)
컨텍스트 스위치를 줄이지 않은 루프
Main
Remote 1 Remote 2 Remote 3
CPU time
Idle time!!
CPU time
CPU time
CONTEXT SWITCH!
![Page 44: 게임 서버 1대에 동시접속자 1만명 넣기](https://reader033.vdocuments.site/reader033/viewer/2022061503/5588f81cd8b42a04688b456d/html5/thumbnails/44.jpg)
컨텍스트 스위치를 줄인 루프
Main
Remote 1 Remote 2 Remote 3
CPU time
CPU time
CPU time
NO CONTEXT SWITCH!(if lucky)
![Page 45: 게임 서버 1대에 동시접속자 1만명 넣기](https://reader033.vdocuments.site/reader033/viewer/2022061503/5588f81cd8b42a04688b456d/html5/thumbnails/45.jpg)
1 개 이상의 상대에의 송신 걸기
• lock(main)• 각 r 에 대해 , r.use_count+1• unlock(main)• 각 r 에 대해 , non-blocking
lock 을 수행• Lock(r) 성공시 , r 의 비동기
송신을 건 후• Lock(r) 성공시 unlock(r) &
r.use_count-1• 실패한 r 들에 대해서만 다시 위
과정을 반복 . 단 , 첫번째 항목에 대해서는 blocking lock 을 수행해야 .
Main
Remote host
P2P pair
P2P group
비파괴 보장
![Page 46: 게임 서버 1대에 동시접속자 1만명 넣기](https://reader033.vdocuments.site/reader033/viewer/2022061503/5588f81cd8b42a04688b456d/html5/thumbnails/46.jpg)
송신 완료시
• GetQueuedComple-tionStatus returns r
• r.use_count+1• lock(r)• r 의 비동기 송신을 걸고• unlock(r)• r.use_count-1
Main
Remote host
P2P pair
P2P group
비파괴 보장
![Page 47: 게임 서버 1대에 동시접속자 1만명 넣기](https://reader033.vdocuments.site/reader033/viewer/2022061503/5588f81cd8b42a04688b456d/html5/thumbnails/47.jpg)
수신 완료시
• GetQueuedCompletionStatus returns r
• r.use_count+1• lock(r)• Extract messages• Unlock(r)• Lock(main)• Process messages• Unlock(main)• lock(r)• r 의 비동기 수신을 걸고• Unlock(r)• r.use_count-1
Main
Remote host
P2P pair
P2P group
비파괴 보장
![Page 48: 게임 서버 1대에 동시접속자 1만명 넣기](https://reader033.vdocuments.site/reader033/viewer/2022061503/5588f81cd8b42a04688b456d/html5/thumbnails/48.jpg)
APPLE MMLXXX][
]10 프로파일&분석]20 테스트 코딩과 엎어버리기의 반복 ]30 설계 문서 작성]40 구현]50 GOTO 10
]RUN
![Page 49: 게임 서버 1대에 동시접속자 1만명 넣기](https://reader033.vdocuments.site/reader033/viewer/2022061503/5588f81cd8b42a04688b456d/html5/thumbnails/49.jpg)
테스트 케이스• 운 좋게도 우리는 이미 이런게 있었다– 자체 개발한 테스트 시스템– 여러가지 스트레스 테스트 앱• MMO case• P2P casual game case • P2P super peer case
![Page 50: 게임 서버 1대에 동시접속자 1만명 넣기](https://reader033.vdocuments.site/reader033/viewer/2022061503/5588f81cd8b42a04688b456d/html5/thumbnails/50.jpg)
• 자체제작된 자동화된 유닛 테스트• 여러 인터넷 공유기• 여러 가상 머신들
Belkin G WirelessTPLINK WR304G+TPLINK V108COSY BR674WLIPTIME G104MIPTIME Q304BUFFALO AIRSTATION
UNICORN WB1000
NETGEAR WGR614V9
DLINK DIR300LINKSYS WRV200MERCURY MR804TPLINK TLR410+TPLINK TLR402Samsung SWP1000
ZIO V10IPTIME N5004NEXT 915VSMC WBR14-G2ZYXEL NBG417NLINKSYS WRT54G2
AZTECH WL830RT4
ASUS RX3041DLINK DIR600PROLINK WNR1004LG-1000
리그레션 테스트용For regress test
![Page 51: 게임 서버 1대에 동시접속자 1만명 넣기](https://reader033.vdocuments.site/reader033/viewer/2022061503/5588f81cd8b42a04688b456d/html5/thumbnails/51.jpg)
스트레스 테스트
Windows 2008 Server x64Xeon CPU
![Page 52: 게임 서버 1대에 동시접속자 1만명 넣기](https://reader033.vdocuments.site/reader033/viewer/2022061503/5588f81cd8b42a04688b456d/html5/thumbnails/52.jpg)
Before
![Page 53: 게임 서버 1대에 동시접속자 1만명 넣기](https://reader033.vdocuments.site/reader033/viewer/2022061503/5588f81cd8b42a04688b456d/html5/thumbnails/53.jpg)
after
![Page 54: 게임 서버 1대에 동시접속자 1만명 넣기](https://reader033.vdocuments.site/reader033/viewer/2022061503/5588f81cd8b42a04688b456d/html5/thumbnails/54.jpg)
APPLE MMLXXX][
]10 프로파일&분석]20 테스트 코딩과 엎어버리기의 반복 ]30 설계 문서 작성]40 구현]50 GOTO 10
]RUN
![Page 55: 게임 서버 1대에 동시접속자 1만명 넣기](https://reader033.vdocuments.site/reader033/viewer/2022061503/5588f81cd8b42a04688b456d/html5/thumbnails/55.jpg)
마무리
![Page 56: 게임 서버 1대에 동시접속자 1만명 넣기](https://reader033.vdocuments.site/reader033/viewer/2022061503/5588f81cd8b42a04688b456d/html5/thumbnails/56.jpg)
평소에 공부하자• 컨텍스트 스위치 주의• 컨텐션 주의• 커널 API 호출 주의
![Page 57: 게임 서버 1대에 동시접속자 1만명 넣기](https://reader033.vdocuments.site/reader033/viewer/2022061503/5588f81cd8b42a04688b456d/html5/thumbnails/57.jpg)
공부한 것을 실무에서 이렇게• 최적화는 가급적 마지막에
코드 프로필러를 꼭 써야• 리소스 분할 기법• 스퀴징• 컨텍스트 스위치가 적은 루프
![Page 58: 게임 서버 1대에 동시접속자 1만명 넣기](https://reader033.vdocuments.site/reader033/viewer/2022061503/5588f81cd8b42a04688b456d/html5/thumbnails/58.jpg)
보너스 : 프라우드넷 소개
![Page 59: 게임 서버 1대에 동시접속자 1만명 넣기](https://reader033.vdocuments.site/reader033/viewer/2022061503/5588f81cd8b42a04688b456d/html5/thumbnails/59.jpg)
프라우드넷 3 가지 구성 요소
P2P
C/S
DB cache
Server-to-serverLANClient-to-server
WAN
![Page 60: 게임 서버 1대에 동시접속자 1만명 넣기](https://reader033.vdocuments.site/reader033/viewer/2022061503/5588f81cd8b42a04688b456d/html5/thumbnails/60.jpg)
프라우드넷 기본 사용 예DB cache
Server-to-serverLANClient-to-server
WAN
Connect()
JoinP2PGroup()
MyMessage(sendTo, a,b,c);
LoadData()UniUpdateData()
JoinP2PGroup()