#Day 3 - 채팅 시스템 트래픽이 너무 많이 발생해요!!!

책상에서 꾸벅꾸벅 졸고 있는데 다시 전화가 왔다.

전화 : "안녕하세요 시스템팀 김미영 팀장입니다. 어제 신규 패치된 채팅 서버가 추가 될때 마다 IDC 내부 트래픽 그래프가 기하급수적으로 상승하고 있습니다. 아직은 괜찮지만 이대로라면 조만간 최대 허용 트래픽을 초과 할것 같습니다. 확인 부탁 드립니다."

(읭?! 김미영 팀장 어디서 많이 듣던 이름인데...기분 탓이겠지..) 


이 사실을 팀장님께 보고 드리니 아무래도 어제 투입된 채팅 시스템의 브로드캐스팅이 이런 문제를 발생 원인인것 같다고 말씀하시며 팀장님의 생각을 설명 해주셨다.

팀장 : "머신당 수용가능 최대 인원을 1000이라고 가정해보자. 그리고 머신 대수를 M 이라는 변수로 대채 해보자. 사용자 한 명당 한 개의 메시지를 보낸다면 자신을 제외한 모든 채팅 서버에게 메시지를 보내야 하니까...1000 x (M-1) 의 메시지 트래픽이 한 대의 머신에서 발생하겠지? 그런데 이게 총 M 대의 서버에하고 모든 사용자가 동시 채팅 메시지를 보내는 경우 M x (1000 x (M -1)) 의 메시지 트래픽이 발생하게 되는거지. 이게 뭘 의미하는지 알겠니?"

나 : "...음...글쎄요..."

내가 쉽게 답을 하지 못하고 우물거리고 있자 팀장님은 아무 말씀도 하지 않고 담배를 하나 물며 기다리셨다.. 거의 반 개피가 타들어 갈무렵 갑자기 수식 중 한부분이 눈에 들어 왔다.

나 : "아... 위 식을 정리 해보면 1000*M^2 -1000*M 이 되는 군요..여기서 M이 제곱이니까 변수 M이 증가 할때 마다, 즉 서버 머신이 추가 될때 마다 그래프는 기하급수적으로 증가하는 거군요.."

팀장님은 이제 알겠냐는 듯한 웃음을 지으며 저 M의 차수를 줄일 수 있는 방법을 찾아 오라 하신다.

자리로 돌아와 지금의 문제점에 대해 곰곰히 생각해 보았다.

머신 대수를 나타내는 항에서 에서 제곱이 발생한다. 이런 구조라면 사용자가 늘어나 머신이  추가 된다면 트래픽 그래프는 다시 한번 더 기울기가 가파라진다. 원인은 브로드캐스팅이다. 서버간 메시지 전달에 브로드캐스팅 방식을 사용 하면서 전체 머신 만큼의 메시지 트래픽이 발생하고, 모든 머신에서 브로드캐스팅을 하고 있으므로 M^2이라는 항이 생긴 것이다.

그렇다면 브로드캐스팅을 하지 않는다면? 메시지 전달에 유니캐스팅을 사용한다면 최대 그래프의 증가는 제곱이 아니라 선형 그래프를 그릴 것이다. 대상 사용자가 접속해 있는 머신을 알 수만 있다면 해당 머신에 유니캐스팅으로 메시지를 전달하면 된다라는 결론이 났다. 그런데 어떡게 대상사용자가 접속해 있는 머신을 알아내는가가 문제 였다. 그래서 다음 두 가지 방법을 생각해 보았다.

 1. 아직 전달 대상 머신이 어디인지 모르는 경우 전체 채팅 머신을 대상으로 사용자를 찾는 메시지를 브로드캐스팅 한다. 사용자를 가지고 있는 머신에서 응답이 오면 다음 부터는 그 머신에만 메시지를 유니캐스팅 하는 방식.

 2. 사용자가 어느 머신에 접속해 있는지 매핑 테이블을 유지하는 센트럴 시스템을 추가하고 사용자가 채팅 시스템에 접속하면 이 센트럴 시스템에 아이디와 위치를 등록한다. 모든 채팅 메시지는 이 센트럴 시스템으로 보내지고, 센트럴 시스템은 사용자가 있는 경우 해당 머신으로 메시지를 릴레이 하는 방식.

1번 방식의 경우 일단 위치를 알아내고 난 다음 부터는 해당 머신으로 바로 메시지를 전달하므로 메시지 전달 트래픽이 1밖에 되지 않지만 최악의 경우 브로드캐스팅과 똑같은 비용이 든다는 단점이 있다. 예를 들자면 모든 사용자가 현재 접속하지 않은 사용자에게 계속 메시지를 보낸다거나, 채팅 시스템이 방금 시작해 아무런 위치 정보가 없는 시점에 사용자들이 채팅을 시작한다던가 하는 시나리오 말이다,

