Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

[야생의 땅: 듀랑고] 서버 아키텍처 Vol. 2 (자막)

32,371 views

Published on

NDC16에서 발표했습니다. 원고를 포함한 추가 발표자료는 다음 주소에서 확인하실 수 있습니다: http://j.mp/sub-ndc16

Published in: Software

[야생의 땅: 듀랑고] 서버 아키텍처 Vol. 2 (자막)

  1. 1. <야생의 땅: 듀랑고> 서버 아키텍처 Vol. 2 넥슨 • 왓 스튜디오 • 이흥섭 TOC #1 멀리 보기 서버 아키텍처 아웃라인 #2 들여다보기 부동산 신기루 전투 공방 합 #3 돌아보기 1, 2차 LBT 회고
  2. 2. <야생의 땅: 듀랑고> 서버 아키텍처 Vol. 2 넥슨 • 왓 스튜디오 • 이흥섭 TOC #1 멀리 보기 서버 아키텍처 아웃라인 #2 들여다보기 부동산 신기루 전투 공방 합 #3 돌아보기 1, 2차 LBT 회고 안녕하세요. 재작년에 이어서 이번에도 <야생의 땅: 듀랑고> 서버 아키텍처를 주제로 발표하는
  3. 3. 이흥섭 넥슨 • 왓 스튜디오 • 서비스파트장 넥슨 왓 스튜디오의 서비스 파트장 이흥섭입니다. 반갑습니다.
  4. 4. 2011-2013 <카트라이더 대시 & 코인러시> 2013- <야생의 땅: 듀랑고> 저는 NDC가 처음 개방된 2011년에 넥슨에 합류해서 <카트라이더 대시 & 코인러시> 시리즈를 거쳐
  5. 5. 2011-2013 <카트라이더 대시 & 코인러시> 2013- <야생의 땅: 듀랑고> 지금은 <야생의 땅: 듀랑고>의 서버 아키텍처를 담당하고 있습니다.
  6. 6. what-studio/profiling 2,380+ sublee/trueskill 215+ sublee/hangulize 100+ sublee 그리고 틈틈이 오픈소스 활동도 하고 있는데요
  7. 7. what-studio/profiling 2,380+ sublee/trueskill 215+ sublee/hangulize 100+ sublee 한 번 제가 만든 프로젝트 중에서 별이 100개 이상 찍힌 것만 모아봤습니다.
  8. 8. what-studio/profiling 2,380+ sublee/trueskill 215+ sublee/hangulize 100+ sublee 혹시 GitHub 하시는 분 계시면 계정 sublee를 팔로우하고 제 프로젝트에 별도 찍어주시면 감사하겠습니다.
  9. 9. 본격적인 발표에 앞서 저희 프로젝트를 먼저 소개해드릴게요. 저희가 만들고 있는 <야생의 땅: 듀랑고>는
  10. 10. 공룡이나 코끼리 조상 같은 고생물들이 사는 땅을 개척하면서
  11. 11. 거기서의 생활을 즐기는 모바일 MMORPG입니다.
  12. 12. 사냥, 채집, 건설 같은 플레이어의 행동 하나하나가 듀랑고 세계에 영구적인 변화를 남기게 되는 오픈월드 게임이죠.
  13. 13. A 서버군 B 서버군 단일 서버군 듀랑고 서버 아키텍처에는 마비노기 영웅전처럼 서버군 구분이 없습니다.
  14. 14. A 서버군 B 서버군 단일 서버군 게임을 시작하거나 접속할 때 자기가 속할 서버군을 고르지 않아도 되는 거죠.
  15. 15. 다중 채널 단일 채널 단일 서버군이던 마비노기 영웅전에서 조금 더 나아가 저희는 채널도 구분하지 않는데요
  16. 16. 그래서 가까운 장소에만 있으면 모든 플레이어와 서로 만날 수 있습니다.
  17. 17. 무한한 공간 영속적 세계 단일 채널 고 가용성 저희 서버 아키텍처는 이런 듀랑고의 게임플레이를 지원하기 위해
  18. 18. 무한한 공간 영속적 세계 단일 채널 고 가용성 무한한 공간, 단일 채널, 영속적 세계, 고 가용성 같은 목표를 세우고 도전해오고 있습니다.
  19. 19. #1 멀리 보기 #2 들여다보기 #3 돌아보기 오늘 발표에선 듀랑고 서버 아키텍처가 저희의 목표를 어떻게 달성해왔고
  20. 20. #1 멀리 보기 #2 들여다보기 #3 돌아보기 또 어떤 결과를 내고 있는지 얘기하려고 합니다.
  21. 21. #1 멀리 보기 첫 번째로 저희 서버 구조가 어떻게 짜여져 있는지 멀리서 큰 윤곽부터 한 번 그려 볼게요.
  22. 22. SPOF Single Point of Failure (단일장애지점) 프로젝트 초반부터 지금까지 저희의 목표는 SPOF 없는 MMORPG 서버를 만드는 거였습니다.
  23. 23. SPOF Single Point of Failure (단일장애지점) SPOF는 Single Point of Failure의 약자로 보통 단일장애지점이라고 번역하는데요
  24. 24. SPOF Single Point of Failure (단일장애지점) 문제가 발생하면 서비스 전체의 장애를 초래하는 한 지점을 얘기합니다.
  25. 25. 한 번 이렇게 생긴 가상의 서비스를 상상해 볼게요.
  26. 26. 클라이언트가 가운데 있는 서버에 요청을 보내면
  27. 27. 그 서버가 여러 백엔드 서버 중 한 대와 통신한 다음 결과를 내주는 구조입니다.
  28. 28. 여기서 백엔드 서버의 경우는 이중화돼있어서 한두 개 죽는다고 서비스에 장애를 초래하진 않습니다.
  29. 29. 반면 이중화 돼있지 않은 가운데 중계 서버에 장애가 발생하면 바로 서비스 장애로 이어지게 되죠.
  30. 30. SPOF 이렇게 서비스 요소 중에 어떤 곳이라도 이중화돼있지 않은 곳이 있다면 그곳을 SPOF라고 볼 수 있습니다.
  31. 31. 이중화 저희는 듀랑고 서버에 단 하나의 SPOF도 만들지 않기 위해서 모든 요소를 빠짐없이 이중화하려고 노력해왔습니다.
  32. 32. 저희 서버는 여러 게임 서버 노드가 서로 통신하면서 유기적으로 협력하며 동작하는데요
  33. 33. 이때 중앙 서버의 중계가 필요하지 않게 하고 싶었습니다.
  34. 34. 그러기 위해 ZeroMQ를 도입했어요.
  35. 35. ZeroMQ는 중계 장치 없이도 RabbitMQ나 Redis의 PUB/SUB같은 메시지큐 기능을 사용할 수 있게 해주는 라이브러리입니다.
  36. 36. 중계 장치가 없다 보니 각 노드는 서로가 서로의 주소를 자동으로 알아낼 수 있어야 하는데
  37. 37. 이 부분에서 Apache ZooKeeper 같은 컨센서스 코디네이터인 etcd의 도움을 받습니다.
  38. 38. 저희의 각 노드는 etcd를 통해서 자기 주소를 다른 노드에게 알리고 또 다른 노드의 주소를 모두 알아내서 서로 연결을 맺게 됩니다.
  39. 39. 데이터베이스로는 RDBMS 대신 NoSQL DBMS인 Couchbase를 채택했습니다.
  40. 40. Couchbase는 CAP이론의 C.A.P. 중에서 C.P.를 취하는 DBMS인데요
  41. 41. 단순한 Key-value 스토리지이긴 한데 내용을 색인하는 기능도 어느정도는 지원하고 있습니다.
  42. 42. 서버 인프라론 손쉽게 서버를 증설하거나 감축하기 위해 AWS를 이용하고 있습니다.
  43. 43. 백엔드 서비스 얘기는 이쯤 해두고 이번엔 듀랑고 게임 서버로 넘어가 볼게요.
  44. 44. 역할 별 노드 저희는 게임 서버 노드를 몇가지 역할 별로 구분해서 만들고 있습니다.
  45. 45. 프론트엔드 프론트엔드는 게임 클라이언트가 직접 접속하는 서버 노드인데요
  46. 46. 프론트엔드 플레이어 객체를 관리하고 주변 상황을 클라이언트에 스트리밍하는 역할을 합니다.
  47. 47. 게이트웨이 게이트웨이는 RESTful한 웹 서버인데 파일이나 DB에 있는 리소스를 클라이언트에서 읽을 수 있게 해주고
  48. 48. 게이트웨이 또 클라이언트가 어느 프론트엔드에 접속할지 배정해주는 역할도 합니다.
  49. 49. 동물원 듀랑고의 동물 AI는 이 동물원 노드에서 돌아가는데요
  50. 50. 동물원 동물의 행동 중에 전투를 제외한 모든 행동이 여기서 시뮬레이션됩니다.
  51. 51. 정원 정원 노드는 식물, 광물, 시설물 같은 정적인 객체를 관리하고요
  52. 52. 콜로세움 마지막으로 콜로세움은 전투만 담당하는 조금 특별한 노드인데
  53. 53. 콜로세움 콜로세움에 대해선 이따가 좀 더 자세히 다룰 게요.
  54. 54. 노드1 노드2 노드3 몇몇 게임 서버 노드는 각자의 역할에 맞춰 게임 세계 곳곳에 흩어져있는 객체를 관리합니다.
  55. 55. 노드1 노드2 노드3 자기가 관리하는 객체의 소유권까지 얻어서 전담하게 되죠.
  56. 56. 노드1 노드2 노드3 이때 같은 노드가 관리하는 객체라고 꼭 같은 장소에 모여있는 건 아닌데요
  57. 57. 노드1 노드2 노드3 노드가 객체를 맡을 때 위치를 참고하긴 하지만 거기에 제한까진 두지 않고 있어요.
  58. 58. 플레이어나 동물 같은 객체는 저마다 일정한 영역의 시야를 갖는데요
  59. 59. 시야에 들어오는 다른 객체를 각자 인지할 수 있게 되는 거죠.
  60. 60. 뿐만 아니라 게임 서버 노드 역시 시야를 갖습니다.
  61. 61. 한 노드가 전담하는 모든 객체들의 시야를 더한 영역이 바로 그 노드의 시야가 되는데
  62. 62. 만약 게임 서버 노드끼리 이렇게 시야가 겹치게 되면
  63. 63. 다른 노드에서 전담하던 객체가 프록시 객체로 만들어져서 이쪽 노드로 동기화됩니다.
  64. 64. 이런 방식으로 한 장소를 한 노드가 배타적으로 독점하지 않으면서도
  65. 65. 각자가 관리하는 객체 근처의 세계를 인지하고 중계하고 상호작용할 수 있게 됩니다.
  66. 66. http://j.mp/sub-ndc14 저희의 서버 노드 간 통신이나 시야 처리에 대해선 제가 재작년 발표에서 주로 다뤘었는데요
  67. 67. http://j.mp/sub-ndc14 위 주소로 들어가면 당시 슬라이드를 보실 수 있습니다.
  68. 68. http://j.mp/sub-ndc14 근데 제가 슬라이드에 글을 별로 안 적어 놔서 아마 이것만 봐서는 무슨 내용인지 모르실 것 같아요.
  69. 69. http://j.mp/sub-ndc14-tig by디스이즈게임안정빈기자 하지만 감사하게도 디스이즈게임 안정빈 기자님께서 그때 제 발표를 굉장히 잘 정리해주신 기사가 있습니다.
  70. 70. http://j.mp/sub-ndc14-tig by디스이즈게임안정빈기자 그러니 관심 있으신 분들은 이쪽도 같이 참고해주시면 좋을 것 같습니다.
  71. 71. 이처럼 저희는 SPOF를 만들지 않기 위해서 모든 서비스 요소를 이중화하는 한편
  72. 72. 모든 서버 노드가 유기적으로 협력해서 단 하나의 듀랑고 세계를 구축하도록 설계하고 있습니다.
  73. 73. 큰 윤곽을 그려봤으니 이번엔 이렇게 만들어진 듀랑고의 게임 서버가
  74. 74. 듀랑고라는 게임을 어떻게 구현하고 있는지 좀 더 자세히 들여다보겠습니다.
  75. 75. #2 들여다보기 부동산 • 신기루 • 전투 공방 합 크게 세 가지 주제를 다룰 건데요 그 중 첫 번째 주제는 게임 세계의 부동산입니다.
  76. 76. 부동산이라고 해서 건물만 가지고 얘기할 건 아니고요
  77. 77. 정적 객체 식물이나 광물, 시설물 같은 모든 정적 객체에 대해 다루겠습니다.
  78. 78. 듀랑고 세계에서 가장 주요한 게임플레이 무대는 자동으로 생성되는 섬입니다.
  79. 79. 심리스 이 섬은 플레이어가 중간로딩 없이 심리스하게 이동할 수 있는 가장 큰 공간적 단위죠.
  80. 80. 단일 대륙 저희가 개발 초기에는 모든 플레이어가 함께 사는 단 하나의 거대한 대륙을 기획했었는데
  81. 81. 군도 개발을 진행하면서 대륙 처럼 거대한 섬 뿐만 아니라 그 밖에도 다양한 섬을 넘나들 수 있는 군도 모델로 선회하게 됐습니다.
  82. 82. 안정섬 불안정섬 군도에는 이렇게 안정섬과 불안정섬, 두 종류의 섬이 있는데요
  83. 83. 자원 ▼ 면적 ▲ 수명 ∞ 안정섬 안정섬의 경우 좋은 자원이 나진 않지만 면적이 넓고 시간이 지나도 사라지지 않아서
  84. 84. 이렇게 사람들끼리 마을을 만들고 정착하기 좋습니다.
  85. 85. 자원 ▲ 면적 ▼ 수명 불안정섬 안정섬과 달리 불안정섬은 면적이 좁고 수명에 제한이 있어서 일정한 시간이 지나면 사라집니다.
  86. 86. 자원 ▲ 면적 ▼ 수명 불안정섬 하지만 생태계도 훨씬 다양하고 좋은 자원도 구할 수 있어서
  87. 87. 이렇게 탐험하기에 적합하죠.
  88. 88. 만약 안정섬에 플레이어가 너무 적게 있으면 적적하고 외로울 겁니다.
  89. 89. 가뜩이나 넓은데 마치 무인도에 혼자 떨어진 느낌이겠죠.
  90. 90. 또 불안정섬의 경우는 사람이 너무 많으면 오히려 경쟁이 치열해져서 탐험하기 괴로워질 겁니다.
  91. 91. 듀랑고에서의 쾌적하고 재밌는 경험을 위해선 섬의 인구밀도가 항상 적절하게 유지돼야 합니다.
  92. 92. 하지만 섬 수가 고정 돼있다면 유입되는 플레이어의 수에 따른 인구밀도 변화에 대응할 수 없을 겁니다.
  93. 93. 사람 ∝ 섬 그래서 저희는 각 섬의 인구밀도를 적절하게 맞추고자 플레이어의 수에 맞춰서 섬 수가 자동으로 조절되게 만들었습니다.
  94. 94. 사람 ∝ 섬 가령 100명만 플레이할 때는 섬이 서너 개밖에 되지 않지만 10,000명이 플레이할 땐 수백 개의 섬도 생길 수 있는 거죠.
  95. 95. 7k 836 2차 LBT 지난 2차 LBT 때를 예로 들면 참여자는 약 7천 명 정도였는데요 그에 맞춰서 836개의 섬이 자동으로 생성돼서 공급됐었습니다.
  96. 96. 이처럼 듀랑고 세계의 공간은 잠재적으로 무한하다고 볼 수 있습니다.
  97. 97. 게임 서버는 이렇게 얼마나 늘어날지 모르는 공간을 모두 지탱해야 하는 거죠.
  98. 98. 그럼 지금부터 저희가 어떻게 무한한 공간을 처리하는지 그 방법을 살펴보도록 하겠습니다.
  99. 99. 플레이어에서 시작해 볼게요.
  100. 100. 접속 중… 플레이어가 게임에 접속할 땐 우선 게이트웨이에 자신의 아이디를 알려주게 됩니다.
  101. 101. 배정 그럼 게이트웨이는 플레이어가 마지막에 있던 위치를 기반으로 접속할 프론트엔드를 배정해주죠.
  102. 102. 이어서 클라이언트가 배정받은 프론트엔드에 접속하면
  103. 103. 플레이어 객체가 게임 세계에 나타나게 됩니다.
  104. 104. 플레이어는 접속했을 때만 게임 세계에 속하니깐 서버는 수동적으로 그저 전달받은 아이디를 DB에서 찾기만 하면 되죠.
  105. 105. 반면 식물이나 광물, 시설물 같은 정적 객체들은 늘 게임 세계에 속해 있어야 합니다.
  106. 106. 그렇다고 플레이어처럼 서버에 스스로 접속하는 건 아니기 때문에 서버가 직접 찾아낼 수 있어야 합니다.
  107. 107. 아이디 위치 색인 키 그러려면 아이디로 색인되는 플레이어와 달리 정적 객체들은 위치로 색인돼야 합니다.
  108. 108. 아이디 위치 색인 키 서버에 좌표만 주어져도 그곳에 있는 정적 객체를 바로 발견할 수 있어야 하는 건데요
  109. 109. 저희가 위치를 다룰 땐 몇 가지 간략화된 지리 단위를 이용합니다.
  110. 110. 섬의 모양새인 지형은 일종의 타일맵인데 한 칸에 한 가지 지질을 담고 있습니다.
  111. 111. 타일 여기서의 한 칸을 저희는 타일이라고 부릅니다.
  112. 112. 타일 타일은 게임 내에서 정적 객체가 점유할 수 있는 가장 작은 영역이기도 하죠.
  113. 113. 16×16 타일 = 청크 그 다음 단위는 가로세로 16타일을 묶은 구역인 청크입니다.
  114. 114. 16×16 타일 = 청크 섬이 크건 작건 청크의 면적은 균일하겠죠.
  115. 115. 16×16 타일 = 청크 그러면서도 타일처럼 너무 작지도 않고 크기가 적당해서 여러가지 용도로 유용하게 쓰고 있습니다.
  116. 116. 가령 게임 클라이언트는 서버로부터 자기 시야에 들어온 근처의 정보만 스트리밍 받는데
  117. 117. 이 때 정보가 묶이는 단위도 바로 청크입니다.
  118. 118. {키: 값} 한편, Key-value 스토리지인 Couchbase에서 아이디가 아닌 정보로 데이터를 찾는 건 그렇게 간단하지 않습니다.
  119. 119. {키: 값} Map/Reduce를 지원하긴 하지만 색인 속도가 느려서 자주 읽고 써야 되는 작업에는 적합하지 않거든요.
  120. 120. {키: 값} 저희는 Couchbase를 쓰면서도 어디에 어느 정적 객체가 있는지 빠르고 정확하게 색인하기 위해
  121. 121. 땅문서 땅문서라고 부르는 별도의 문서에 정적 객체의 위치를 역정규화시켰습니다.
  122. 122. {타일: 객체} 구조는 단순한데요 어느 타일에 어떤 정적 객체가 위치하는지 가리키는 딕셔너리라고 볼 수 있습니다.
  123. 123. 만약 섬 전체를 하나의 땅문서로 관리하게 되면 다루기는 편하겠죠.
  124. 124. 하지만 섬 크기가 클 수록 색인하는 부담도 함께 커질 겁니다. 땅문서 하나가 객체 수백만 개를 색인한다고 생각해보세요.
  125. 125. 청크마다 땅문서 저희는 섬 크기와 상관 없이 색인 성능을 일관되게 보장하기 위해
  126. 126. 청크마다 땅문서 땅문서 하나가 딱 하나의 청크만 담당하게 만들었습니다.
  127. 127. 노드1 노드2 노드3 이런 땅문서는 어떤 서버 노드든 자유롭게 조회하고 수정할 수 있습니다.
  128. 128. 노드1 노드2 노드3 종종 여러 스레드가 동시에 같은 땅문서를 건드릴 때도 있겠죠.
  129. 129. 노드1 노드2 노드3 그런 경우에도 다른 스레드의 수정사항을 덮어쓰지 않도록 트랜잭션 처리로 보호해야 합니다.
  130. 130. 낙관적 트랜잭션 개발 초기엔 여기에 낙관적 트랜잭션 이라는 기법을 적용했는데요
  131. 131. 낙관적 트랜잭션 낙관적 트랜잭션은 ‘경합이 거의 없겠거니’하고 낙관적으로 가정하는 트랜잭션 방법 중 하나입니다.
  132. 132. 낙관적 트랜잭션 용어는 낙관적 동시성 제어 식 트랜잭션이라고 부르는 게 맞지만 편의상 이렇게 줄여서 말할 게요.
  133. 133. v1 낙관적 트랜잭션은 이렇게 동작하는데요 DB엔 레코드 별로 버전이 기록돼 있습니다.
  134. 134. v1 v1 애플리케이션이 DB에서 레코드를 조회할 때 이 버전도 함께 받습니다.
  135. 135. v1' v1 그런 다음 레코드를 수정하고 다시 저장할 때도 받아 뒀던 버전을 같이 보냅니다.
  136. 136. v1' v1 그렇게 DB에 있는 버전이 기존 버전과 일치하는지 확인하죠.
  137. 137. v1' v1 두 버전이 여전히 같을 때에만 레코드가 성공적으로 저장되게 됩니다.
  138. 138. v1' v2 만약 그새 다른 스레드에서 이 레코드를 수정했다면 버전이 자동으로 바뀌게 되는데
  139. 139. v1' v2 이땐 DB가 저장 요청을 받아주지 않고 거부합니다.
  140. 140. v1' v2 그럴 경우 애플리케이션은 트랜잭션을 포기하거나 다시 시도할 수 있는데요
  141. 141. v2 v2 트랜잭션을 다시 시도하는 경우엔 최신 레코드를 조회해서 새 버전을 받고
  142. 142. v2 v2 똑같은 수정사항을 적용한 다음 다시 저장하길 시도합니다.
  143. 143. v2' v2 이 과정을 반복하다 보면 언젠가는 경합이 끝나서 트랜잭션의 성공을 보장할 수 있는 거죠.
  144. 144. v2' v2 경합이 자주 일어나는 경우에 이 방법을 쓰면 이런 재시도 루프가 여러 바퀴 돌 수 있어서 효율적이지 않습니다.
  145. 145. v2' v2 하지만 경합이 별로 없는 경우에 사용하면 대체로 루프가 한 바퀴 밖에 안 돌 테니까 꽤 가볍게 쓸 수 있죠.
  146. 146. Check and Set (CAS) Couchbase는 CAS라는 이름으로 이런 버전 검사 기능을, 기본으로 제공합니다.
  147. 147. Check and Set (CAS) 그래서 쓰기 편하긴 한데 딱 한 레코드에 한한 트랜잭션만 보장해주기 때문에
  148. 148. Check and Set (CAS) 거래 처리 같이 여러 레코드를 함께 수정하는 경우엔 적합하지 않습니다.
  149. 149. 낙관적 트랜잭션 그래서 정적 객체가 한 청크 안에 쏙 들어갈 땐 수정할 땅문서도 딱 한 개라서 낙관적 트랜잭션이면 충분하지만
  150. 150. 낙관적 트랜잭션 여러 청크에 걸치는 경우는 그렇지 않습니다.
  151. 151. BEGIN; UPDATE A; UPDATE B; COMMIT; Couchbase는 RDB와 다르게 여러 레코드를 한 번에 수정하는 트랜잭션은 지원하지 않습니다.
  152. 152. ?! 만약 게임 서버가 트랜잭션 처리 없이 무턱대고 한 번에 여러 땅문서를 차례대로 수정하려고 하면
  153. 153. ?! 예기치 못 한 오류나 다른 스레드와의 경합이 발생했을 때 이렇게 불완전한 땅문서가 만들어질 수 있습니다.
  154. 154. ?! 저희는 정적 객체가 여러 청크에 걸치는 경우라도 안전하게 처리하기 위해서
  155. 155. BASE 트랜잭션 BASE 트랜잭션이라는 기법을 기반으로 땅문서의 트랜잭션을 보장할 다른 방법을 고안했습니다.
  156. 156. BASE ACID 트랜잭션 RDBNoSQL RDB에 ACID 트랜잭션이 있다면 NoSQL엔 BASE 트랜잭션이 있습니다.
  157. 157. BASE ACID 트랜잭션 RDBNoSQL 여러 레코드에 대한 트랜잭션을 DB가 아닌 애플리케이션에서 보장하는 방법이죠.
  158. 158. Basically Available Soft state Eventual consistency BASE 트랜잭션에서 “BASE”가 이런 뜻이라는데 그냥 산성 염기성 말장난하려고 억지로 짜 맞춘 것 같죠?
  159. 159. Basically Available Soft state Eventual consistency 이중에서 마지막 Eventual consistency가 중요한 것 같습니다.
  160. 160. Basically Available Soft state Eventual consistency ACID 트랜잭션과 다르게 BASE 트랜잭션이 진행되는 동안엔 DB에서 레코드들 간의 일관성이 깨지게 돼요.
  161. 161. Basically Available Soft state Eventual consistency 하지만 트랜잭션이 완료됐을 때 결국에는 일관성이 맞춰지게 됩니다.
  162. 162. Basically Available Soft state Eventual consistency 그럼 한 번 BASE 트랜잭션이 어떻게 동작하는지 간단하게 짚고 넘어가 볼게요.
  163. 163. 여기 수정할 레코드들이 있습니다.
  164. 164. BASE 트랜잭션을 쓸 땐 이 레코드들을 바로 수정하는 대신
  165. 165. TX 트랜잭션 문서 먼저 별개의 레코드에 작업내용만 기록합니다.
  166. 166. TX 트랜잭션 문서 레코드를 각각 어떻게 어떻게 바꿔라 하는 내용을 저장하는 거죠.
  167. 167. TX 트랜잭션 문서 이 레코드를 트랜잭션 문서라고 부르겠습니다.
  168. 168. TX 트랜잭션 문서 트랜잭션 문서가 성공적으로 등록됐으면
  169. 169. TX 수정할 레코드들은 차근차근 수정되게 됩니다.
  170. 170. TX 이 때 보면 레코드 간 일관성이 깨져 있죠.
  171. 171. TX 예를 들면 한쪽에선 돈을 꺼냈는데 다른 쪽에는 돈이 안 들어가 있다거나 하는 상황이에요.
  172. 172. 하지만 언젠가 모든 레코드에 수정사항이 적용되면
  173. 173. 일관성도 맞춰지고 트랜잭션도 완료되게 됩니다.
  174. 174. 만약 중간에 일부 레코드 수정에 실패하더라도
  175. 175. 트랜잭션 문서에 적힌 내용을 바탕으로 애플리케이션에서 뒤늦게나마 수정사항을 마저 적용할 수 있습니다.
  176. 176. TX 트랜잭션 문서 땅문서에 바로 저희가 정적 객체를 땅문서에 기록하는 경우에도 BASE 트랜잭션과 마찬가지로
  177. 177. TX 트랜잭션 문서 땅문서에 바로 땅문서에 바로 쓰는 대신 별개의 트랜잭션 문서에 설치 계획만 먼저 기록해둡니다.
  178. 178. TX 트랜잭션 문서 땅문서에 바로 어느어느 타일에 어떤 객체를 올리겠다는 내용이죠.
  179. 179. TX 각 트랜잭션 문서는 이렇게 가로세로 4청크 씩을 담당합니다.
  180. 180. TX 패치 이 구역을 저희는 패치라고 부르는데요.
  181. 181. TX 이 패치 내에서 벌어지는 땅문서 변경이 모두 해당 트랜잭션 문서에 기록됩니다.
  182. 182. TX 그럼 패치의 경계에 걸치는 경우는 어떻게 처리될까요?
  183. 183. TX 설치 계획을 두 트랜잭션 문서에 나눠서 기록하면 여전히 트랜잭션을 보장할 수 없게 될 겁니다.
  184. 184. TXTX 이런 빈틈을 없애기 위해서 패치를 이웃한 패치와 1청크 씩 겹치게 만들었습니다.
  185. 185. TXTX 모든 청크 경계가 적어도 하나 이상의 패치로는 덮여있는 거죠.
  186. 186. 정적 객체가 아무리 커도 한 청크를 넘지는 않기 때문에
  187. 187. 어느 곳에 위치하더라도 단 하나의 패치로 완전히 포갤 수 있습니다.
  188. 188. 설치계획은 그 위치를 완전히 포갤 수 있는 단 하나의 트랜잭션 문서에 기록하게 됩니다.
  189. 189. 롤백 대비 한편 BASE 트랜잭션을 쓸 땐 레코드가 롤백되는 상황에도 대비해야 하는데요
  190. 190. TX 가령 첫 번째 레코드는 성공적으로 수정했는데 두 번째 레코드에선 실패했을 경우에
  191. 191. TX 애플리케이션이 직접 역함수를 실행해서 첫 번째 레코드에 적용했던 수정사항을 다시 되돌려야 하는 거죠.
  192. 192. TX 그런데 역함수를 구현하기 어려운 경우가 있습니다.
  193. 193. TX 수정 로직에 사이드이펙트가 있다거나 하는 경우 같이요.
  194. 194. TX 또 역함수마저 실패하거나 애플리케이션이 두 번째 레코드를 며칠 뒤에야 건드려서
  195. 195. TX 첫 번째 레코드를 롤백시켜야한단 사실을 알기까지 시간이 오래 걸릴 수도 있습니다.
  196. 196. TX 이렇게 신경 써야 할 예외 상황이 많아서 저는 BASE 트랜잭션이 다루기 까다로운 편이라고 생각합니다.
  197. 197. + 비관적 트랜잭션 저희는 땅문서 트랜잭션을 좀 더 단순하게 만들기 위해서
  198. 198. + 비관적 트랜잭션 BASE 트랜잭션에 비관적 트랜잭션이라는 방법을 접목해서 롤백 될 가능성을 완전히 없앴습니다.
  199. 199. + 비관적 트랜잭션 이것도 원래는 비관적 동시성 제어 식 트랜잭션이라고 불러야 하지만 그냥 편의 상 이렇게 부를 게요.
  200. 200. 비관적 트랜잭션은 낙관적 트랜잭션과 달리 경합이 분명히 발생할 거라고 비관적으로 가정합니다.
  201. 201. 그래서 수정할 레코드에 일단 락을 걸고 보죠.
  202. 202. 땅문서 트랜잭션을 시작할 때도 반드시 청크 별 락을 얻게 해서
  203. 203. 트랜잭션을 등록하는 동안은 해당 청크의 조건이 절대 바뀌지 않도록 했습니다.
  204. 204. 이 락엔 짧은 TTL이 설정돼 있어서 게임 서버 오류로 인해 제때 풀리지 않더라도 크게 문제가 되진 않습니다.
  205. 205. 지금까지 여러 청크에 걸치는 땅문서 트랜잭션을 보장하는 방법을 소개했는데요
  206. 206. 이렇게 두 청크에 걸치는 정적 객체를 설치하고자 할 때 게임 서버가 땅문서를 어떻게 수정해 나가는지
  207. 207. 그 과정을 한 번 나열해 보겠습니다.
  208. 208. 1. 청크 잠그기 TX 첫 번째 단계에선 우선 청크들에 락을 걸어서 다른 스레드가 해당 청크엔 트랜잭션을 등록하지 못 하게 합니다.
  209. 209. TX 2. 조건 검사 그리고 객체를 설치해도 되는지 조건을 검사해요. 설치하려는 자리가 비어 있어야 되는 거죠.
  210. 210. TX 3. 트랜잭션 등록 TX 조건에 부합하면 다음 단계로 넘어가서 설치 계획을 트랜잭션 문서에 등록하는데
  211. 211. TX 3. 트랜잭션 등록 TX 이 단계까지만 성공하면 정적 객체의 정상적인 설치가 보장됩니다.
  212. 212. TX 4. 잠금 해제 그 다음으론 청크에 걸어둔 락을 풀어주고
  213. 213. TX 5. 땅문서 수정 마지막으로 등록해둔 설치 계획을 처리합니다. 땅문서를 실제로 수정하는 거죠.
  214. 214. TX 5. 땅문서 수정 여기까지 성공하면 한 큐에 정적 객체 설치가 완료됩니다.
  215. 215. TX 5. 땅문서 수정 이제 각 과정에서 오류가 발생하면 어떻게 되는지 역순으로 살펴볼게요.
  216. 216. TX 5. 땅문서 수정 먼저 마지막 단계에서 일부 땅문서 수정에 실패하는 경우엔
  217. 217. TX 5. 땅문서 수정 다른 스레드가 해당 땅문서를 읽을 때 결국 다시 처리되게 됩니다.
  218. 218. TX 4. 잠금 해제 그 전 단계에서 실패하면 청크 락이 제대로 안 풀리겠죠.
  219. 219. TX 4. 잠금 해제 하지만 앞서 소개한 TTL이 있어서 금새 자동으로 풀리게 됩니다.
  220. 220. TX 4. 잠금 해제 또 설치계획도 이미 트랜잭션 문서에 등록돼서 결국엔 모두 처리되게 되죠.
  221. 221. TX 3. 트랜잭션 등록 아예 트랜잭션 등록에 실패하거나
  222. 222. TX 2. 조건 검사 땅의 상태가 조건에 부합하지 않을 땐 즉시 락을 풀고 트랜잭션을 포기합니다.
  223. 223. 1. 청크 잠그기 TX 첫 단계에서부터 오류가 나거나 아니면 다른 스레드가 청크 락을 잡고 있어서 잠그는 데 실패해도
  224. 224. 1. 청크 잠그기 TX 마찬가지로 트랜잭션을 포기하죠.
  225. 225. TX 요약하자면 트랜잭션 문서가 등록되는 3단계를 기준으로
  226. 226. TX 여기를 지나면 정적 객체 설치는 반드시 성공하고
  227. 227. TX 그 전에 실패할 경우 땅문서엔 이렇게 아무런 찌꺼기도 남지 않습니다.
  228. 228. 청크 지금까지 듀랑고 서버의 부동산 처리에 관해 얘기했는데요
  229. 229. 청크 크기가 균일한 청크와
  230. 230. 땅문서 청크 별로 저장되는 땅문서로 정적 객체를 어떻게 다루는지 살펴봤습니다.
  231. 231. 부동산은 듀랑고에서 가장 중요한 자원인 만큼 이렇게 안전한 방법으로 관리하고 있습니다.
  232. 232. #2 들여다보기 부동산 • 신기루 • 전투 공방 합 이어서 듀랑고 세계의 객체들이 언제 생성되고 또 언제 서버 메모리에 올라오는지 얘기해보겠습니다.
  233. 233. 섬은 그저 공간만 차지하는 게 아니라 수많은 객체들도 포함하고 있습니다.
  234. 234. 나무나 바위, 시설물 같은 정적 객체도 잔뜩 배치돼있고 여기저기엔 동물도 살고 있죠.
  235. 235. 300만 10만 2차 LBT 지난 2차 LBT의 경우 정적 객체 300만 개와 동물 10만 마리가 동원됐는데요
  236. 236. 300만 10만 2차 LBT 이 많은 객체들을 항상 서버 메모리에 올려두는 건 불가능할 겁니다.
  237. 237. ⓒ Rockstar Games 제가 한 동안 빠져있었던 <GTA5>라는 게임은 방대한 공간을 제공하는 심리스 오픈월드 게임입니다.
  238. 238. ⓒ Rockstar Games 게임의 배경은 로스산토스라는 가상의 도시인데요
  239. 239. ⓒ Rockstar Games 여기선 어딜 가든 정교한 NPC를 만나볼 수 있습니다. 걸어 다니는 행인부터
  240. 240. ⓒ Rockstar Games 절 잡으러 쫓아오는 경찰이나
  241. 241. ⓒ Rockstar Games 도로를 빽빽이 채우는 자동차들까지
  242. 242. ⓒ Rockstar Games 얼마나 많은 NPC랑 정교한 AI가 이 로스산토스라는 곳을 채우고 있을지 상상하기 어려웠습니다.
  243. 243. ⓒ Rockstar Games 하지만 이렇게 정교하고 구체적인 NPC는 실은 제 근처의 좁은 구역에만 있다는 걸 알 수 있었는데요
  244. 244. ⓒ Rockstar Games 저 멀리 다리 위를 달리는 자동차들은
  245. 245. ⓒ Rockstar Games 사실 아무것도 판단하지 않고 그저 정해진 패턴만 반복하는 하얗고 붉은 불빛일 뿐이더라고요.
  246. 246. ⓒ Rockstar Games 네모 친 곳을 잘 보면 패턴이 보일 겁니다. 불빛들이 간격을 딱딱 맞춰서 다니고 있죠?
  247. 247. LOD Level of Detail 그림: http://polygon-reducer.pc-guru.cz/reducing-level-of-detail 컴퓨터 그래픽스 쪽 최적화 기법 중에 LOD라는 게 있습니다.
  248. 248. LOD Level of Detail 그림: http://polygon-reducer.pc-guru.cz/reducing-level-of-detail 카메라에서 먼 객체를 대충 렌더링하는 기법인데요
  249. 249. LOD Level of Detail 그림: http://polygon-reducer.pc-guru.cz/reducing-level-of-detail 여기 판자 위에 있는 스탠포드버니들은 모두 똑같아 보이지만
  250. 250. LOD Level of Detail 그림: http://polygon-reducer.pc-guru.cz/reducing-level-of-detail 실은 멀 수록 폴리곤을 적게 쓰고 있습니다.
  251. 251. NPC에 LOD <GTA5>는 NPC에 이런 LOD를 적용하고 있습니다.
  252. 252. NPC에 LOD 바로 근처의 NPC는 매우 정교하게 동작하지만 거리가 멀 수록 단순한 패턴만 반복하는 거죠.
  253. 253. NPC에 LOD <GTA5> 뿐 아니라 <어쌔신 크리드 유니티>도 그렇고 여러 심리스 오픈월드 게임들이 비슷한 방식을 취합니다.
  254. 254. NPC에 LOD 저희도 수많은 객체들을 효율적으로 처리하기 위해 객체들에 LOD를 적용하고 있습니다.
  255. 255. 상호작용 활성화 정적 객체 LOD의 경우 거리 대신 상호작용 여부에 반응하게 했는데요
  256. 256. 상호작용 활성화 얘네는 플레이어가 건드려야만 활성화돼서 서버 메모리에 올라가게 됩니다.
  257. 257. 신기루 객체 건드리기 전까진 표시하는 데 필요한 최소한의 정보로만 땅문서에 기록되는데
  258. 258. 신기루 객체 저희는 이 상태를 신기루라고 부릅니다.
  259. 259. 신기루 객체 이런 신기루 상태에서도 클라이언트에 표시될 수 있고 서버에서도 존재를 인식할 수 있습니다.
  260. 260. 플레이어가 건드려서 활성화된 정적 객체는 일정 시간 동안 플레이어랑 상호작용해주다가
  261. 261. 다시 신기루가 돼서 서버 자원을 아낄 수 있게 해줍니다. 접속자가 없으면 서버도 쉴 수 있도록 말이죠.
  262. 262. 자연물 정적 객체 중에 나무나 바위 같은 자연물들은 섬이 만들어질 때부터 같이 있어야 되는데요
  263. 263. NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW 그렇다고 섬 만들 때 자연물도 같이 만들어서 일일이 DB에 저장한다면
  264. 264. NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW 섬 만드는 속도가 느려져서 필요에 따라 섬을 실시간으로 늘리기 어려워질 겁니다.
  265. 265. 시설물 같은 경우는 재료에 따라 생김새가 달라져서 신기루에 담아야 되는 정보도 많은 편인데요
  266. 266. 78 27 12 63 반면 자연물은 생김새가 판에 박혀있어서 그냥 숫자 하나만으로도 표현할 수 있습니다.
  267. 267. 0 12 27 78 63 78 12 27 78 이 점을 활용해서 저희는 섬의 최초 자연물 배치를 단순한 숫자맵 파일로 만들어서 지형 데이터에 포함시켰습니다.
  268. 268. NEW 땅문서의 경우도 역시 섬과 함께 만들어지진 않습니다. 섬이 새로 생성된 직후엔 DB에 땅문서가 존재하지 않죠.
  269. 269. 0 12 27 78 63 78 12 27 78 NEW 그런 경우 서버는 땅문서 대신 자연물 배치 파일을 읽어서 신기루 자연물로 보여줍니다.
  270. 270. DB NEW 플레이어가 신기루 자연물을 건들면 그때야 비로소 객체가 만들어지고 DB에도 저장되죠.
  271. 271. DB NEW NEW 이때 그 청크의 땅문서도 함께 생성돼서 DB에 저장됩니다.
  272. 272. 0 12 27 78 63 78 12 27 78 서버도 그 다음부턴 자연물 배치 파일 대신 DB에 있는 땅문서를 참조하게 됩니다.
  273. 273. 여기까지 정적 객체의 신기루 상태를 먼저 살펴봤는데요
  274. 274. 이번엔 동물의 신기루 상태를 살펴보겠습니다.
  275. 275. 동물에는 고수준 AI가 돌아가서 성능을 많이 잡아먹기 때문에 서버에서 특히 효율적으로 관리해야 합니다.
  276. 276. 동물에는 아까 보신 <GTA5>의 NPC처럼 플레이어와의 거리에 반응하는 LOD를 적용했습니다.
  277. 277. 섬 여기저기엔 동물의 서식지가 기록돼 있는데요
  278. 278. 어디에 어떤 종이 몇 마리 있고 마지막엔 뭘 하고 있었는지 같은 정보가 저장돼있죠.
  279. 279. 플레이어가 섬에 들어오면 자기 시야에 들어오는 동물 서식지를 찾습니다.
  280. 280. 그리고 거기에 살고 있는 동물들을 깨우죠.
  281. 281. 깨어난 동물은 게임 세계에 스폰돼서 고수준 AI를 돌리기 시작합니다.
  282. 282. 이런 동물의 활동은 근처에 관객이 있는 동안에만 지속되고요
  283. 283. 관객이 사라지면 동물들도 마지막 상태만 DB에 기록하고
  284. 284. 모두 사라지게 됩니다. 다시 서식지 정보만 남게 되는 거죠.
  285. 285. 이처럼 듀랑고에선 수많은 객체가 플레이어의 눈앞을 빽빽이 채우고 있지만
  286. 286. 대부분은 신기루 상태라서 컴퓨팅 자원이나 DB 공간을 거의 소모하지 않습니다.
  287. 287. 이렇게 플레이어가 필요로 하는 곳에만 자원을 집중하는 것이
  288. 288. 듀랑고 서버가 잠재적으로 무한한 공간을 지탱하는 방법입니다.
  289. 289. <야생의 땅: 듀랑고> 중앙 서버 없는 게임 로직 최호영 • 14:10 • GBI 오늘 오후 2시 10분에 저희 스튜디오 최호영 님 발표에서 방금 소개해드린 신기루나 부동산을 게임로직에서 실제로 다룬 사례를 소개합니다.
  290. 290. <야생의 땅: 듀랑고> 중앙 서버 없는 게임 로직 최호영 • 14:10 • GBI 제가 슥 넘긴 시설물의 신기루도 이쪽에서 자세히 다룰 거고요
  291. 291. <야생의 땅: 듀랑고> 중앙 서버 없는 게임 로직 최호영 • 14:10 • GBI 또한 중앙 서버가 없는 환경에서 게임 로직을 만드는 데 있어서 어떤 어려움이 있었고
  292. 292. <야생의 땅: 듀랑고> 중앙 서버 없는 게임 로직 최호영 • 14:10 • GBI 또 어떻게 극복했는지 공유하는 자리니까
  293. 293. <야생의 땅: 듀랑고> 중앙 서버 없는 게임 로직 최호영 • 14:10 • GBI 저희 서버 아키텍처에 관심 있는 분들께선 이어서 들으시면 좋을 것 같습니다.
  294. 294. #2 들여다보기 부동산 • 신기루 • 전투 공방 합 이번엔 주제를 바꿔서 듀랑고의 전투에 대해 이야기해보겠습니다.
  295. 295. vs. 개발 초기에 저희가 구현한 전투는 프론트엔드와 동물원 노드에 걸쳐서 벌어졌는데요
  296. 296. vs. 양쪽에서 플레이어 객체와 동물 객체가 서로 공격을 주거니 받거니 하며 싸우는 거죠.
  297. 297. RPC 그러다 보니 모든 전투 액션이 노드 간 통신으로 이뤄져서 리액션이 지연되는 경우가 자주 있었습니다.
  298. 298. 가령 플레이어 공격 연출은 이미 나갔는데 동물이 제때 맞아주지 않아서
  299. 299. 피격 판정이 늦거나 어긋난다거나 하는 식이었죠.
  300. 300. 이건 일부러 서버 간 통신을 지연시켜놓고 찍은 영상인데요
  301. 301. 공방 합이 맞지 않는 것을 보실 수 있습니다.
  302. 302. 저희는 공방 합이 재밌는 전투를 만드는 데 있어서 굉장히 중요한 요소라고 생각했습니다.
  303. 303. 콜로세움 그래서 공방합을 맞추기 위해 새로운 게임 서버 노드인 콜로세움을 도입했습니다.
  304. 304. 콜로세움 앞서 콜로세움은 전투만 담당하는 특별한 노드라고 소개 했었는데요 콜로세움이 전투를 어떻게 이끄는지 한 번 보도록 하겠습니다.
  305. 305. vs. 프론트엔드에 있는 플레이어와 동물원 노드에 있는 동물 사이에 전투가 벌어지면
  306. 306. vs. vs. 두 노드가 직접 전투를 처리하는 대신 임의의 콜로세움에 전투 방을 생성합니다.
  307. 307. vs. vs. 그때부터 전투에 참여한 객체는 콜로세움에 동기화되는데요
  308. 308. vs. vs. 콜로세움이 동기화된 객체를 소유하는 건 아니지만 대신 제어권을 넘겨받아서 직접 조종할 수 있게 됩니다.
  309. 309. vs. vs. 공방 계획 전투 방에서는 전투 스케줄러라는 게 돌아갑니다. 전세를 파악하고 공방 계획을 짜는 역할을 하죠.
  310. 310. vs. vs. 통보 이렇게 세워진 공방 계획은 프론트엔드와 동물원 노드에 통보되는데
  311. 311. vs. vs. 통보 통보 받은 쪽에선 그 계획을 무조건 따라야 합니다.
  312. 312. 쉽게 말하면 클라이언트 대신 서버가 접속하는 인스턴스 던전이라고도 볼 수 있을 것 같아요.
  313. 313. 클라이언트에선 심리스한 필드 전투로 보이지만 말이죠.
  314. 314. RPC 아까와 달리 콜로세움 노드 하나에서 공방 계획이 모두 결정되다 보니까
  315. 315. RPC 노드 간 통신에 의존하지 않아도 돼서 판정에서의 공방 합이 맞게 됩니다.
  316. 316. ① 이렇게 짠 공방 계획을 패킷 하나로 묶어서 클라이언트로 보낸다면 연출에서도 공방 합을 맞출 수 있을 겁니다만
  317. 317. ① 아직… 이 계획은 아직 실현하지 못 했습니다.
  318. 318. ① ② 그래서 현재 구현은 이런데요
  319. 319. ① ② 콜로세움에서 결정된 동물의 행동이 프론트엔드로 바로 전달되지 않고 동물원 노드를 거쳐갑니다.
  320. 320. ① ② 그래서 플레이어의 행동과 동물의 행동이 서로 다른 시점에 클라이언트로 전달되죠.
  321. 321. ① ② 노드 간 통신 속도가 빠를 땐 별 문제가 생기지 않는데 통신이 느려지거나 동물원에 과부하가 걸리게 되면
  322. 322. ① ② 공격 연출과 방어 연출 사이에 시간차가 발생하게 됩니다.
  323. 323. ① 이 부분은 차후에 앞에서 말씀드린 방법으로 개선할 예정입니다.
  324. 324. 규모, 가용성 합의 분산 아키텍처 저희가 설계한 분산 서버 아키텍처로 처리 규모와 가용성을 높일 순 있었지만
  325. 325. 규모, 가용성 합의 분산 아키텍처 여러 서버 노드 사이에 합의가 필요한 경우엔 간단한 일이라도 콜로세움 같은 우회책을 마련할 필요가 있었습니다.
  326. 326. 규모, 가용성 합의 분산 아키텍처 저희는 이점을 듀랑고 세계를 무한히 넓게 만들기 위한 일종의 트레이드오프로 인식하고 있고요
  327. 327. 규모, 가용성 합의 분산 아키텍처 좀 더 쉽게 해결할 수 있는 방법과 장치를 꾸준히 고민하고 있습니다.
  328. 328. <야생의 땅: 듀랑고>의 거친 환경에서 살아가는 동물 AI 박동일 • 15:20 • GBI 콜로세움 전투를 비롯해 듀랑고의 동물에 관한 더 자세한 이야기는
  329. 329. <야생의 땅: 듀랑고>의 거친 환경에서 살아가는 동물 AI 박동일 • 15:20 • GBI 오늘 오후 3시 20분 박동일 님 발표에서 들으실 수 있으니까요 이쪽에도 많은 참관 부탁드립니다.
  330. 330. 지금까지 저희 게임 서버가 듀랑고라는 게임을 어떻게 구현하고 있는지 살펴봤습니다.
  331. 331. 청크 신기루 청크라는 크기가 균일한 단위와 필요한 곳에만 자원을 집중하는 LOD 처리를 이용해서
  332. 332. 청크 신기루 잠재적으로 무한한 공간을 지탱하고
  333. 333. 땅문서 콜로세움 여러 서버 노드가 접근해도 안전하게 관리되는 땅문서와 콜로세움 같이 특화된 서버 노드로
  334. 334. 땅문서 콜로세움 모든 서버 노드가 합의한 단 하나의 게임 세계를 만들었습니다.
  335. 335. 하지만 아직은 서버 아키텍처에 미흡한 부분이 많습니다.
  336. 336. #3 돌아보기 이번엔 그 중 지난 두 차례의 LBT를 진행하면서 저희가 겪은 주요 문제 두 가지를 꼽아봤습니다.
  337. 337. 하나는 로드밸런싱 문제인데요 특히 프론트엔드 부하가 유난히 고르게 분배되지 않던 점입니다.
  338. 338. 듀랑고에선 많은 사람들이 이렇게 좁은 지역에 마을을 짓고 옹기종기 모여 살게 됩니다.
  339. 339. 지금처럼 위치만으로 프론트엔드를 배정해서는 특정 프론트엔드에 부하가 몰리게 마련이더라고요
  340. 340. 그로 인해 동기화 품질이 떨어지는 걸 이번엔 막지 못 했습니다.
  341. 341. 프론트엔드를 배정해줄 때 위치 뿐만 아니라 부하 상황도 함께 고려하는 방향으로 계획하고 있습니다.
  342. 342. 나머지 하나는 불안정섬 과잉공급 문제입니다.
  343. 343. 불안정섬이 하나만 생겨도 그곳엔 동물이 수십 마리는 딸려오는데
  344. 344. 섬 면적이 좁다 보니 플레이어가 한두 명만 돌아다녀도 대부분의 동물이 깨어나게 됩니다.
  345. 345. 그러다 보니 동물원 노드에도 부하가 생기고 프론트엔드에도 동기화 부담이 가중됐었습니다.
  346. 346. 불안정섬의 인구밀도를 잘 조절하면 이런 문제가 발생하지 않을 거라고 생각했지만
  347. 347. 이번에 저희가 설정한 인구밀도로는 동시 접속자에 비해 동물의 수가 지나치게 많아졌었습니다.
  348. 348. 이런 문제를 방지하기 위해 동기화 성능과 인구밀도 조절 방법을 함께 개선하려고 합니다.
  349. 349. 모든 서버는 분명히 죽는다 주요 문제들 말고도 메모리릭이나 게임 로직 오류, 미묘한 타이밍 문제 같은 각종 버그도 있었습니다.
  350. 350. 모든 서버는 분명히 죽는다 개중에는 몇몇 서버 노드를 힘들게 만드는 것도 있었죠. 모든 서버는 분명히 죽는 거 아시죠?
  351. 351. 증설 감축 재시작 보셨듯이 이번에 저희가 모든 문제를 해결한 상태는 아니었지만 그래도 테스트를 성공적으로 마칠 수 있었던 까닭은
  352. 352. 증설 감축 재시작 서버 증설과 감축, 그리고 재시작을 자유롭게 할 수 있었다는 점에 있는 것 같아요.
  353. 353. 노드1 노드2 노드3 각 게임 서버 노드가 특정 영역을 독점하지 않는 덕분에
  354. 354. 노드1 노드2 노드3 어떤 노드가 문제를 일으킬 때 그걸 종료하기만 하면 바로 다른 노드들이 그 역할을 대신할 수 있습니다.
  355. 355. 노드1 노드2 노드3 또 서버 부하가 높아졌을 때 노드를 새로 띄우기만 해도 부하가 자동으로 분산돼서 서비스를 중단하지 않고도 상황을 회복시킬 수 있죠.
  356. 356. ON ON ON ON ON 이번 테스트에선 몇몇 동물원 노드가 폭주하는 버그가 있었는데요
  357. 357. OFF ON ON ON ON 해당 노드를 껐다가
  358. 358. ON ON ON ON ON 다시 켜는 것만으로 점검을 걸지 않고 문제를 해결할 수 있었습니다.
  359. 359. 꿈: 오토스케일링 저희는 이런 구조와 운영 경험을 바탕으로
  360. 360. 꿈: 오토스케일링 나중엔 듀랑고 서버를 오토스케일링할 수 있는 MMORPG 서버로 만들고자 합니다.
  361. 361. To be continued… 개인적으로는 지난 두 LBT에서 아쉬움이 많이 남았었는데요
  362. 362. To be continued… 하지만 저희 서버 아키텍처의 강점과 약점을 파악할 수 있는 굉장히 좋은 기회였다고 생각합니다.
  363. 363. To be continued… 이 경험을 발판 삼아서 다음 번엔 좀 더 좋은 서비스를 제공하도록 준비하고 있습니다.
  364. 364. 감사합니다. http://j.mp/sub-ndc16 제가 준비한 이야기는 여기까지입니다. 끝까지 발표를 들어주셔서 감사하고요
  365. 365. 감사합니다. http://j.mp/sub-ndc16 아래 주소에 발표 원고를 올려놨으니 제 전달력이 부족해서 이해하기 어려웠던 부분은 이쪽을 참고해주세요.
  366. 366. 아울러 저희 왓 스튜디오에선 함께 교류할 훌륭한 인재를 찾아다니고 있습니다.
  367. 367. 저와 함께 듀랑고의 흥하는 서버를 만들고 싶으신 분이나 아이디어를 주고받고 싶으신 분은
  368. 368. 이흥섭 http://subl.ee/ sub@nexon.co.kr 제게 연락주세요. 이 QR코드 찍으시면 될 겁니다.
  369. 369. 이흥섭 http://subl.ee/ sub@nexon.co.kr 이상 이흥섭이었습니다. 감사합니다.
  370. 370. 이흥섭 http://subl.ee/ sub@nexon.co.kr

×