31
SCALABILITY DISTRIBUTED 채팅 서버 적용사례를 통한 분산서버 관리 방법 알아보기 github.com/xpush/nodexpush

채팅서버의 부하 분산 사례

Embed Size (px)

Citation preview

SCALABILITYDISTRIBUTED

채팅  서버  적용사례를  통한  분산서버  관리  방법  알아보기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://s

ession-­‐s

erver/no

de/amer

icatv/yum

daeng

!!!!!!"""

!!!!"""

채팅방  -­‐  kimeve

채팅방  -­‐  yumdaeng

server  :  C,  url  :  123.45.67.02:9001

server  :  

F,  url  :  1

23.45.67

.03:900

2

-­‐ 실제로,  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  :  Curl  :  123.45.67.02:9001

channel  :  yumdaeng  server  :  Furl  :  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 CD

ABCD

D

ABCD

ABCABC

DA

BCA

ABCD A

B C D

value����������� ������������������  =����������� ������������������  HASH(key2)

#  STEP  1.  Consistent  Hashing  -­‐  replica  !!

A

B

C

D

B CD

ABCD

D

ABCD

ABCABC

DA

BCA

ABCD 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-­‐ser

ver/node/americatv/k

imeve

REDIS  에서  조회한  Channel  Server  C  정보를  반환한다.

"

HSET

socket  (TCP)

kimeve    :    C    :    2

접속한  정보는  실시간으로  REDIS  에서  관리한다.

KEY 서버이름

현재  접속자  수현재  접속자  수는  Channel  Server  에서  구해서REDIS  의  값을  갱신한다.(이제  2명이  되었다!)

GET

In-­‐Memory  DB  에  현재  접속  정보를  관리하고,  서버  할당시  확인한다.

이미  접속한  C

lient

REDIS  에  서버  접속  정보가  있는지  확인한다.  있다!!!KEY값이  kimeve  인  데이터가  REDIS  에  있는지  확인한다.

1

2

3

"새로

 접속하는

 2번째  clie

nt

#  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

신규  추가된  C

hannel  서버

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:9002Zoo

keeper  에

 Node  생성

Consiste

nt  Hashi

ng  갱신  !!!

kimeve  채팅방은

Consistent  Hashing  결과  값은  C  였지만,

Channel  Server  I  가  추가된  후

Consistent  Hashing  결과  값이  H  가  되었다.

하지만,

REDIS  에는  C  이므로,

kimeve  채팅방에  C  를  할당할  수  있다.

만약,  kimeve  채팅방이  다시  만들어  진다면,

그때는  H를  할당  한다.

#  STEP  2.  Using  allocaRon  data  table

#  Channel  서버의  접속량에  따라  가중치를  부여해보자.Session  서버는,  더  많이  처리할  수  있는  스펙  좋은  Channel  서버나  접속량이  적어  놀고  있는  Channel  서버가  더  많이  할당  되도록  해야  할  것이다.

server  /  A^123.45.67.01:9001  (160)                              B^123.45.67.01:9002  (160)                              C^123.45.67.01:9001  (160)                              D^123.45.67.01:9002  (160)                              E^123.45.67.01:9001    (320)                              F^123.45.67.01:9002    (320)                              G^123.45.67.01:9001  (160)                              H^123.45.67.01:9002  (160)

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

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

#  STEP  3.  Weighted  Consistent  HashingConsistent  Hashing  Ring  에  replica  수가  가중치가  된다.

Default  는    160  개의  relica  가  생성되며,스펙  좋은  서버는  relica  수를  더  많이  한다.

다른  서버에  비해  CPU  나  메모리  상황이  좋은  서버들  (E,  F)

Create  Node  with  Datazookeeper  node  생성시  replica  수를  함께  저장한다.

server  /  A^123.45.67.01:9001  (1)                              B^123.45.67.01:9002  (1)                              C^123.45.67.01:9001  (160)                              D^123.45.67.01:9002  (1)                                E^123.45.67.01:9001    (1)                              F^123.45.67.01:9002    (320)                              G^123.45.67.01:9001  (1)                              H^123.45.67.01:9002  (160)

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