2번 방식은 센트럴 시스템에 메시지를 보내는 트래픽과 센트럴 시스템이 릴레이 하는 트래픽, 이렇게 매 메시지마다 2의 트래픽 비용이 발생하지만 최대 트래픽이 (1x1000+1x1000)xM 만큼으로 일정한 선형 그래프를 그린다는 장점이 있다.

1번과 2번 모두 각자의 장단점이 있긴하지만 나는 최악의 경우 트래픽이 선형 증가를 하는 시스템이 더 안정적이라고 판단 2번 방식을 택하기로 했다.

그래서 다음과 같은 디자인이 나왔다 :
 


팀장님이 트래픽 사용으로 회사에서 지불하는 비용도 무시할 수 없이 크므로 오늘 내로 패치를 해야 한다고 하신다.
오늘도 뜨는 아침 해를 보며 센트럴 시스템과 기존 채팅서버에 센트럴 서버와 통신하는 인터페이스를 완성 했다.

입사 삼 일째, 집에 가지 못한 시간도 삼일째..피곤하다..책상이 아닌 이불에서 자고 싶다...ㅠㅠ

[발로 그리는 분산 시스템] - 발로 그리는 분산 시스템 #Day 1 - 발로 그리는 채팅 시스템 
[발로 그리는 분산 시스템] - 발로 그리는 분산 시스템 #Day 2 - 채팅 서버에 접속이 안되요!!

Posted by kukuta

댓글을 달아 주세요

  1. BlogIcon 김경모 2012.02.20 23:34  댓글주소  수정/삭제  댓글쓰기

    아 지나가던 쪼그만한 학생입니다 ㅎㅎ.
    실제로 입사하자마자 시스템을 개발해라 하고서 (비록 채팅 서비스지만 ㅎㅎ...)
    오늘 안에 되겠니? 하고 하는 무서운 경우가...
    있을거라는 무서운 생각을 하면서 3일차까지 보고있습니다 ㅎㅎ.

    사내 에서 브로드 캐스팅을 하더라도 트래픽이 많이 발생하는군요 ㄷㄷㄷㄷ....
    역시 사람을 찾기위해서 그때 마다 서버를 찾기에는..... 무리가 따르죠 ㅎㅎ
    (물론 . 색인 작업을을위한 사용자를 알파벳 순(이름순)으로 정리해서 서버에 차곡 차곡 쌓을수있다는 무식한 생각도해보지만 ㅎㅎ..서버가 역시 효율적으로 유저관리를 하기가.. 알고리즘을 다시짜야하니 ㅎㅎ)

    센트롤 시스템을 통한 (사용자가 접속하고 나갈때마다 센트롤 테이블의 유저 테이블을 업데이트하면 ㅎ..)
    게 좋다고 생각이되네요 ㅎㅎ..
    사용자별로 n번 브로드 캐스팅을 한다면은

    1000명의 유저가 10개의 서버에있는 사용자를 찾기위해서는 ...
    최대10000 번의 메시지를보내야겠죠.... 물론... 첫 메시지에만 한정이 되겠지만 ㅎㅎ..
    엄청난 트래픽이.... n*m*1/2 의 복잡도란 ㄷㄷ

    하지만 두번째 방법은 첫메시지 2n의 시간 복잡도를 갖고 . 이후에 상대편이 나갔을때에만
    그유저가 있는 머신에 메시지를 보내서 다시 접속 확인을 할수있는 시스템이 구축...이 될라나요 ㅋㅋ앜...
    (수식은 틀렸지만 이게 효율적이라고 생각함니다 ㅎㅎ!!)

    물론 두번째 경우든 첫번때 경우든 메시지가 전송이 됬다는 ask 메시지나 확인 법
    그리고 그후에 유저를 다시 검색하고 이사람이 없다면은 접속이 실패했다는 메시지도 메시지를 전송한 사람에게 알려줘야하는 부담이있네요 ㅎㅎ.

    물론 리니지의 장사 채팅 같은 경우는 브로드 캐스트로 ^^.~!!

    괜히 니자가다가 주저리 주저리 해봄니다 ㅎㅎ..

    흥미 진진하고 재밌네요 ㅋㅋㅋ...

  2. Favicon of http://kukuta.tistory.com BlogIcon kukuta 2012.02.23 23:22  댓글주소  수정/삭제  댓글쓰기

    1번 방식은 사실 한번으로 끝나는 것이 아닙니다. 없는 사용자에 대해서 계속 검색을 하게 된다면 결국 지속적으로 브로드캐스팅을 하는 것이나 다름 없습니다. 최악의 경우를 고려한다면 브로드캐스팅 정도의 비용이 지불 됩니다.
    2번 경우엔 사용자 로긴과 로그아웃을 처리해주면 보낼 수 없는 사용자에 대한 처리도 보다 쉬워지지요.

    다만 여기서 빠진 이야기가 있는데 결국 센트럴 릴레이 서버가 병목이 될 수도 있습니다. 이에 대한 분산 정책도 나중에 다룰 예정입니다ㅎㅎ

    관심있게 지켜봐 주셔서 감사합니다.

    • BlogIcon 김경모 2012.02.27 13:17  댓글주소  수정/삭제

      아 ㅋㅋ
      중앙에서 처리해주는 중앙 릴레이 서버 녀석도 고려해야되는군요 이런 ㅋㅋ

      저도 안드로이드 메신저 서버에대해서 생각해보다가 수천만이나되는 ㄷㄷㄷ 유저에게 메시지를 보내는 대규모 메신저 서버에대해서 궁금했었거든요 ㄷㄷㄷㄷ ㅋㅋ 비슷할라나 ㅋㅋㅋ...앜 ㅋㅋㅋ

      곧 개강이니 ㅠㅠ 네트워크 교수님한테 물어봐야지요 ㅎㅎㅎ

      재밌게 보고감니다 ^^*

