Upload
john-kim
View
2.239
Download
1
Embed Size (px)
Citation preview
# 수십만명이 동시에 접속하는 온라인 인터넷 방송 ‘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 통신하게 하자 !! ( 네트워크 비용이나, 성능 향상 )
# 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 서버의 설정값이 모두 일괄 변경된다.
# github.com/xpush/node-‐xpush 에서 구현하고 있는데... 정리가 다 되려면, 추석은 지나야 될 듯. 명절에는 고향에서 코딩이죠!!
[email protected] 2015.08
프로젝트 관련 문의는 [email protected] 로 주세요.