SCALABILITY

DISTRIBUTED
채팅  서버  적용사례를  통한  분산서버  관리  방법  알아보기
github.com/xpush/node-­‐xpush
#  효과적인  부하  분산은  어떻게  하면  좋을까?
그냥  Round  Robin  하면  된다.
#  그런데..  대용량  처리를  위한  채팅  서버라면,  좀  다른  것  같다.
#  수십만명이  동시에  접속하는  온라인  인터넷  방송  ‘America  TV’  의  
      채팅  기능을  구현한다고  생각하자.
#  채팅  서버만해도  수십대  또는  수백대가  필요할  것인데,  
      어떻게  부하  분산하고  무중단  확장할  수  있을까?
실제로  이런거  없음.  그냥  예를  들어..
#  네트워크  비용을  최소화  하고,  성능을  극대화  하기  위한  방법이  필요하다
#  로컬  통신을  극대화  하기  위한  분산  기법이  될  수  있겠다.
분산  서버  아키텍처  설계는  네트워크  비용이  커질  수  밖에  없지.    분산된  서버들간에  데이터  통신이나  데이터  공유가  필요하니까  말이다.
분산  서버  아키텍처  설계에서  최대한으로  서버간  데이터  전송을  하지  않도록  해야  한다.  물론  모든  경우에  적합하지는  않다.채팅  같은  경우가  적합하겠지  말이다.
비용이라고,  꼭  돈만이  아니다!
이런거  크게  신경  쓰기  싫다면,  역시  Round  Robin  하면  된다.
#  채팅  서버가  어떻게  구성되어  있는지  부터  보자  !
#  분산된  채팅  서버를  할당해주는  Session  서버를  별도로  만들었다.
Session  Server  
-­‐ 채팅방  별  Channel  서버  할당

(할당할  서버목록을  가지고  있어야  함)  
-­‐ Channel  서버  접속을  위한  인증
Channel  Server  
-­‐ 실시간  메시지  송수신  처리  (채팅  서버)  
-­‐ 모든  Client  는  Channel  서버에  접속  유지  
-­‐ Client  수에  따라  유동적으로  Scale-­‐out  필요
session  서버는  zookeeper  의  channel  서버  목록을  동기화  하고  있다.
channel  서버가  실행되면,  zookeeper  에  znode를  생성
server  /  A^123.45.67.01:9001  
                            B^123.45.67.01:9002  
                            C^123.45.67.01:9001  
                            D^123.45.67.01:9002  
                            E^123.45.67.01:9001  
                            F^123.45.67.01:9002  
                            G^123.45.67.01:9001  
                            H^123.45.67.01:9002
Session  Server
Channel  Server  A
.  
.  
.  
.  
zookeeper
Channel  Server  B
Channel  Server  C Channel  Server  D
Channel  Server  E Channel  Server  F
Channel  Server  G Channel  Server  H
.  
.  
.  
.  
watching
create  Node
123.45.67.01:9001 123.45.67.01:9002
123.45.67.02:9001 123.45.67.02:9002
123.45.67.03:9001 123.45.67.03:9002
123.45.67.04:9001 123.45.67.04:9002
#  가장  먼저,  Session  서버는  접속할  Channel  Server  정보를  알려  준다.
server  /  A^123.45.67.01:9001  
                            B^123.45.67.01:9002  
                            C^123.45.67.02:9001  
                            D^123.45.67.02:9002  
                            E^123.45.67.03:9001  
                            F^123.45.67.03:9002  
                            G^123.45.67.04:9001  
                            H^123.45.67.04:9002