Day 2 - 채팅 서버에 접속이 안되요!!
채팅 서버를 실서버에 반영하고 피로에 지쳐 잠이 들었다. 전지현과 손예진이 서로 나랑 사귀겠다며 싸우는 꿈을 한참 꾸고 있는데 전화가 왔다. 여자다.
전화 : "안녕하세요. 운영팀 김미영 팀장입니다. 12시 부터 게임에 접속 할 수 없다는 메시지와 함께 클라이언트가 다운 되고 있습니다. 조속한 조치 부탁드립니다."

젠장..접속이 안된다니. 게임에 접속해 보니(처음으로 우리 회사 게임에 접속했다!!) 정말 게임에 접속 할 수 없다는 메시지와 함께 클라이언트가 다운된다. 클라이언트 개발자에게 디버깅을 문의하니 채팅 서버에서 더 이상 접속을 받을 수 없다는 에러 코드를 리턴한단다.

우리 게임 평균 동접이 1만인데 채팅 서버는 동접 1천 밖에 받지 못 했던 것이다. 급하게 시스템 팀에 연락해 채팅 서버 10대를 추가 하고 운영팀에 문제 상황이 해결 되었다고 응답해 주었다.

시스템이 정상 동작 하는지 모니터링 하다 나도 모르게 다시 잠이 들었다.

30분 정도 잠들었나 싶었을 무렵 다시 전화가 울린다.
전화 : "안녕하세요. 운영팀 김미영 팀장입니다. 접속 할 수 없다는 메시지는 더 이상 뜨지 않는데요. 사용자들간에 채팅이 되지 않는다고 합니다. 확인 부탁 드립니다."

읭? 채팅이 되지 않는다고? 다시 게임에 접속해 클라이언트 개발자와 테스트를 해봤다. 어라..? 잘 되는데? 접속을 끊고 다시 테스트 해보니 이번에는 되지 않는다!! 서버 로그를 살펴 보니 해당 사용자를 찾을 수 없다는 메시지다. 분명히 접속 중인데..아..다른 서버에 접속 중이었다. 내가 만든 채팅 서버는 서버간 메시지 전송 기능이 없던 것이었다.

팀장님이 원래 채팅 시스템은 없던 서비스였기 때문에 아직 사용하는 사람들이 그렇게 많지는 않다고 하시며 어서 패치 하라고 하신다. 그래서 다음과 같은 설계도를 그렸다.

채팅 메시지를 받고 로컬 머신에서 전달 대상을 찾지 못하면 전체 시스템으로 브로드캐스팅 하는 방식이다. 채팅 메시지를 받은 서버는 로컬에 있는 사용자면 메시지를 전달 하고, 사용자가 로컬에 없는 경우에는 메시지를 무시 한다. 
브로드캐스팅 기능만 추가 하는 것이기 때문에 금방 끝날 줄 알았는데 의외로 개발하는데 시간이 많이 걸렸다. 결국 다시 아침을 뜬 눈으로 맞았다.

