기본 콘텐츠로 건너뛰기

감정인식 AI서비스 SES업무(100만엔 짜리 안건).. 1일차.




제가 하는 일을 좀더 구체적으로 적어볼까 해서 시작해 봅니다. 

지난 번에 월 100만엔 짜리 안건 소개 했잖아요?
그걸 하기로 해서 도대체 100만엔 짜리 안건은 뭘하는건지 구체적으로 보여드릴까 해서 시작해 봅니다. 

우선 고객이 현재 상태를 제공해 줬습니다. 
인도 개발팀에서 개발을 하고 있구요, 고객은 일본의 CAC라는 업체 입니다. 

간단한 서비스 개념을 설명드리자면, 
콜센터 같은데에서 고객들과 상담을 하는 상담사의 목소리, 떨림, 톤 등을 기반으로 감정의 움직임을 PBX에서부터 리얼타임으로 캐치를 합니다. 

그리고 캐치하여 분석한 데이터를 기반으로 상담사의 심리적 압박을 수치로 나타내고, 
그 수치가 일정 이상 벗어나면 긴급 대응반이 통화를 가로채서 압박을 하고 있는 고객을 상대하고 상담사의 정신케어를 해줄 수 있도록 도와주는 서비스 입니다. 

일본에선 이미 6000개 이상 기업이 채용해서 쓰고 있는데, 
이유는 한국에서도 비슷할 것 같지만 일본에선 상담사는 모두 계약직 또는 파견 업체에서 온 파견직입니다. 때문에 애사심 같은것은 있을 수 없기 때문에 상담사가 지쳐서 관둬 버리면 그만큼 원청사도 손해지만, 파견회사도 이 현장에 넣어봤자 사람들이 망가져서 안되겠다 하고 파견회사에서도 점점 사람을 넣지 않지요. 

때문에 너무 높지 않은 가격에 좋은 인재를 파견업체에 요청하기 위해서는 파견된 사람의 케어할 준비가 얼마나 잘 되어있는지를 보여주어야 합니다. 
그래서 이러한 비즈니스도 일본에선 잘 될 수 밖에 없지요. 

여기서 제가 할 일은 개발자들에게 어떠한 구성으로 가는 것이 좋은지 정리를 해주고 개발자들과 협업을 해서 가장 적합한 구조로 대규모 처리가 가능한 구성을 만들 수 있도록 도와주는 것 입니다. 

그런데 미션은 150세션까지 커버 가능한 시스템... 이라서 굳이 제가 할 규모는 아니긴 했지만, 일단 도와주기로 한 이상 최대한 정보를 정리해서 주기로 했습니다. 

이 시스템의 개발사에서 받은 구성도를 잠깐 보겠습니다. 


왼쪽이 큐 베이스 서비스 라고 해서 어딘가에 보존된 음성 데이터를 서버가 직접 가져가는 방식이라고 합니다. PBX는 리얼타임 스트리밍이기 때문에 이건 녹음된 파일을 특정 위치에 업로드하면 가져가서 분석하는 용도 같네요. 

가운데가 고객 시스템이 콜 해서 처리하는 web api방식이구요, 

오른쪽이 PBX에서 스트리밍 되는 데이터를 받아서 리얼타임으로 처리하는 web socket방식이라고 합니다. 

현재 문제는 맨 오른쪽의 web socket방식이구요, 자기네들이 확장을 생각해서 구성한 것을 보여주겠다고 합니다. 


구조를 파악하는데 한참을 보고서 알게 되었는데요.. 

왼쪽이 현재 한 대의 서버에서 돌아가는 프로세스를 설명한 것이고, 

오른쪽의 두 가지 방법으로 쓰레드를 분리해서 리얼타임 분석과 풀 타임 분석을 나누거나, 
프로세스를 분리해서 리얼타임 분석과 풀 타임 분석을 나누는 방법을 취하고 싶다고 합니다.

그 이유는 테스트로 50세션을 돌려봤는데, 
리얼타임은 문제가 없었는데, 
풀타임 분석이 30개가 넘으면서 실패를 해서 열 몇개는 결과가 나오지 않았기 때문에 풀타임 분석을 분리하는게 맞다고 생각해서라고 합니다. 

여기서 간과한 것이 무엇일까요?

1세션당 트래픽 정보가 없습니다. 
일단 풀데이터의 분석에 CPU가 100%를 찍으면서 실패가 뜬다는 이야기를 들었는데, 
쓰레드를 나누어 봤자 하나의 인스턴스에서 CPU를 사용하기 때문에 분산이 안되겠죠. 