Session  Server
Channel  Server  A
.  
.  
.  
.  
zookeeper
Channel  Server  B
Channel  Server  C Channel  Server  D
Channel  Server  E Channel  Server  F
Channel  Server  G Channel  Server  H
.  
.  
.  
.  
watching
create  Node
123.45.67.01:9001 123.45.67.01:9002
123.45.67.02:9001 123.45.67.02:9002
123.45.67.03:9001 123.45.67.03:9002
123.45.67.04:9001 123.45.67.04:9002
hDps://session-­‐server/node/americatv/kimeve
hDps://session-­‐server/node/americatv/yumdaeng
채팅방  -­‐  kimeve
채팅방  -­‐  yumdaeng
server  :  C,  url  :  123.45.67.02:9001
server  :  F,  url  :  123.45.67.03:9002
-­‐ 실제로,  Session  서버는  client  의  접속  인증처리도  함께  해야  하기  때문에,  인증  Token  을  생성하여  Client  에  전달해야  할  것이다.  (인증  토큰은  Client  가  Channel  Server  에  접근할  때  함께  전달한다.)
#  그  다음,  Client  는  할당받은  channel  서버에  접속해서  메시지를  송수신  한다.
server  /  A^123.45.67.01:9001  
                            B^123.45.67.01:9002  
                            C^123.45.67.02:9001  
                            D^123.45.67.02:9002  
                            E^123.45.67.03:9001  
                            F^123.45.67.03:9002  
                            G^123.45.67.04:9001  
                            H^123.45.67.04:9002
Session  Server
Channel  Server  A
.  
.  
.  
.  
zookeeper
Channel  Server  B
Channel  Server  C Channel  Server  D
Channel  Server  E Channel  Server  F
Channel  Server  G Channel  Server  H
.  
.  
.  
.  
watching
create  Node
123.45.67.01:9001 123.45.67.01:9002
123.45.67.02:9001 123.45.67.02:9002
123.45.67.03:9001 123.45.67.03:9002
123.45.67.04:9001 123.45.67.04:9002
채팅방  -­‐  kimeve
채팅방  -­‐  yumdaeng
channel  :  kimeve  
server  :  C

url  :  123.45.67.02:9001
channel  :  yumdaeng  
server  :  F

url  :  123.45.67.03:9002
socket  (TCP)
socket  (TCP)
-­‐ 실제로,  Client  가  Channel  Server  에  연결  요청할  때는,  인증  토큰을  함께  전달하고,  Channel  Server  는  인증  토큰이  유효한  값인지  확인하고  ConnecOon  을  맺어야  할  것이다.
같은  채팅방에  있는  Client  는  모두  같은  서버에  접속하게  해서,  Local  통신하게  하자  !!  (  네트워크  비용이나,  성능  향상  )
#  그럼  이제  본론이다.  
      Session  서버는  어떻게  Channel  서버를  할당해야  할까?
#  STEP  1.  Consistent  Hashing
server  /  A^123.45.67.01:9001  
                            B^123.45.67.01:9002  
                            C^123.45.67.01:9001  
                            D^123.45.67.01:9002  
                            E^123.45.67.01:9001  
                            F^123.45.67.01:9002  
                            G^123.45.67.01:9001  
                            H^123.45.67.01:9002
Session  Server
Channel  Server  A
.  
.  
.  
.  
zookeeper
Channel  Server  B
Channel  Server  C Channel  Server  D
Channel  Server  E Channel  Server  F
Channel  Server  G Channel  Server  H
.  
.  
.  
.  
watching
create  Node
123.45.67.01:9001 123.45.67.01:9002
123.45.67.02:9001 123.45.67.02:9002
123.45.67.03:9001 123.45.67.03:9002
123.45.67.04:9001 123.45.67.04:9002
zookeeper  로  부터  동기화  되는  서버  목록  데이터를  기반으로

Session  서버에는  Consistent  Hashing  함수  구현한다.
A
B
C
D
value
 =
 HASH(key)
Service
 Server
Token
 Ring
#  STEP  1.  Consistent  Hashing
A
B
C
D
value
 =
 HASH(key)B C
D
A
B
C
D
D
A
B
C
D
A
B
CAB
C
D
A
B
C
A
A
B
C
D
A
B C
D
value
 =
 HASH(key2)
#  STEP  1.  Consistent  Hashing  -­‐  replica  !!
A
B
C
D
B C
D
A
B
C
D
D
A
B
C
D
A
B
CAB
C
D
A
B
C
A
A
B
C
D
A
B C
D
value
 =
 HASH(key2)
value
 =
 HASH(key)
#  STEP  1.  Consistent  Hashing
https://weblogs.java.net/blog/tomwhite/archive/2007/11/consistent_hash.html
standard  devia@on
#  STEP  1.  Consistent  Hashing
#  그런데,  
      Channel  서버가  추가되거나  삭제되면,  Consistent  Hashing  값이  달라진다.