간단한 테스트 후 시스템 팀에 연락하여 새로운 서버를 서비스에 반영했다. 이제 어떤 채팅 서버에 접속하던지 메시지를 못 받는 상황이 해결 되었다. 입사 이틀 째, 집에 가지 못한 시간도 이틀째..피곤하다..집에 가고 싶다..ㅠㅠ
 
[발로 그리는 분산 시스템] - 발로 그리는 분산 시스템 #Day 1 - 발로 그리는 채팅 시스템

Posted by kukuta

댓글을 달아 주세요

/**
한 대의 머신이 처리 할 수 있는 cpu 파워와 memory, kernel object에는 한계가 있고 이를 극복하기 위해 분산 시스템이라는 것을 구축한다. 이번 포스팅 시스즈에서는 connection 한계를 극복하는 방법과 그러기 위해 고려할 사항들을 생각 해보자.
*/
나는 대학을 졸업하자 마자 꿈에도 그리던 게임 업계에 취직했다. 직원이 채 10명도 안되는 작은 회사이긴 하지만 청년 실업 60만에 육박하는 이 사회에서 졸업과 동시에 취업이라니 얼마나 뿌듯한가!!
첫 출근하니 팀장이라는 분이 나를 맞아 주었다.
'우리 회사는 출시한 게임은 몇개 안되지만 그래도 최대 동접 네 자리를 자랑하는..' 주저리 주저리..뭔 말인지도 모를 회사 소개가 끝나고 팀원들 소개로 이어졌다..아니..그냥 팀원 소개였다..(지금 까지 PM 역할을 하는 팀장과 개발자 단 둘이서 게임을 만들어 왔다고 한다)..팀원은..남자 였다..(그냥 그랬다는 거다..)
자리를 배정 받고 앉아서 컴퓨터를 켜자 마자 팀장님이 자리로 오시더니 이번에 우리 게임에서 채팅 시스템이 추가 된다고 한다..(읭? 동접 네자리 게임이 채팅도 안된거야?!)..내가 만든 것이 바로 실 서비스 투입 될 거라고 하니 잘 만들어 달란다..아직 아무 것도 모르는 어리버리긴 하지만 입사 하자마자 뭔가 중요한 일을 맡은것 같아 기분이 좋다.
미션 1 : 채팅 시스템을 구축하라!!
팀장님이 개발하기 전에 먼저 시스템 설계를 하는 것이 좋다고 하며 자기가 검토해 줄테니 설계도를 그려 오라고 한다. 누가 봐도 알수 있도록 그리는 것이 포인트라고 한마디 덧붙여 주시는 것도 잊지 않으셨다.
그렇지 학교 다닐 때 항상 아무런 생각 없이 코드 부터 먼저 짜다 엎었던 적이 한두번이 아니었지..
진중한 마음으로 설계에 대해서 고민하기 시작 했다. 

# Day 1 - 발로 그리는 채팅 시스템 하루 종일 채팅 시스템을 어떻게 만들어야 하나 고민 하다 아래와 같은 설계도를 만들었다. 센스 있게 'ㅋ'도 넣었다. 팀장님이 보시면 좋아 하실것 같다 :-)

설계도를 팀장님께 보여드리니 아무말 없이 설계도만 보고 계신다. 읭?! 저 쉬운 설계도가 이해가 안 가시나? 누가 봐도 알수 있도록 엄청 직관적으로 그린건데..
한참을 들여만 보시더니 갑자기 긴 한숨과 함께 담배를 입에 무시며 오늘 까지 만들 수 있겠냐고 하신다..
자신 있게 '네!' 라고 대답하니 그럼 이대로 개발 하란다. 역시 한번에 통과 했다. 후딱 후딱 빨리 빨리 만들고 퇴근하자!!라고 했지만 채팅 서버 하나 만드는데도 하루가 꼬박 걸렸다. 아...해뜬다...집에 가고 싶다...


[발로 그리는 분산 시스템] - 발로 그리는 분산 시스템 #Day 2 - 채팅 서버에 접속이 안되요!!
Posted by kukuta

댓글을 달아 주세요

  1. 2012.02.17 16:44  댓글주소  수정/삭제  댓글쓰기

    비밀댓글입니다

    • Favicon of https://kukuta.tistory.com BlogIcon kukuta 2012.02.20 00:32 신고  댓글주소  수정/삭제

      발로 그리는 분산 시스템은 시간이 나는 대로 짬짬이 계속 연재 할 생각 입니다. 가끔 들려 주셔서 부족한 부분이 있으면 조언 부탁 드릴게요.