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. 3 - 3부

839 views

Published on

NDC18에서 발표했습니다. 슬라이드 뒤쪽에 Q&A를 첨부했습니다.

SlideShare에 슬라이드 300장 제한이 생겨서 부득이하게 3부로 나눠서 올렸습니다. 보는 데 불편하시겠지만 양해를 부탁드립니다.

- 1부: https://subl.ee/~ndc18
- 2부: https://subl.ee/~ndc18.2
- 3부: https://subl.ee/~ndc18.3

자막은 subpptx로 붙였습니다: https://github.com/sublee/subpptx

Published in: Software
  • Be the first to comment

  • Be the first to like this

〈야생의 땅: 듀랑고〉 서버 아키텍처 Vol. 3 - 3부

  1. 1. <야생의 땅: 듀랑고> 서버 아키텍처 Vol. 3 넥슨 • 왓 스튜디오 • 이흥섭 3부
  2. 2. SlideShare에 슬라이드 300장 제한이 생겨서 부득이하게 3부로 나눠서 올렸습니다. 보는 데 불편하시겠지만 양해를 부탁드립니다.
  3. 3. 초반 서버장애
  4. 4. 초반 서버장애 이제 출시 초반에 발생했던 치명적인 서버장애 몇 가지를 되돌아보려고 합니다.
  5. 5. 초반 서버장애 당시에 대해서 궁금해 하셨을 분들이 많을 텐데
  6. 6. 초반 서버장애 이번 기회에 조금이나마 해소해드릴 수 있으면 좋겠습니다.
  7. 7. 해외 CBT 2017년 7월 20일 ~2018년 1월 19일 출시 1주일 전
  8. 8. 해외 CBT 2017년 7월 20일 ~2018년 1월 19일 저희는 6개월동안 태국과 브라질 등 해외에서 진행한 CBT를 마무리하고
  9. 9. 사전예약자 200만 명과 함께
  10. 10. 국내 출시 2018년 1월 25일 오전 10시 2018년 1월 25일 오전 10시
  11. 11. 국내 출시 2018년 1월 25일 오전 10시 드디어 〈야생의 땅: 듀랑고〉를 국내에 출시했습니다.
  12. 12. 국내 출시 2018년 1월 25일 오전 10시 출시하자마자 저희는 크고 작은 문제를 많이 겪었는데요
  13. 13. 주요 사건 1. 인구 과밀화 2. 접속 대기열 장애 3. 데이터베이스 과부하 4. 단일 서버 포기 그 중에서 주요 사건을 뽑아봤습니다.
  14. 14. 주요 사건 1. 인구 과밀화 2. 접속 대기열 장애 3. 데이터베이스 과부하 4. 단일 서버 포기 인구 과밀화와 접속 대기열 장애, DB 과부화
  15. 15. 주요 사건 1. 인구 과밀화 2. 접속 대기열 장애 3. 데이터베이스 과부하 4. 단일 서버 포기 그리고 이런 장애로 인한 단일 서버 포기입니다.
  16. 16. 인구 과밀화1
  17. 17. 인구 과밀화1 처음부터 발생한 문제는 인구 과밀화였습니다.
  18. 18. 인구 과밀화1 재앙의 시작이었죠.
  19. 19. 당시에 찍은 스크린샷인데 한 통신소에 수십 명이 몰려 있는 모습을 볼 수 있습니다.
  20. 20. 스크린샷으로 남기진 못 했지만 수백 명이 몰리는 경우도 있었어요.
  21. 21. 인구 부족 인구 과밀 앞에서 짚었듯이 듀랑고는 섬의 인구밀도에 민감하고
  22. 22. 나아가 한 청크에 너무 많은 플레이어가 몰리면 서버 성능에 큰 타격을 입습니다.
  23. 23. 인구 분배기 •해외 CBT에서 검증했으나 •폭발적인 유입에 취약 이렇게 되지 않도록 인구밀도를 조절하는 장치인 인구 분배기는
  24. 24. 인구 분배기 •해외 CBT에서 검증했으나 •폭발적인 유입에 취약 해외 CBT를 통해서 오랫동안 검증해왔지만
  25. 25. 인구 분배기 •해외 CBT에서 검증했으나 •폭발적인 유입에 취약 국내 출시 때처럼 유입이 폭발적인 상황에는 취약했습니다.
  26. 26. 활성사용자 동시접속자 국내 출시해외 CBT 인구 분배기가 섬의 인구밀도를 판단할 땐
  27. 27. 활성사용자 동시접속자 국내 출시해외 CBT 일정 기간 동안의 활성 사용자 수를 세는데
  28. 28. 활성사용자 동시접속자 국내 출시해외 CBT 출시 직후에 활성 사용자 수 대비 동접이
  29. 29. 활성사용자 동시접속자 국내 출시해외 CBT 이렇게까지 높아질 수 있단 점을 간과했던 겁니다.
  30. 30. 수동 생성 인구 분배기를 개선하기엔 너무 긴박한 상황이었고
  31. 31. 수동 생성 어쩔 수 없이 수동으로 섬을 미리 만들어 놓는
  32. 32. 수동 생성 응급처치를 시행했습니다.
  33. 33. 물론 이런다고 몰려 있던 플레이어들이 알아서 퍼져 나가는 건 아니어서
  34. 34. 과밀화 문제는 한 동안 계속 됐습니다.
  35. 35. 접속 대기열 장애2
  36. 36. 접속 대기열 장애2 오후가 되니 이번엔 접속 대기열에서 장애가 발생했습니다.
  37. 37. 접속 대기열 장애2 아주 유명한 사건이었죠.
  38. 38. 이 장면 보고 실망하신 분 정말 많을 것 같습니다.
  39. 39. 접속 대기열 장애로 인한 MySQL 에러가
  40. 40. 클라이언트에 고스란히 노출됐었는데요
  41. 41. 대기열 장애 자체와는 별개로
  42. 42. 에러 내용이 그대로 노출된 건 정말 창피한 실수였습니다.
  43. 43. 에러 내용 감추기 • 플레이어 서비스 • 로그인 서비스 대부분의 게임플레이가 처리되는 플레이어 서비스 쪽에선
  44. 44. 에러 내용 감추기 • 플레이어 서비스 • 로그인 서비스 에러 내용이 드러나지 않도록 포장 처리가 잘 돼있었지만
  45. 45. 에러 내용 감추기 • 플레이어 서비스 • 로그인 서비스 로그인 서비스 쪽엔 이 처리가 제대로 안 돼있었는데요
  46. 46. 에러 내용 감추기 • 플레이어 서비스 • 로그인 서비스 그동안 초반 진입 단계에서 장애가 일어난 경우가 거의 없어서
  47. 47. 에러 내용 감추기 • 플레이어 서비스 • 로그인 서비스 정말 기초적인 실수임에도 불구하고 미리 발견하지 못 했습니다.
  48. 48. 아무튼 접속 대기열의 작동방식은 이랬습니다.
  49. 49. 딱히 특별할 건 없는데요
  50. 50. 동접 제한에 걸려서 서버에 못 들어간 플레이어들은
  51. 51. 접속을 시도한 순서대로 대기열에 줄을 서게 됩니다.
  52. 52. 이 순서는 클라이언트를 띄워 놓은 동안에만 유지되고
  53. 53. 클라이언트를 끄고 일정한 시간이 흐르면
  54. 54. 대기열에서도 빠지게 되죠.
  55. 55. 7명 각 플레이어에겐 대기열의 앞쪽 길이를 세서 몇 번째인지 알려줍니다.
  56. 56. 접속 대기열 당시 접속 대기열은 MySQL로 구현돼 있었는데요
  57. 57. 접속 대기열 쿼리 설계 상의 실패로
  58. 58. 접속 대기열 풀스캔 유발 서비스 중에 끊임없는 풀스캔을 유발하게 됐습니다.
  59. 59. 접속 대기열 풀스캔 유발 대기열에만 수십만명이 쌓여 있는 상황에서
  60. 60. 접속 대기열 풀스캔 유발 쿼리 처리는 걷잡을 수 없이 느려졌고
  61. 61. 쿼리 지연 •MySQL 락 타임아웃 •MySQL 연결 개수 과다 •MySQL 접속 타임아웃 처리가 오래 걸리다 보니 각종 MySQL 에러가 터지고야 말았습니다.
  62. 62. 접속 대기열 접속 대기열 쿼리의 장애 가능성이 출시 전에 발견되긴 했었는데
  63. 63. 접속 대기열 저희가 그 파괴력을 얕잡아 보고
  64. 64. 문제가 생기더라도 일단은 DB를 증설하는 걸로 버틸 수 있을 거라고
  65. 65. 안일하게 생각했습니다.
  66. 66. 계획했던 대로 바로 DB를 증설하긴 했지만
  67. 67. 일시적으로 완화되는가 싶더니
  68. 68. 머잖아 다시 장애가 발생했습니다.
  69. 69. 증설로는 역부족이었죠.
  70. 70. MySQL 접속 대기열 재구현 Redis 이 전략으론 해결할 수 없을 거란 걸 뒤늦게 깨닫고
  71. 71. MySQL 접속 대기열 재구현 Redis 접속 대기열을 Redis로 재빨리 다시 구현했습니다.
  72. 72. Sorted Set 이때 Redis의 Sorted Set이 크게 도움됐습니다.
  73. 73. 새 구현으로 접속 대기열 장애는 해결할 수 있었습니다.
  74. 74. 서버의 수용인원이 늘어난 건 아니었지만
  75. 75. 적어도 줄만큼은 제대로 설 수 있게 된 거죠.
  76. 76. 데이터베이스 과부하3
  77. 77. 데이터베이스 과부하3 또 하나의 큰 문제였던 DB 과부하는 파악하기 어려운 문제였습니다.
  78. 78. 장애 양상 • 로그인 지연(≥5초) • 사유지 권한 검사 타임아웃 장애 양상은 이랬습니다.
  79. 79. 장애 양상 • 로그인 지연(≥5초) • 사유지 권한 검사 타임아웃 로그인 처리가 느려지고
  80. 80. 장애 양상 • 로그인 지연(≥5초) • 사유지 권한 검사 타임아웃 사유지가 선언된 곳에서 권한 검사를 할 때 타임아웃 나는 경우가 많아졌죠.
  81. 81. N1QL[니켈] SQL for JSON Couchbase Couchbase엔 N1QL이라는 쿼리 언어가 있습니다.
  82. 82. N1QL[니켈] SQL for JSON Couchbase JSON 문서를 색인하고 조회할 수 있는 SQL 같은 거죠.
  83. 83. SELECT * FROM players WHERE ARRAY_LENGTH(inventory) >= 42 AND equipments.weapon.damage < 100 LIMIT 10; 그냥 SQL처럼 생겼죠?
  84. 84. SELECT * FROM players WHERE ARRAY_LENGTH(inventory) >= 42 AND equipments.weapon.damage < 100 LIMIT 10; Couchbase 용 SQL이라고 생각하시면 될 것 같습니다.
  85. 85. SELECT * FROM players WHERE ARRAY_LENGTH(inventory) >= 42 AND equipments.weapon.damage < 100 LIMIT 10; 당시에 발생했던 DB 과부하를 이해하려면
  86. 86. SELECT * FROM players WHERE ARRAY_LENGTH(inventory) >= 42 AND equipments.weapon.damage < 100 LIMIT 10; N1QL이 어떻게 작동하는지 조금 살펴봐야 합니다.
  87. 87. 데이터 서비스 쿼리 서비스인덱스 서비스 N1QL을 쓸 때 Couchbase는 총 세 가지 서비스로 구성됩니다.
  88. 88. N1QL 색인과 검색 데이터 서비스 쿼리 서비스 인덱스 서비스 검색결과 문서 저장 색인 용 정보 저장된 문서가 N1QL로 색인되고 검색되기 까지는
  89. 89. N1QL 색인과 검색 데이터 서비스 쿼리 서비스 인덱스 서비스 검색결과 문서 저장 색인 용 정보 이 세 서비스에 걸친 일련의 과정이 필요합니다.
  90. 90. N1QL 색인과 검색 데이터 서비스 쿼리 서비스 인덱스 서비스 검색결과 문서 저장 색인 용 정보 단순한 키-밸류 저장소인 데이터 서비스에 새로운 문서가 들어오면
  91. 91. N1QL 색인과 검색 데이터 서비스 쿼리 서비스 검색결과 문서 저장 색인 용 정보 인덱스 서비스 데이터 서비스는 색인에 필요한 정보만 추려서
  92. 92. N1QL 색인과 검색 데이터 서비스 쿼리 서비스 검색결과 문서 저장 색인 용 정보 인덱스 서비스 인덱스 서비스로 스트리밍해줍니다.
  93. 93. N1QL 색인과 검색 데이터 서비스 쿼리 서비스 검색결과 문서 저장 색인 용 정보 인덱스 서비스 그러면 인덱스 서비스는 인덱스를 구축해두죠.
  94. 94. N1QL 색인과 검색 데이터 서비스 검색결과 문서 저장 색인 용 정보 인덱스 서비스 쿼리 서비스 쿼리 서비스는 N1QL 쿼리를 해석하고 쿼리 계획을 짜서
  95. 95. N1QL 색인과 검색 데이터 서비스 검색결과 문서 저장 색인 용 정보 인덱스 서비스 쿼리 서비스 인덱스 서비스로부터 검색결과를 구하고 조립하는 역할을 합니다.
  96. 96. N1QL 사용 기능 •로그인 •사유지 권한 검사 •플레이어 검색 •부족 검색 •적정 섬 찾기 저희는 이런 기능에 N1QL을 쓰고 있었는데요
  97. 97. N1QL 사용 기능 •로그인 •사유지 권한 검사 •플레이어 검색 •부족 검색 •적정 섬 찾기 강한 일관성 그 중 문제가 됐던 로그인과 사유지 권한 검사엔
  98. 98. N1QL 사용 기능 •로그인 •사유지 권한 검사 •플레이어 검색 •부족 검색 •적정 섬 찾기 강한 일관성 강한 일관성 옵션이 켜져 있었습니다.
  99. 99. 약한 일관성 강한 일관성 N1QL로 검색할 땐 약한 일관성과 강한 일관성 중에
  100. 100. 약한 일관성 강한 일관성 한 옵션을 선택할 수 있습니다.
  101. 101. 약한 일관성으로 검색 인덱스 서비스 쿼리 서비스 데이터 서비스 약한 일관성으로 검색하면
  102. 102. 약한 일관성으로 검색 인덱스 서비스 쿼리 서비스 데이터 서비스 인덱스 서비스에 이미 쌓여 있던 인덱스에서 검색이 즉시 수행됩니다.
  103. 103. 약한 일관성으로 검색 인덱스 서비스 쿼리 서비스 데이터 서비스 대부분의 경우엔 데이터 서비스에 방금 들어온 따끈따끈한 정보까지 검색할 필요는 없고
  104. 104. 약한 일관성으로 검색 인덱스 서비스 쿼리 서비스 데이터 서비스 이렇게 검색하는 게 더 빠르다 보니 이 옵션을 쓰는 경우가 많습니다.
  105. 105. 강한 일관성으로 검색 데이터 서비스 인덱스 서비스 쿼리 서비스 반면 강한 일관성으로 검색할 땐
  106. 106. 강한 일관성으로 검색 데이터 서비스 인덱스 서비스 쿼리 서비스 데이터 서비스에서 인덱스 서비스로 데이터가 모두 넘어간 후에야
  107. 107. 강한 일관성으로 검색 데이터 서비스 인덱스 서비스 쿼리 서비스 검색결과를 얻을 수 있습니다.
  108. 108. 강한 일관성으로 검색 데이터 서비스 인덱스 서비스 쿼리 서비스 약한 일관성 검색에 비해선 느린 방법이지만
  109. 109. 강한 일관성으로 검색 데이터 서비스 인덱스 서비스 쿼리 서비스 로그인과 사유지 권한처럼
  110. 110. 강한 일관성으로 검색 데이터 서비스 인덱스 서비스 쿼리 서비스 최신 데이터가 누락되면 안 되는 경우엔 꼭 이 옵션을 써야 됩니다.
  111. 111. 한 버킷 Couchbase엔 RDB의 테이블 같이 쉽게 만들 수 있는 콜렉션이 없습니다.
  112. 112. 한 버킷 한 클러스터에 버킷을 여러 개 만들 수 있긴 하지만
  113. 113. 한 버킷 버킷 별로 메모리 사용량을 미리 정해 둬야 하고
  114. 114. 한 버킷 나중에 재설정하는 것도 어려워서
  115. 115. 한 버킷 보통은 버킷을 하나만 두고 여러 종류의 문서를 섞어서 저장합니다.
  116. 116. 색인 용 정보 인덱스 서비스 WHERE type = "estate" 데이터 서비스 그때문에 데이터 서비스에는
  117. 117. 색인 용 정보 인덱스 서비스 WHERE type = "estate" 데이터 서비스 저장되는 문서를 각 인덱스의 조건과 비교해서
  118. 118. 색인 용 정보 인덱스 서비스 WHERE type = "estate" 데이터 서비스 색인이 필요한 문서만 추려내는 기능이 탑재돼 있습니다.
  119. 119. 색인 용 정보 인덱스 서비스 WHERE type = "estate" 데이터 서비스 그리고 이 기능에서 과부하가 발생한 겁니다.
  120. 120. 색인 용 정보 인덱스 서비스 WHERE type = "estate" 데이터 서비스 생각해보면 이 작업은 바뀌고 있는 모든 JSON 문서를
  121. 121. 색인 용 정보 인덱스 서비스 WHERE type = "estate" 데이터 서비스 끊임없이 파싱하는 일일 거라서 상당히 비쌀 것 같습니다.
  122. 122. 인덱스 서비스 WHERE type = "estate" 데이터 서비스 이 과부하로 데이터 서비스에서 인덱스 서비스로 정보가 제때 넘어가지 않게 됐고
  123. 123. 인덱스 서비스 WHERE type = "estate" 데이터 서비스 그로 인해 강한 일관성을 요구하는 쿼리가 모조리 느려졌던 거죠.
  124. 124. CPU 사용률 95%데이터 서비스 당시 모든 데이터 서비스 노드의 CPU 사용률이 95%까지 치솟아서
  125. 125. CPU 사용률 95%데이터 서비스 좀처럼 떨어지지 않는 상황이었습니다.
  126. 126. CPU 사용률 95%데이터 서비스 Couchbase는 주류 DBMS가 아니다 보니 주변에서 다른 전문가도 찾을 수 없어서
  127. 127. CPU 사용률 95%데이터 서비스 문제 파악에 오랜 시간이 걸렸습니다.
  128. 128. CPU 사용률 95%데이터 서비스 또 이 상황에 대한 자료도 쉽게 찾을 수 없었고 때문에 직접 실험하면서 탐구해야만 했죠.
  129. 129. •저장이 빈번할 수록 •저장한 문서 크기가 클 수록 •N1QL 인덱스가 많을 수록데이터 서비스 그 결과 저장이 빈번하고 문서 크기가 클 수록, 그리고 N1QL 인덱스가 많을 수록
  130. 130. •저장이 빈번할 수록 •저장한 문서 크기가 클 수록 •N1QL 인덱스가 많을 수록데이터 서비스 부하가 더 커진다는 걸 알게 됐습니다.
  131. 131. projector 데이터를 인덱스 서비스에 보내는 건 projector라는 프로세스였습니다.
  132. 132. projector projector의 코드는 GitHub에 공개돼 있어서
  133. 133. projector 내부 구현을 들여다볼 수 있었는데요
  134. 134. projector {JSON} 검사 인덱스 1 인덱스 2 인덱스 3검사 검사 객체파싱 저희는 당연히 한 번 파싱한 JSON 문서를
  135. 135. projector {JSON} 검사 인덱스 1 인덱스 2 인덱스 3검사 검사 객체파싱 모든 인덱스의 조건과 비교할 거라고 생각했는데
  136. 136. projector {JSON} 검사 인덱스 1 인덱스 2 인덱스 3검사 검사 객체파싱 놀랍게도 그렇지 않았습니다.
  137. 137. projector {JSON} 검사 인덱스 1 인덱스 2 인덱스 3검사 검사 파싱 파싱 파싱 객체 객체 객체 인덱스 개수만큼 JSON 문서를 중복으로 파싱하는 구조로 돼있었죠.
  138. 138. projector {JSON} 검사 인덱스 1 인덱스 2 인덱스 3검사 검사 파싱 파싱 파싱 객체 객체 객체 의아하긴 했지만
  139. 139. projector {JSON} 검사 인덱스 1 인덱스 2 인덱스 3검사 검사 파싱 파싱 파싱 객체 객체 객체 다행히 이점이 단기적인 해결책을 찾는 데 큰 실마리가 됐습니다.
  140. 140. projector {JSON} 검사 인덱스 1 인덱스 2 인덱스 3검사 검사 파싱 파싱 파싱 객체 객체 객체 전체 N1QL 인덱스 중 절반이 게임플레이가 아닌 운영툴 용이었거든요.
  141. 141. •N1QL 인덱스 최소화 •데이터서비스 증설 데이터서비스 바로 복제 DB를 새로 만들어서
  142. 142. •N1QL 인덱스 최소화 •데이터서비스 증설 데이터서비스 운영툴 용 N1QL 인덱스는 모두 그쪽으로 보내는 조치를 했습니다.
  143. 143. •N1QL 인덱스 최소화 •데이터서비스 증설 데이터서비스 또 데이터 서비스의 노드 수도 대폭 증설해서
  144. 144. •N1QL 인덱스 최소화 •데이터서비스 증설 데이터서비스 한 노드가 처리하는 문서의 개수를 몇 분의 1로 감소시켰죠.
  145. 145. CPU 사용률 60%데이터서비스 그 결과 CPU 사용률은 60%대까지 떨어졌습니다.
  146. 146. CPU 사용률 60%데이터서비스 여전히 높지만 급한 불은 끌 수 있었습니다.
  147. 147. 단일 서버 포기4
  148. 148. 단일 서버 포기4 인구 과밀화 문제와 DB 과부하 등 이런저런 장애를 겪으면서
  149. 149. 단일 서버 포기4 저희는 끝내 단일 서버라는 꿈을 포기하게 됐습니다.
  150. 150. 단일 서버 끝까지 단일 서버라는 욕심을 부리면서도
  151. 151. 아시아 알파 아시아 브라보 아시아 찰리 혹시 모를 상황에 대비해 다중 서버를 준비해두긴 했습니다.
  152. 152. 아시아 알파 아시아 브라보 아시아 찰리 처음부터 세 개의 서버가 구축돼 있었고
  153. 153. 서버 선택 UI도 만들어 뒀었죠.
  154. 154. 아시아 알파 아시아 브라보 아시아 찰리 그래도 가능하면 한 서버만으로 성공적으로 출시하고 싶었습니다.
  155. 155. 아시아 알파 아시아 브라보 아시아 찰리 하지만 첫 서버인 알파서버의 상황은 걷잡을 수 없이 나빠졌고
  156. 156. 아시아 브라보 아시아 찰리아시아 알파 브라보에 이어
  157. 157. 아시아 알파 아시아 브라보 아시아 찰리 다음날엔 찰리까지
  158. 158. 아시아 알파 아시아 브라보 아시아 찰리 준비해둔 세 서버를 모두 열 수밖에 없었습니다.
  159. 159. 하지만 대기열은 여전히 빽빽한 상태였습니다.
  160. 160. 잘못된 DB 연결 풀 게임서버 Couchbase 당시엔 게임서버가 DB 연결 풀을 잘못 사용해서
  161. 161. 잘못된 DB 연결 풀 게임서버 Couchbase 확장성에 문제가 좀 있었는데 그로 인해 서버를 더 증설하면
  162. 162. 잘못된 DB 연결 풀 게임서버 Couchbase DB를 안정적으로 쓸 수 없게 되는 상황이었습니다.
  163. 163. STOP 증설 불가 그때까진 각 서버의 성능을 최대한으로 조절하고 있었지만
  164. 164. STOP 증설 불가 더 이상은 증설할 순 없다는 판단을 내렸습니다.
  165. 165. 아시아 알파 아시아 브라보 아시아 찰리 아시아 델타 아시아 에코 저희는 급하게 새로 두 서버를 구축했고
  166. 166. 드디어 대기열이 비워지기 시작했습니다.
  167. 167. 회고
  168. 168. 회고 출시 초반에 겪었던 심각한 장애들에 대해서
  169. 169. 회고 저희 스튜디오와 회사 내부적으로 깊은 회고와 반성을 진행했습니다.
  170. 170. 균형에 민감 듀랑고 서비스에서 균형은 무엇보다도 중요한 요소였습니다.
  171. 171. 균형에 민감 하지만 저희가 찾았다고 생각했던 균형은
  172. 172. 해외 CBT에 맞춰진 균형 사실은 해외 CBT에 맞춰져 있었습니다.
  173. 173. 폭발적인 유입 그 결과 국내 출시 때의 폭발적인 유입에 제대로 대응하지 못 했고
  174. 174. 무중단 패치 하필이면 이때 무중단 패치도 포기했던 상황이어서
  175. 175. 긴 중단시간 저희가 추구했던 것과는 반대로 긴 중단시간을 가져야만 했습니다.
  176. 176. 하지만 저흰 끝까지 포기하지 않았고
  177. 177. 중단시간이 길었던 만큼 대응에 최선을 다 했습니다.
  178. 178. 한 서버에 7만명 결국 5개의 서버를 열고 난 후
  179. 179. 한 서버에 7만명 한 서버에서 7만명을 받는 데에 성공했습니다.
  180. 180. 한 서버에 7만명 단일서버라는 목표에는 부족한 기록이지만
  181. 181. 한 서버에 7만명 그래도 MMORPG 한 서버의 수용인원으론 작지 않은 숫자를 달성했습니다.
  182. 182. 앞으로
  183. 183. 앞으로 마지막으로 앞으로 듀랑고의 서버를 어떻게 가꿔 나갈지 말씀드리겠습니다.
  184. 184. 다시 단일 서버로 우선 빠른 시일 내에 5개로 나뉜 서버를
  185. 185. 다시 단일 서버로 단일 서버로 합치기 위해 준비 중입니다.
  186. 186. 다시 단일 서버로 지금 각 서버에 나뉘어 있는 캐릭터와 섬 등은
  187. 187. 다시 단일 서버로 하나도 지우지 않고 모두 빠짐없이 한 서버로 합쳐질 예정입니다.
  188. 188. 인구 과밀 최적화 또 한 청크에 수백명이 몰려도 고질적인 서버 랙이 생기지 않도록
  189. 189. 인구 과밀 최적화 개선하는 걸 큰 목표로 삼고 있습니다.
  190. 190. 인구 과밀 최적화 여기엔 고도의 최적화 기법과 넓은 범위의 구조 개편이 필요할 것 같습니다.
  191. 191. 견고한 균형 인구밀도나 청크 당 노드 수 처럼 균형에 민감한 요소도
  192. 192. 견고한 균형 똑똑하게 자동으로 조절돼서 균형 상태가 쉽게 무너지지 않고
  193. 193. 견고한 균형 견고해지도록 만들고자 합니다.
  194. 194. 전세계 단일 서버 이런 방향으로 한 서버의 수용량을 더더욱 높여서
  195. 195. 전세계 단일 서버 다음 마일스톤인 전세계 출시 때는
  196. 196. 전세계 단일 서버 꼭 전세계 단일 서버라는 꿈을 이루고 싶습니다.
  197. 197. 지금까지 〈야생의 땅: 듀랑고〉의 서버가 어떻게 만들어졌고
  198. 198. 출시 때 어떤 장애를 겪었는지, 그 배경엔 어떤 문제가 있었는지 살펴봤습니다.
  199. 199. 저희가 좀 더 잘 준비했더라면
  200. 200. 서버 하나로도 더 멋지게 개장할 수 있었을 것 같은데
  201. 201. 그러지 못해 아쉬움이 많이 남습니다.
  202. 202. 저흴 응원해주신 많은 분들과 유관부서 분들께
  203. 203. 감사하고 죄송한 마음입니다.
  204. 204. 하지만 출시라는 홍역을 치르면서
  205. 205. 단기간에 고질적인 문제를 많이 해결하기도 했습니다.
  206. 206. 남아있는 여러가지 부족한 점을 보완해서
  207. 207. 앞으로의 라이브서비스와 전세계 출시에서
  208. 208. 보다 좋은 모습을 보이기 위해 노력하겠습니다.
  209. 209. 감사합니다 제가 준비한 발표는 여기까지 입니다.
  210. 210. 감사합니다 3부로 나눴음에도 불구하고 끝까지 들어 주셔서 감사합니다.
  211. 211. WE'RE HIRING!http://what.studio/ 마지막으로 저희 왓 스튜디오에선 다양한 직군에서 채용을 진행하고 있습니다.
  212. 212. WE'RE HIRING!http://what.studio/ 혹시 오늘 발표를 들으면서 듀랑고 개발에 직접 참여하고 싶다고 생각하게 되신 분이 있다면
  213. 213. WE'RE HIRING!http://what.studio/ 주저 말고 저희에게 연락주시면 감사하겠습니다.
  214. 214. WE'RE HIRING!http://what.studio/ 이상으로 발표를 마치겠습니다. 감사합니다.
  215. 215. Q&A
  216. 216. Q. 게임 세계의 일관성 유지를 위한 컨센서스 메커니즘이 있나요? A. 다른 노드에 있는 원본 개체의 상태가 고스트로 동기화되긴 하지만 시 간 차이가 있습니다. 일관성에 민감하지 않은 경우 이미 동기화된 정보 만 읽어도 괜찮지만 그렇지 않을 때는 새로운 RPC로 최신 상태를 물어 보는 방식을 쓰고 있습니다. DB 상 여러 문서에 걸친 트랜잭션은 BASE 방식으로 처리하고 있고, 드물지만 글로벌 락이 필요한 경우엔 etcd를 이용하고 있습니다.
  217. 217. Q. 노드 간 RPC 통신 지연에 대한 해결책이 있나요? A. 대부분의 게임플레이는 문제 없지만, 다른 개체와의 일관성에 민감한 몇몇 게임플레이엔 응답 지연이 발생할 것입니다. 현재 타임아웃을 내 는 것 이외에 이 상황에 대한 해결책은 마련돼 있지 않습니다.
  218. 218. Q. NoSQL DBMS 중에서 Couchbase를 선택한 이유가 궁금합니다. A. 넥슨에서 이전 프로젝트를 진행할 때 DevOps 엔지니어의 권유로 Couchbase(당시 Membase)를 사용했습니다. 그때 N1QL 같은 검색 기능은 없었지만 높은 확장성과 빠른 속도는 충분히 매력적으로 다가왔 습니다. 당시의 운영 경험이 좋았고 장단점도 잘 파악하고 있었기에 듀 랑고에서도 Couchbsae를 사용하게 되었습니다.
  219. 219. Q. Couchbase가 백만 단위의 저장/조회에도 문제 없나요? A. 단일 노드의 성능은 그보다 낮을 수 있지만 노드를 추가하는 만큼 성능 을 배로 끌어올릴 수 있습니다. 발표에서도 언급했듯 저희는 초당 170만 회의 저장/조회를 무리 없이 처리하는 걸 경험했습니다.
  220. 220. Q. etcd가 SPOF 아닌가요? A. etcd는 Apache ZooKeeper, HashiCorp Consul과 같은 컨센서스 코디네이터입니다. 컨센서스 코디네이터는 SPOF를 제거하기 위한 분 산 아키텍처를 가지고 있습니다. 더 많은 노드를 운영할 수록 성능은 떨 어지지만 더 많은 장애 노드에 대응할 수 있습니다. 저희는 3개 노드를 사용해 동시에 1개 노드에서 발생하는 장애를 방어 하고 있습니다.

×