kimeve  채팅방은  Channel  Server  C  를  할당했다.  신규  Channel  Server  를  추가해서  Consistent  Hashing  을  갱신했더니,    이제  Channel  Server  F  를  할당하더라.
#  STEP  2.  Using  allocaRon  data  table
Session  Server
Channel  Server  A
.  
.  
.  
.  
zookeeper
Channel  Server  B
Channel  Server  C Channel  Server  D
Channel  Server  E Channel  Server  F
Channel  Server  G Channel  Server  H
.  
.  
.  
.  
watching
create  Node
123.45.67.01:9001 123.45.67.01:9002
123.45.67.02:9001 123.45.67.02:9002
123.45.67.03:9001 123.45.67.03:9002
123.45.67.04:9001 123.45.67.04:9002
REDIS
hDps://session-­‐server/node/americatv/kimeve
Consistent  Hashing  함수를  통해  ‘Channel  Server  C’  를  할당한다.
HSET
socket  (TCP)
kimeve    :    C    :    1
접속한  정보는  실시간으로  REDIS  에서  관리한다.
KEY 서버이름
현재  접속자  수

(당연히,  처음  적속했다면  1  이다)
GET
In-­‐Memory  DB  에  현재  접속  정보를  관리하고,  서버  할당시  확인한다.
속도  때문에  redis  를  사용했지,  꼭  이것만  할  수  있는건  아니다.
REDIS  에  서버  접속  정보가  있는지  확인한다.

KEY값이  kimeve  인  데이터가  REDIS  에  있는지  확인한다.
1
2
3
Session  Server
Channel  Server  A
.  
.  
.  
.  
zookeeper
Channel  Server  B
Channel  Server  C Channel  Server  D
Channel  Server  E Channel  Server  F
Channel  Server  G Channel  Server  H
.  
.  
.  
.  
watching
create  Node
123.45.67.01:9001 123.45.67.01:9002
123.45.67.02:9001 123.45.67.02:9002
123.45.67.03:9001 123.45.67.03:9002
123.45.67.04:9001 123.45.67.04:9002
REDIS
hDps://session-­‐server/node/americatv/kimeve
REDIS  에서  조회한  Channel  Server  C  정보를  반환한다.
HSET
socket  (TCP)
kimeve    :    C    :    2
접속한  정보는  실시간으로  REDIS  에서  관리한다.
KEY 서버이름
현재  접속자  수

현재  접속자  수는  Channel  Server  에서  구해서

REDIS  의  값을  갱신한다.

(이제  2명이  되었다!)
GET
In-­‐Memory  DB  에  현재  접속  정보를  관리하고,  서버  할당시  확인한다.
이미  접속한  Client
REDIS  에  서버  접속  정보가  있는지  확인한다.  있다!!!

KEY값이  kimeve  인  데이터가  REDIS  에  있는지  확인한다.
1
2
3
새로  접속하는  2번째  client
#  STEP  2.  Using  allocaRon  data  table
Session  Server
Channel  Server  A
zookeeper
Channel  Server  B
Channel  Server  C Channel  Server  D
Channel  Server  E Channel  Server  F
Channel  Server  G Channel  Server  H
.  
.  
.  
.  
watching
create  Node
123.45.67.01:9001 123.45.67.01:9002
123.45.67.02:9001 123.45.67.02:9002
123.45.67.03:9001 123.45.67.03:9002
123.45.67.04:9001 123.45.67.04:9002
REDIS
HSET
kimeve    :    C    :    2
GET
Channel  Server  I
신규  추가된  Channel  서버
123.45.67.05:9001
server  /  A^123.45.67.01:9001  
                            B^123.45.67.01:9002  
                            C^123.45.67.02:9001  
                            D^123.45.67.02:9002  
                            E^123.45.67.03:9001  
                            F^123.45.67.03:9002  
                            G^123.45.67.04:9001  
                            H^123.45.67.04:9002  
                              I  ^123.45.67.05:9002Zookeeper  에  Node  생성