Update  Node  Data

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

#  STEP  3.  Weighted  Consistent  Hashingrelica  수를  1로  설정하여  Consistent  Hashing  을  다시  생성하면,  서버  할당  대상이  되기  희박하다.  (하지만,  같은  채팅방에  Client  접속이  늘어난다면,  계속  할당해주기는  할  것이다.)

Client  의  ConnecXon  이  적은  서버들  (C,  F,  H)

2500

15

2610

1890

3150

1979

24

32

Client  의  ConnecXon  이   많이  연결된  서버들  (A,B,D,E,G)

channel  서버의  현재  연결된  Client  수가  초기  설정한  임계치를  초과  하면,zookeeper  node  의  데이터(replica  수)를  1  로  수정한다.

현재  Co

nnecOo

n  수  (예

)

#  만약  엄청  유명한  BJ  라면,  한대의  채팅  서버가  감당할  수  없다!네트워크  비용을  최소화  하기  위해  같은  채팅방의  Client  가  하나의  Channel  서버와  연결한다는  것은.....  사실은  현실적이지  못했다.  ‘마리텔’  을  생각해보자.  박종원  쉐프  방송에  수천명이  접속해  대화  할  것이  아닌가?  이걸  단일  서버에서  처리한다는건  말도  안된다.    (솔직히...  수천명의  대화  내용을  읽는  것도  이해  할  수  없다.)

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

REDISPUB

SUB  ‘G’

123.45.67.05:9001

!!!!!!!!!!!!!!!!!!

!!!!!!!!!!!!!!!!!!

""""""""

""""""""

kimeve    채팅방  접속  Clients

PUB

SUB  ‘C’

PUB

#  STEP  4.  Sharing  messages  between  distributed  servers  채팅방당  최대  연결  가능  수를  임계치로  설정하고,  초과  하면  다른  Channel  서버에  접속하도록  한다.  어쩔  수  없다  ㅠ,.ㅠChannel  서버간  통신은  Redis  의  Pub/Sub  을  사용한다.

채팅방  당  최대  400  까지

Channel  서버가  Startup  될  때  Redis  에  서버ID  를  키로하여    Subscribe  한다.

Channel  서버  C  는

 총  ConnecOon  1

,300  중  

kimeve  채팅방이  Con

necOon  400  으로

 임계치를  초과  했다

!    

그러므로,  Session

 서버는  다른  새로운

 Channel  서버를  할

당해  준다.

#  드디어,  정말  부하  분산이  잘될  것이다!표준편차도  계산해본  Consistent  Hashing  을  적용했을  뿐더러,  서버  부하  상황에  따라  가중치도  자동  조절  되도록  했다!  최대한  네트워크  비용을  줄였다!  같은  채팅방에  접속한  Client들은  모두  같은  서버에  접속하기  때문에,  하지만  Client  가  너무  많으면  어쩔  수  없이  나누긴  했지만  말이다.  

#  그런데.  이상하다!        여전히  하나의  서버에  몰릴  때가  있다.

이정도라면,  할만큼  한거  아닌가?  ㅠ  ,.  ㅠ

#  STEP  5.  Changing  replica  quanRty  SOFTLYChannel  서버는  ConnecOon  수에  따라  Session  서버가  분배를  유연하게  할  수  있도록  해야  한다.  그래서,  Channel  서버는  ConnecOon  수에  따라  Replica  수를  결정하여  Consistent  Hashing  을  상황에  따라  수시로  최적화  해야  한다.

server  /  A^123.45.67.01:9001  (1)                              B^123.45.67.01:9002  (1)                              C^123.45.67.01:9001  (160)                              D^123.45.67.01:9002  (1)                                E^123.45.67.01:9001    (1)                              F^123.45.67.01:9002    (320)                              G^123.45.67.01:9001  (1)                              H^123.45.67.01:9002  (160)

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