그럼 다른 인스턴스에서 데이터를 끌어서 풀 분석을 하게 되는데, 
이는 처음 받아주는 VM에서 데이터를 모아 저장한 뒤에 다시 새로운 인스턴스에서 끌고 가기 때문에 모인 파일을 한 번에 가져가는 순간 엄청난 트래픽을 요구합니다. 
트래픽 지연등의 문제가 발생할 소지가 있겠지요.. 
특히나 통화가 끝난 타이밍에 일제히 끌고갈텐데, 
입력이 한 곳이라면 통화가 끝나고 다음 통화가 들어오는데 갑자기 대량의 트래픽으로 끌고가게 되므로 한계가 금방 나오지 않을까 싶습니다. 

때문에 세션당 전송 데이터를 알고 싶어서 dfd를 달라 했더니, 
데이터양은 적지 않고 dfd를 그려주네요.. 

일단 들은 내용을 가지고 정리를 해보려 합니다. 
트래픽 정보를 안가지고 있어서 제가 검색해 보았는데요.. 
우선 IP PBX에서 사용되는 음성 데이터는 큰게 64Kbps 정도 되는군요.. 


그럼 64kbps로 100세션을 받으면 6.4Mbps가 됩니다. 
입력은 충분히 문제가 없을 것 같네요. 

그런데 받은 데이터가 만약 평균 10MB정도에 내부의 다른 인스턴스로 던지게 되면 네트워크 부하가 10Mbps정도가 추가되겠죠. 그 이상도 나올 수 있지만 shared cloud network의 QoS상 이 이상은 안나올 것 같습니다. 그 얘기는 10초에 파일 하나씩은 전송 되지 않을까.. 
하지만 그 10초간은 다른 트래픽에 장애가 오지 않을까.. 

게다가 물어보니 한 서버에서 모든 고객의 세션을 받고자 한다고 합니다. 
그럼 한 고객이 100세션씩 계약하고, 그 고객이 1000개가 된다면, 
64Kbps x 100000 = 6.4Gbps 가 되겠죠?

인스턴스당 100Mbps정도로 QoS가 잡혀 있다면 
100세션에서 풀 데이터를 가져오는 타이밍 마다 딜레이가 발생할 것 같습니다. 
그리고 앞부분에 받는 서버 역시 지금 한대로 다 하고 백그라운드 인스턴스를 늘리는 식이 될 거 같은데 그렇게 하면 아마 700Session에서 터지지 않을까요?
분석용 서버들이 세션을 물고 끌고 가는 것도 있고, 원래 OS별로 다르긴 하지만, 
웹소켓은 일반적인 HTTP통신과는 달라서 하나의 인스턴스당 1000정도를 잡거든요.. 
OS마다 최대 65535개까지 쓰는 법도 있긴 하지만 보통은 1000을 넘기면 OS에서 관장하는 내부 소켓의 port가 빈 곳이 없어서 time_wait이 끊기는 것을 대기 하게 되는데 
그러면 유저의 소켓 데이터를 받지 못하고 튕겨질게 뻔합니다. 

대부분의 개발자들이 대규모 게임 같은 것을 처음 만들 때 제일 먼저 직면하는 부분입니다.

입구를 고객 베이스로 늘릴거냐, 
아니면 전체 고객용으로 프론트를 대거 늘리고 백그라운드를 spot형태로 늘리느냐를 구성해서 보여주면 될 것 같네요. 

고객이 azure에서 vm안에 nginx환경을 쓰고 있으므로 앞단에서 분산 방식은 

application gateway
VMSS
Nginx Load balancing
DNS Round robin

의 방법중 하나 또는 두 가지를 적절히 섞어서 쓰면 좋을 것 같습니다. 
각 방법마다 가격적 메리트 또는 죽은 인스턴스에 대한 체크 등등의 장단점이 있습니다. 
참고로 Azure의 로드밸런싱을 찾아보시면 아래 네 가지가 있습니다. 

이 중에서 CDN이나 Load Balancer, Traffic Manager를 쓰지 않은 이유는 
이 CDN은 서버 쪽에서 유저가 많이 몰려서 다운로드 하는 서비스에 특화된 분산 기술이고, Load Balancer는 L4계열의 처리라서 단순 컨트롤이라 처음 진입은 쉬우나 세세한 분류가 귀찮고 현재 HTTPS통신을 할 때 SSL을 관리하지 못합니다. Application Gateway는 서버가 유저의 입력을 보고 분산 방식을 정하는 것이라고 보시면 됩니다. 게다가 L4계열이냐 L7계열이냐, Traffic manager같은 DNS방식 차이도 있으나, 이번에는 일단 application gateway쪽으로 그려볼까 합니다. 