Consistent  Hashing  갱신  !!!
kimeve  채팅방은
Consistent  Hashing  결과  값은  C  였지만,
Channel  Server  I  가  추가된  후
Consistent  Hashing  결과  값이  H  가  되었다.
하지만,
REDIS  에는  C  이므로,
kimeve  채팅방에  C  를  할당할  수  있다.
만약,  kimeve  채팅방이  다시  만들어  진다면,
그때는  H를  할당  한다.
#  STEP  2.  Using  allocaRon  data  table

채팅서버의 부하 분산 사례

  • 1.
    SCALABILITY
 DISTRIBUTED 채팅  서버  적용사례를 통한  분산서버  관리  방법  알아보기 github.com/xpush/node-­‐xpush
  • 2.
    #  효과적인  부하 분산은  어떻게  하면  좋을까? 그냥  Round  Robin  하면  된다.
  • 3.
    #  그런데..  대용량 처리를  위한  채팅  서버라면,  좀  다른  것  같다.
  • 4.
    #  수십만명이  동시에 접속하는  온라인  인터넷  방송  ‘America  TV’  의        채팅  기능을  구현한다고  생각하자. #  채팅  서버만해도  수십대  또는  수백대가  필요할  것인데,        어떻게  부하  분산하고  무중단  확장할  수  있을까? 실제로  이런거  없음.  그냥  예를  들어..
  • 5.
    #  네트워크  비용을 최소화  하고,  성능을  극대화  하기  위한  방법이  필요하다 #  로컬  통신을  극대화  하기  위한  분산  기법이  될  수  있겠다. 분산  서버  아키텍처  설계는  네트워크  비용이  커질  수  밖에  없지.    분산된  서버들간에  데이터  통신이나  데이터  공유가  필요하니까  말이다. 분산  서버  아키텍처  설계에서  최대한으로  서버간  데이터  전송을  하지  않도록  해야  한다.  물론  모든  경우에  적합하지는  않다.채팅  같은  경우가  적합하겠지  말이다. 비용이라고,  꼭  돈만이  아니다! 이런거  크게  신경  쓰기  싫다면,  역시  Round  Robin  하면  된다.
  • 6.
    #  채팅  서버가 어떻게  구성되어  있는지  부터  보자  !
  • 7.
    #  분산된  채팅 서버를  할당해주는  Session  서버를  별도로  만들었다. Session  Server   -­‐ 채팅방  별  Channel  서버  할당
 (할당할  서버목록을  가지고  있어야  함)   -­‐ Channel  서버  접속을  위한  인증 Channel  Server   -­‐ 실시간  메시지  송수신  처리  (채팅  서버)   -­‐ 모든  Client  는  Channel  서버에  접속  유지   -­‐ Client  수에  따라  유동적으로  Scale-­‐out  필요 session  서버는  zookeeper  의  channel  서버  목록을  동기화  하고  있다. channel  서버가  실행되면,  zookeeper  에  znode를  생성 server  /  A^123.45.67.01:9001                              B^123.45.67.01:9002                              C^123.45.67.01:9001                              D^123.45.67.01:9002                              E^123.45.67.01:9001                              F^123.45.67.01:9002                              G^123.45.67.01:9001                              H^123.45.67.01:9002 Session  Server Channel  Server  A .   .   .   .   zookeeper Channel  Server  B Channel  Server  C Channel  Server  D Channel  Server  E Channel  Server  F Channel  Server  G Channel  Server  H .   .   .   .   watching create  Node 123.45.67.01:9001 123.45.67.01:9002 123.45.67.02:9001 123.45.67.02:9002 123.45.67.03:9001 123.45.67.03:9002 123.45.67.04:9001 123.45.67.04:9002
  • 8.
    #  가장  먼저, Session  서버는  접속할  Channel  Server  정보를  알려  준다. server  /  A^123.45.67.01:9001                              B^123.45.67.01:9002                              C^123.45.67.02:9001                              D^123.45.67.02:9002                              E^123.45.67.03:9001                              F^123.45.67.03:9002                              G^123.45.67.04:9001                              H^123.45.67.04:9002 Session  Server Channel  Server  A .   .   .   .   zookeeper Channel  Server  B Channel  Server  C Channel  Server  D Channel  Server  E Channel  Server  F Channel  Server  G Channel  Server  H .   .   .   .   watching create  Node 123.45.67.01:9001 123.45.67.01:9002 123.45.67.02:9001 123.45.67.02:9002 123.45.67.03:9001 123.45.67.03:9002 123.45.67.04:9001 123.45.67.04:9002 hDps://session-­‐server/node/americatv/kimeve hDps://session-­‐server/node/americatv/yumdaeng 채팅방  -­‐  kimeve 채팅방  -­‐  yumdaeng server  :  C,  url  :  123.45.67.02:9001 server  :  F,  url  :  123.45.67.03:9002 -­‐ 실제로,  Session  서버는  client  의  접속  인증처리도  함께  해야  하기  때문에,  인증  Token  을  생성하여  Client  에  전달해야  할  것이다.  (인증  토큰은  Client  가  Channel  Server  에  접근할  때  함께  전달한다.)
  • 9.
    #  그  다음, Client  는  할당받은  channel  서버에  접속해서  메시지를  송수신  한다. server  /  A^123.45.67.01:9001                              B^123.45.67.01:9002                              C^123.45.67.02:9001                              D^123.45.67.02:9002                              E^123.45.67.03:9001                              F^123.45.67.03:9002                              G^123.45.67.04:9001                              H^123.45.67.04:9002 Session  Server Channel  Server  A .   .   .   .   zookeeper Channel  Server  B Channel  Server  C Channel  Server  D Channel  Server  E Channel  Server  F Channel  Server  G Channel  Server  H .   .   .   .   watching create  Node 123.45.67.01:9001 123.45.67.01:9002 123.45.67.02:9001 123.45.67.02:9002 123.45.67.03:9001 123.45.67.03:9002 123.45.67.04:9001 123.45.67.04:9002 채팅방  -­‐  kimeve 채팅방  -­‐  yumdaeng channel  :  kimeve   server  :  C
 url  :  123.45.67.02:9001 channel  :  yumdaeng   server  :  F
 url  :  123.45.67.03:9002 socket  (TCP) socket  (TCP) -­‐ 실제로,  Client  가  Channel  Server  에  연결  요청할  때는,  인증  토큰을  함께  전달하고,  Channel  Server  는  인증  토큰이  유효한  값인지  확인하고  ConnecOon  을  맺어야  할  것이다. 같은  채팅방에  있는  Client  는  모두  같은  서버에  접속하게  해서,  Local  통신하게  하자  !!  (  네트워크  비용이나,  성능  향상  )
  • 10.
    #  그럼  이제 본론이다.        Session  서버는  어떻게  Channel  서버를  할당해야  할까?
  • 11.
    #  STEP  1. Consistent  Hashing server  /  A^123.45.67.01:9001                              B^123.45.67.01:9002                              C^123.45.67.01:9001                              D^123.45.67.01:9002                              E^123.45.67.01:9001                              F^123.45.67.01:9002                              G^123.45.67.01:9001                              H^123.45.67.01:9002 Session  Server Channel  Server  A .   .   .   .   zookeeper Channel  Server  B Channel  Server  C Channel  Server  D Channel  Server  E Channel  Server  F Channel  Server  G Channel  Server  H .   .   .   .   watching create  Node 123.45.67.01:9001 123.45.67.01:9002 123.45.67.02:9001 123.45.67.02:9002 123.45.67.03:9001 123.45.67.03:9002 123.45.67.04:9001 123.45.67.04:9002 zookeeper  로  부터  동기화  되는  서버  목록  데이터를  기반으로
 Session  서버에는  Consistent  Hashing  함수  구현한다.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
     Ring #  STEP  1. Consistent  Hashing
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
     HASH(key2) #  STEP  1. Consistent  Hashing  -­‐  replica  !!
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
     HASH(key) #  STEP  1. Consistent  Hashing
  • 27.
  • 28.
    #  그런데,        Channel  서버가  추가되거나  삭제되면,  Consistent  Hashing  값이  달라진다. kimeve  채팅방은  Channel  Server  C  를  할당했다.  신규  Channel  Server  를  추가해서  Consistent  Hashing  을  갱신했더니,    이제  Channel  Server  F  를  할당하더라.
  • 29.
    #  STEP  2. Using  allocaRon  data  table Session  Server Channel  Server  A .   .   .   .   zookeeper Channel  Server  B Channel  Server  C Channel  Server  D Channel  Server  E Channel  Server  F Channel  Server  G Channel  Server  H .   .   .   .   watching create  Node 123.45.67.01:9001 123.45.67.01:9002 123.45.67.02:9001 123.45.67.02:9002 123.45.67.03:9001 123.45.67.03:9002 123.45.67.04:9001 123.45.67.04:9002 REDIS hDps://session-­‐server/node/americatv/kimeve Consistent  Hashing  함수를  통해  ‘Channel  Server  C’  를  할당한다. HSET socket  (TCP) kimeve    :    C    :    1 접속한  정보는  실시간으로  REDIS  에서  관리한다. KEY 서버이름 현재  접속자  수
 (당연히,  처음  적속했다면  1  이다) GET In-­‐Memory  DB  에  현재  접속  정보를  관리하고,  서버  할당시  확인한다. 속도  때문에  redis  를  사용했지,  꼭  이것만  할  수  있는건  아니다. REDIS  에  서버  접속  정보가  있는지  확인한다.
 KEY값이  kimeve  인  데이터가  REDIS  에  있는지  확인한다. 1 2 3
  • 30.
    Session  Server Channel  Server A .   .   .   .   zookeeper Channel  Server  B Channel  Server  C Channel  Server  D Channel  Server  E Channel  Server  F Channel  Server  G Channel  Server  H .   .   .   .   watching create  Node 123.45.67.01:9001 123.45.67.01:9002 123.45.67.02:9001 123.45.67.02:9002 123.45.67.03:9001 123.45.67.03:9002 123.45.67.04:9001 123.45.67.04:9002 REDIS hDps://session-­‐server/node/americatv/kimeve REDIS  에서  조회한  Channel  Server  C  정보를  반환한다. HSET socket  (TCP) kimeve    :    C    :    2 접속한  정보는  실시간으로  REDIS  에서  관리한다. KEY 서버이름 현재  접속자  수
 현재  접속자  수는  Channel  Server  에서  구해서
 REDIS  의  값을  갱신한다.
 (이제  2명이  되었다!) GET In-­‐Memory  DB  에  현재  접속  정보를  관리하고,  서버  할당시  확인한다. 이미  접속한  Client REDIS  에  서버  접속  정보가  있는지  확인한다.  있다!!!
 KEY값이  kimeve  인  데이터가  REDIS  에  있는지  확인한다. 1 2 3 새로  접속하는  2번째  client #  STEP  2.  Using  allocaRon  data  table
  • 31.
    Session  Server Channel  Server A zookeeper Channel  Server  B Channel  Server  C Channel  Server  D Channel  Server  E Channel  Server  F Channel  Server  G Channel  Server  H .   .   .   .   watching create  Node 123.45.67.01:9001 123.45.67.01:9002 123.45.67.02:9001 123.45.67.02:9002 123.45.67.03:9001 123.45.67.03:9002 123.45.67.04:9001 123.45.67.04:9002 REDIS HSET kimeve    :    C    :    2 GET Channel  Server  I 신규  추가된  Channel  서버 123.45.67.05:9001 server  /  A^123.45.67.01:9001                              B^123.45.67.01:9002                              C^123.45.67.02:9001                              D^123.45.67.02:9002                              E^123.45.67.03:9001                              F^123.45.67.03:9002                              G^123.45.67.04:9001                              H^123.45.67.04:9002                                I  ^123.45.67.05:9002Zookeeper  에  Node  생성 Consistent  Hashing  갱신  !!! kimeve  채팅방은 Consistent  Hashing  결과  값은  C  였지만, Channel  Server  I  가  추가된  후 Consistent  Hashing  결과  값이  H  가  되었다. 하지만, REDIS  에는  C  이므로, kimeve  채팅방에  C  를  할당할  수  있다. 만약,  kimeve  채팅방이  다시  만들어  진다면, 그때는  H를  할당  한다. #  STEP  2.  Using  allocaRon  data  table