작성
·
209
0
안녕하세요, 강의 서버를 테스트 툴로 유저를 유입시킨뒤 채팅 BroadCast 테스트를 해봤습니다.
당연한 것이겠지만 유저 많아질 수록 _sendQueue.push 의 수가 _sendQueue.pop 보다 많아지면서 메모리가 계속 올라가는 이슈가 생기고, 또 WRITE_LOCK 경합에서 pop 이 잘 이루어 지지않아 패킷 send 에도 지장을 주는 현상이 발생됩니다.
테스트툴은 100 Msec 마다 N 명의 유저가 계속 채팅을 하는 방식으로 테스트 하였습니다.
위에서 말한 이슈는 어떻게 해결하면 좋을까요 ? 어떤 노하우가 있을지 궁금합니다 !
답변 1
1
네 그게 바로 MMO의 어려움입니다.
[XX엔진 동접 20만명 달성!!] 이렇게 서버 엔진을 홍보하지만
현실은 동접이 몇명인지가 중요한게 아니라
같은 공간에 몇 명이 있는지가 관건입니다.
(broadcast 부하는 N^2이기 때문)
대략적으로 500명이 넘어가면 아주아주 힘들어지기 때문에,
1000vs1000 RvR을 홍보하는 게임은 많지만
생각보다 실제로 그 정도 대규모 전투를 성공적으로 서비스한 게임은 많이 없습니다.
관련해서 다음과 같은 방법을 고려할 수 있습니다.
1.
경합이 아주 많아질 때는 LockFreeQueue가 아주 약간 이점이 있어서
(push, pop이 서로 영향을 주지 않기 때문)
고려해볼만 합니다.
2.
컨텐츠 코드단에서 패킷을 최대한 뭉쳐 보내는 것도 방법입니다.
가령 broadcast되는 패킷들은 사실상 동일한 공간에 있는 사람들이 모두 봐야하는 것이기에,
이를 쌓아두다가 한 번에 serialize한 다음, 그 뭉탱이 결과를 통으로
큐에다 밀어넣는 식으로 하면 지나친 경합을 피할 수 있겠죠.
3.
그러나 정말 정말로 1000vs1000 같은 대규모 전투를 생각한다면,
일반적인 방법으로는 부족하고 보통 그런 게임을 만드는 프로젝트 발표 내용을 보면
broadcast를 전담하는 서버를 앞단에 더 두는 경우가 많습니다.
[전송 서버1] [전송 서버2] [전송 서버3] ...
[로직 서버]
요런 느낌으로 묶여 있고 클라는 로직 서버가 아니라
전송 서버 1, 2, 3... 에 붙는 것이죠.
서버 1, 2, 3...은 로직 서버와 소통을 하면서 동일한 세상을 유지해야 하기 때문에
제작 난이도가 급격히 올라갑니다.
2번을 조금 변형해서 캐시와 비슷하게 Queue 를 하나 더 만들어서 push 해 놓고
지정된 사이즈가 되었을 때야 이 Queue 에 있는 것을 _sendQueue 로 이전하는 방식은 어떨까요 ?
그러면 WRITE_LOCK 경쟁은 한번만 취하면서도 여러 데이터를 _sendQueue 에 많이 쌓을수 있을거라 생각합니다.
물론 여러가지 변종이 있긴 하지만, 그 다음 문제는 그럼 '언제 누가' 이전해줄로 변경됩니다.
너무 늦으면 렉이 걸릴테고.. 그리고
항상 패킷을 누군가가 보내는게 아니라 국제 미아가 될 수도 있고 골치가 아픈 부분이 있습니다.
하지만 그렇게 계속 개선점을 찾아나서는게 아주 바람직하다 봅니다.
이런 저런 헤딩을 해보고 테스트를 해보시는 것이 정말 필요합니다.
(저도 아주 많은 삽질을 했었어요)
와.. 역시 약간 원초적인? 문제였긴 하네요 ㅠㅠ 위에서 말씀하신 조언 너무 감사드립니다. 이것을 어떻게 해결할지에 대해 잘 고민해서 적용해보도록 하겠습니다 !