application gateway는 유저의 세션 성격을 보고 서버를 타게팅 가능하고, sticky처럼 연결도 해줄 수 있으며 DDoS 의 방어도 해줍니다. 물론 DDoS 체크를 하는 순간 3만엔짜리가 갑자기 가격이 50만엔까지 올라가죠. 

IP PBX와의 연결만이기 때문에 이런거 필요없다는 경우는 
VMSS만으로 스케일링을 하고 DNS에 붙이는 방법도 가능합니다. 

Nginx의 load balancing 기능이 있어서 Nginx의 설정만으로도 충분히 부하분산이 가능하지요. 이렇게 설정하겠다면 VMSS로 새로운 인스턴스가 생겼을 때 바뀐 IP를 기존 VM에 추가하는 스크립팅이 굉장히 중요해지는데, 아마 그걸 커버할 정도의 실력을 가지진 않았으리라 봅니다.

아니면 단순히 VM을 늘린 후 DNS에 각 VM의 IP를 입력하는 것 만으로도 유저 세션이 돌아가면서 VM에 붙는 방법도 가능합니다. 
단지 이 경우는 VM이 죽어도 무시하고 붙으려 하기 때문에 손실이 나서 서비스에선 이 하나만 사용하지 않긴 합니다. 

Traffic Manager가 바로 이 DNS에서 VM이 죽었는지 체크를 해주기 때문에 DNS를 사용할 경우 Traffic Manager를 사용하면 됩니다. 이는 AWS의 Route53과 같은 기능을 가지고 있습니다. 그래도 기왕 부른거 자동으로 인스턴스가 확장되는 구조를 가져가고 싶긴 할테죠?

개발과의 연계도 중요하기 때문에 좀더 논의는 필요한 내용입니다.

참고로, Route53이나 Traffic Manager는 다른 LB와는 달리 트래픽을 자신이 받지 않기 때문에 비용이 저렴하며 대규모 트래픽 또는 글로벌 리전을 가지고 부하분산을 하고 싶은 경우에도 충분히 커버가 가능하므로 잘 참고하시면 좋을 것 같습니다. 

이렇게 정리를 했으니 제안을 준비해야겠지요.. 

제안 내용 정리 및 고객의 반응은 다음 편에 다시 정리해 드리겠습니다. 

보시고 어떠신가요? 
여러분도 100만엔 짜리 안건은 여유로 받으실 수 있으신가요? 

이번 안건에 필요한 지식은, 

Application gateway와 Traffic manager, Front Door(CDN), Load balancer의 각 특징과 IP BPX의 원리 및 websocket에서 어떻게 처리되는지, 그리고 Nginx의 구조와 SSL을 어떻게 붙이는게 효율적인지, OS의 Session 과 connection 관리 사양 및 병목의 체크 방법과 그에 대한 분산 구조의 재설계 능력, 그리고 그 재설계에서 개발팀들의 역량에 맞는 최적의 설계안을 몇 개 만들 수 있으면 됩니다. 

생각보다 어렵지 않지요? 

개발자였던 사람이 IT컨설턴트가 되면 장점은, 
현재 구조의 코드를 대충 머릿속에 그릴 수 있고, 그에 따른 예상 병목을 알 수 있게 됩니다. 
거기에 하드웨어와 OS의 특징을 알면 병목을 유발시키는 하드웨어를 특정할 수 있고, 그에 따른 분산방법을 쉽게 찾을 수 있지요. 

IT컨설팅을 하고자 하시는 분들께 도움이 되는 내용이면 좋겠습니다.



giip :: Control all Robots and Devices! Free inter-RPA orchestration tool! https://giipasp.azurewebsites.net/

댓글

이 블로그의 인기 게시물

Alter table 에서 modify 와 change 의 차이 :: SQL Server

두 개의 차이를 모르는 경우가 많아서 정리합니다.  modify는 필드의 속성값을 바꿀때 사용하구요.. change는 필드명을 바꿀떄 사용합니다.  alter table tbbs modify bNote varchar(2000) NULL; alter table tbbs change bNoteOrg bNoteNew varchar(2000) NULL; change에는 원래 필드와 바꾸고 싶은 필드명을 넣어서 필드명을 바꾸는 것이죠~ 더 많은 SQL Server 팁을 보려면  https://github.com/LowyShin/KnowledgeBase/tree/master/wiki/SQL-Server giip :: Control all Robots and Devices! Free inter-RPA orchestration tool! https://giipasp.azurewebsites.net/