Update  Node  Data

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

Client  의  ConnecXon  이  적은  서버들  (C,  F,  H)

2500

15

2610

1890

3150

1979

24

32

Client  의  ConnecXon  이   많이  연결된  서버들  (A,B,D,E,G)

channel  서버의  현재  연결된  Client  수가  초기  설정한  임계치를  초과  하면,zookeeper  node  의  데이터(replica  수)를  1  로  수정한다.

#  STEP  3.  Weighted  Consistent  Hashing  ?  이제는..  160  에서  바로  1  로  줄어드는것이  문제다!  

SCALE 60

BUFFER 10

MAX_LEVEL 4

REPLICA_BASE_NUM 4

Channel  서버의  ConnecOon  수에  따라  Replica  수를  결정하는  변수를  정하자!

ConnecOon  수  증가

SCALE  :  60

600 120 180 240

Replica  수  변화의  단계

50 70 110 130 230 250170 190

BUFFER  :  10

Replica  수를  결정하는  모수

Channel  서버의  ConnecOon  수  임계치  결정  모수

Channel  서버의  ConnecOon  수  임계치  변경  버퍼

ConnecOon  수  :  1  ~  70

Replica 수 는 = REPLICA_BASE_NUM ^ LEVEL

Replica = 4^4 = 256

ConnecOon  수  :  70  ~  130

Replica = 4^3 = 64

ConnecOon  수  :  130  ~  190

Replica = 4^2 = 16

ConnecOon  수  :  190  ~  250

Replica = 4^1 = 4

ConnecOon  수  :  250  ~

Replica = 4^0 = 1

ConnecOon  수  :  50  ~  0

Replica = 4^4 = 256

ConnecOon  수  :  110  ~  50

Replica = 4^3 = 64

ConnecOon  수  :  170  ~  110

Replica = 4^2 = 16

ConnecOon  수  :  230  ~  170

Replica = 4^1 = 4

ConnecOon  수  :    ~  230

Replica = 4^0 = 1

#  STEP  5.  Changing  replica  quanRty  SOFTLY

<  예시  >

SCALE 60

BUFFER 10

MAX_LEVEL 4

REPLICA_BASE_NUM 4

Channel  서버의  ConnecOon  수에  따라  Replica  수를  결정하는  변수를  정하자!

Replica  수  변화의  단계

Replica  수를  결정하는  모수

Channel  서버의  ConnecOon  수  임계치  결정  모수

Channel  서버의  ConnecOon  수  임계치  변경  버퍼

#  STEP  5.  Changing  replica  quanRty  SOFTLY

server  /  A^123.45.67.01:9001  (4)                              B^123.45.67.01:9002  (256)                              C^123.45.67.01:9001  (64)                              D^123.45.67.01:9002  (256)                              E^123.45.67.01:9001  (64)                              F^123.45.67.01:9002  (256)                              G^123.45.67.01:9001  (256)                              H^123.45.67.01:9002  (1)  config  /  SCALE  (60)                              BUFFER  (10)                              MAX_LEVEL  (4)                              REPLICA_BASE_NUM  (4)

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

watching    update  Node  Data

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

Channel  서버는  ConnecOon  수와  설정  변수를  바탕으로  replica  수를  변경하여  Zookeeper  데이터를  갱신한다.  그리고,  replica  수가  변경되면  Session  서버가  Consistent  Hashing  을  재구성  한다.

zookeeper  의  데이터를  수정하면,  모든  Channel  서버의  설정값이  모두  일괄  변경된다.

#  이상하게  복잡해  보이지만  .  .  .      그냥,  Replica  수를  천천히  조절하며  Consistant  Hashing  을  최적화  하는  거임.

#  github.com/xpush/node-­‐xpush  에서  구현하고  있는데...        정리가  다  되려면,  추석은  지나야  될  듯.        명절에는  고향에서  코딩이죠!!

[email protected]  2015.08

프로젝트  관련  문의는  [email protected]  로  주세요.