책에서는 안 알려주는 대규모 트래픽을 위한 설계

음성 버전 :  https://www.youtube.com/watch?v=ZZlW6diG_XM 대규모 트래픽을 커버하는 첫 페이지 만드는 법..  보통 DB를 연결할 때 대규모 설계는 어떻게 하시나요?  잘 만들었다는 전제 하에 동접 3000명 이하는  어떤 DBMS를 사용해도 문제 없이 돌아갑니다.  여기서 이미 터졌다면 이 콘텐츠를 보기 전에 DB의 기초부터 보셔야 합니다.  아.. 개발 코드가 터졌다구요? 그럼 개발자를 때리셔야지요..  만약 3000명을 넘겼다면? 이제 Write/Read를 분리해서  1 CRUD + n개의 READ Replica를 만들겠죠?  보통 Read Replica는 5개가 최대라고 보시면 됩니다.  누가 연구한 자료가 있었는데...  6번째 레플리카를 만든느 순간 마스터가 되는 서버의 효율 저하 때문에  5번째에서 6번쨰로 올릴때의 성능이 급격히 줄어든다는 연구 결과가 있습니다.  때문에 Azure에서도 replica설정할 때 5대까지 밖에 설정 못하게 되어 있지요.  유저의 행동 패턴에 따라 다르긴 하지만,  1 CRUD + 5 Read Replica의 경우 동접 15000명 정도는 커버 합니다.  즉, 동접 15000명 에서 다시 터져서 저를 부르는 경우가 많지요..  이 때부터는  회원 DB, 게시판DB, 서비스DB, 과금 DB 등등 으로 성격, 서로의 연관도에 따라 나누기 시작합니다.  물리적으로 DB가 나눠지면 Join을 못하거나 Linked Table또는 LinkDB등의 연결자를 이용해서 JOIN이 되기도 합니다.  그에 따라 성능 차이가 생기지만 가장 중요한 포인트는  서로 다른 물리적 테이블의 JOIN은 인덱스를 타지 않는다!  라는 것입니다. 즉, JOIN할 테이블들을 최소한으로 만든 뒤에 JOIN을 걸지 않으면 NoSQ...

BI의 궁극판! Apache Drill을 써보자!

사실 Apache Drill 은 BI(Business Intelligence)라고 부르는 것 보다는 단순 데이터 연결 엔진이다. https://drill.apache.org/ 하지만 내가 왜 극찬을 하느냐면.. DBA로서 항상 문제가 되어왔던게, 이기종 데이터의 변환이나 처리였다. 포맷을 맞추는데 엄청난 시간이 걸리고, 데이터 임포트 실패가 무수하게 나고.. 한 번 잘못 데이터를 추출하면 다시 조정, 변환, 추출하는데 시간이 많이 걸린다. 그런데! Apache Drill은 그냥 RDB를 CSV랑 연결해서 조인해서 통계를 낼 수 있다. 그것도 표준 SQL을 사용하여! 예를 들어, CSV의 세 번째 컬럼이 price 이고, 물건의 판매이력을 PG사에서 CSV로 출력 받았다. 우리 DB와의 검증을 위해서는 수동으로 Import를 한 뒤에 포맷이 안맞아 잘리는 데이터가 있다면 다시 맞춰주고, 재 임포트를 수십 번, 그리고 나서 겨우 들어간 데이터를 조인하여 빠진 데이터를 분간한다. 숫자가 적다면 개발자가 개발로 처리할 수도 있지만, 건수가 하루에 300만건 짜리라면.. 한 달 온 파일은 9천만 건이다. 프로그램으로 고작 처리하는 것이 초당 500건. 거의 20만초, 에러 없이 약 56시간.. 에러가 생기면 다시 56시간.. ㅠㅡㅠ 이런게 현실이기 때문에 쿼리 말고는 방법이 없다. apache drill 의 진면목을 보자! 이번에는 좀 범용 적인 MySQL DB와 붙여 보자. . 난 이번에는 Mac에서 작업을 했기 때문에 그냥 다운 받아서 풀었음.. https://drill.apache.org/download/ 여기서 자기 OS에 맞는 버전을 받아서 설치하시길.. 압축을 풀고 나면 MySQL 커넥터를 붙여야 한다. https://dev.mysql.com/downloads/connector/j/5.1.html 여기서 다운로드 이런 커넥터 들을 붙일 때마다 콘피그를 수정해 줘야 하지만, 몇 번만...