기본 콘텐츠로 건너뛰기

경험자가 이야기 하는 대규모 처리 경험이란?

영상버전 : https://youtu.be/gkMwrSJsUVo



 제가 재섭게 자랑처럼 맨날 이야기 하는내용이 있잖아요?


4000만 DAU

60만 동접

120만 TPMC

300Gbps 트래픽

2억대 펌웨어 다운로드..

1.76PB 머신러닝 팜 설계

DR을 Active화 하여 Geo Balancing구성을 했다거나

소프트뱅크 페퍼 공식 저서 작성

각종 블록체인의 소스코드 분석 및 토큰 에코노미 분석

요즘은 chatgpt프로젝트 세 개나 했구요.. 


혹자는 이렇게 생각하겠죠.. 저거 구라 아냐? 저정도 해본 인간이 왜 찌질하게 몇 명 없는 유튜브나 하고 있어?


라구요.. 

저처럼 지지리도 운도 없고 영어도 못하면 이 정도 실력을 가지고 있어도 이렇게 찌질하게 유튜브나 찍으면서 자기 잘난 맛에 보는 사람 없이 떠들기도 한답니다. 


어디 엄청난 선구안을 가진 사람이 절 안주워갈려나요? 


어디선가 저의 진짜 모습에 투자해주실 분을 기다리면서 홀로 방송 해봅니다. ^^

주변에 엄청난 분이 계시다면 제 영상을 꼭 보여주세요~~


쓸데없는 말은 이정도 하구요.. 


얼마전 대규모 설계 경험자 모집이란 내용에 대한 썰을 푸는 영상을 보았는데요.. 


이런 대규모 설계는 다른 설계와 뭐가 다르길래 대규모 처리 경험자와 비 경험자가 나뉘어지게 되는걸까요?


그 전에 그 대규모 라는 건 어떤 기준일까요?


 제가 생각하는 대규모 라고 접어드는 단계는 


서버 한 두대 정도로 케어할 수 없는 규모의 처리를 이야기 한다고 생각합니다.


 예를 들어서 이런게 있죠.


 하루 4천만 유저가 들어오는 시스템의 가장 중요한 건 무엇일까요?


 제가 강조할 때 4000만DAU를 말하면서

 다른 서비스에서는 동시 60만 클릭을 다시 이야기 합니다.

 그냥 4000만으로 퉁치면 되는 거 아닌가요?



 하루는 1440분 입니다. 1분에 약 3만 명의 사용자, 초당 500명의 사용자라면 순간 동접으로 따지면 그렇게 크지 않아요. 


 즉, 4000만 DAU일때 신경써야 하는 인프라와 60만 동시 리퀘스트에서 신경써야 하는것, 그리고 120만 TPMC에서 체크해야 하는 것이 완전히 다르기 때문에 각각을 따로 이야기 하는 것이지요.


4000만 DAU라는 것은 순간 트래픽보다는 일간 로그가 엄청난 양이 남게 됩니다. 

로그 분석을 RDB로 불가능한 수준이 되기 때문에 예전에는 매일 파일로 남긴 뒤에 BI에서 로드해서 분석을 했지요. 때문에 리얼타임이 불가능 했습니다. 

하지만 요즘은 NoSQL이 있어 리얼타임으로 집계가 됩니다. 


따라서 4000만 DAU커버 라는 말 속에는 그 많은 유저들의 성향 분석이나 로그 분석, 그리고 유저에 대한 CS가 가능한 백그라운드 데이터 처리 구조를 잘 짤 수 있습니다 라는 어필인 것이구요, 이걸 이렇게 해석하지 못한다면 면접관의 스킬 문제가 되는 것이지요. 

데이터 사이즈가 커지게 되면 여러 대의 서버가 각각 데이터를 Async로 가져오게 됩니다. 

때문에 기존 RDBMS시스템처럼 엮어버리게 되면 데이터 불일치가 나오는 타이밍이 생깁니다. 

때문에 어떤 데이터를 어떤 타이밍에 로드해서 어디까지 보였을 때부터 화면에 뿌려줘야 하는지, 데이터 양은 어느 정도 단위로 잘라서 로드해야 하는지 등을 생각하지 않으면 메모리 부족으로 터지게 되는 것이지요. 

또, 데이터 사이즈 문제가 있다보니 IOPS에서 특히 Read에 특화된 Disk IO성능을 이야기 할 수 있어야 합니다. 


그렇다면 동시 60만 리퀘스트는 어떻게 설계해야 할까요? 

동시 60만 리퀘스트는 메이플 스토리 일본 서비스에서 2005년 매 점검이 끝나는 타이밍에 유저들이 연타해서 생기는 트래픽인데요.. 

지난 콘텐츠에서도 언급했지만, 이 정도 되면 웹서버 이전에 그앞의 L4에서 터져 버립니다. 그런곳에서 유식한 척 L7같은 표현을 해버리면 바보가 되는 영역이지요. 

요즘 AWS의 ELB가 L4/L7 제어가 되니가 가장 강력한 듯이 이야기 하는 사람들 많죠? 

바로 이런 사람들이 대규모 처리를 해본 적 없는 사람입니다. 

L4와 L7의 차이도 모르기 때문이지요. 

L4와 L7은 부하분산에 쓰이는 네트워크 레이어를 이야기 합니다. 

네트워크의 7레이어 라고 들어보셨죠? 


거기서 L4는 IP를 관장하고 L7는 어플리케이션을 관장합니다. 

L4의 데이터를 보려면 Decapsulation을 3번만 열면 보입니다. 

하지만 L7은 6번 Decapsulation을 거쳐서 데이터 영역을 열어보아야 어떤 어플리케이션을 사용하는 패킷인지 알 수 있기 때문에 그만큼 더 많은 네트워크 장치에 부하를 주게 됩니다. 

즉, 같은 쓰루풋이라면 L7은 약 2배 더 느리게 되는 것이지요. 

1초에 60만 리퀘스트가 오는데 0.1초만 딜레이되어도 스택에는 6만 스택이 쌓여 버립니다. 

그게 10초가 지난 다음에는 120만 리퀘스트가 쌓이게 되는 것이지요. 

이런 초대량 동시 리퀘스트는 네트워크 단계에서 어떻게 설계하여 분산을 시키는지가 중요하고 그걸 할 줄 안다는 이야기 입니다. 그렇기 때문에 저는 굳이 이걸 나누어 강조를 하고 있지요. 


그리고 60만 리퀘스트가 서버에 들어왔을 때 서버는 최소 부하시 최대 10만 리퀘스트를 받지만, 보통 DB연동등의 설계를 했기 때문에 2만 리퀘스트에서 서버를 늘리는게 보통입니다. 그리고 그 앞에 부하분산 장치를 두지요. 요즘은 L4/L7이 아닌 GLB를 사용합니다. 한국사람들은 제가 아무리 쓰라해도 뭔 똥고집으로 안쓰는 Route53을 사용해야만 하지요. 그리고 서버당 리퀘스트를 줄이기 위해서 site캐싱도 하지만 HTML화를 시켜서 물리적으로 서버 파싱을 줄이는 방법도 있습니다. 

이런 종합적인 부하분산을 위한 처리 경험이 중요한 것이지요. 


그럼 그 외에 120만 TPMC를 처리한다는 얘기는 뭘까요?

초당 데이터베이스 트랜잭션을 120만번을 처리한다는 이야기 입니다. 

이것도 대규모 처리를 못해보신 분들은 감이 안오실텐데요.. 

MySQL은 4000TPS, SQl Server는 6~8000 TPS, ORACLE은 12000 TPS를 기준으로 잡습니다. 

물론 이 이상 넘어간다고 터지는 것이 아니고 이보다 큰 동시 요청이 오면 성능 저하가 급격하게 된다는 이야기 입니다. TPMC는 1분당 처리 트랜잭션이기 때문에 120만이라는 것은 2만 TPS와 같지만 DBMS의 처리는 시작부터 끝까지의 시간이 쿼리마다 천차 만별이기 때문에 평균치를 잡기 위해 분당 트랜잭션 처리량으로 계산하는 경우가 많습니다. 그게 TPMC이지요. 

이건 DBMS의 성능의 최적화를 위해 복잡한 구성을 하기 때문에 그 구성에 던졌을 때의 처리를 이야기 하기 때문에 이렇게 계산을 합니다. 

아까 이야기한 ORACLE에서조차 2만 TPS가 나오지 않잖아요?

하지만 Exa data급이라던가 Mainframe에 HP-UX등의 OS를 설치하여 PPAR로 구성하고 ORACLE만 탑재 하는 경우 120TPMC는 쉽게 나옵니다. 

그 밖에 내부적으로 레플리카의 개수, 복구 플랜 최적화에 따른 부하 경감 정도, 그리고 DISK IO최적화를 위한 어레이 또는 RAID구성, OS의 세세한 파라미터 조정능력 등이 바로 저 숫자를 가능하게 하는 것이지요. 


300Gbps 트래픽이란 것은 또 뭘까요? 


아무리 대량으로 웹호출이 와도 300Gbps는 쉽사리 나오는 숫자가 아닙니다. 

보통 웹페이지 로드할 때 평균 7초에 50KB 정도를 많이 생각합니다. 

이게 100만명 온다해도 50GB에서 멈추죠.. 

100만명이 동시 접속하는 서비스는 전 세계 몇 개나 있을까요? 

그렇다면 300Gbps는 어떻게 나올 수 있죠? 

여러분이 좋아하는 LOL의 한국 네트워크에서 패치 다운로드의 순간 요청 트래픽이 300Gbps가 됩니다. 

이걸 어떻게 유저에게 불편하지 않게 분산시켜 가장 가까운 노드에서 다운로드 할 수 있게 하느냐가 바로 이 경험이 되는 것이지요. 요즘은 Cloud Front에 설정만 하면 되긴 하지만 예전에는 여러 CDN업체와 계약하고 Pre load를 걸어서 미리미리 준비해 놓지 않으면 저 동시 요청을 처리할 수가 없었답니다. 

물론 지금도 Cloud Front에 300Gbps를 흘리면 아마 뻗거나 강제 QoS로 유저가 답답함을 느낄걸요.. 

이러한 분산 네트워크 처리 경험을 이야기 할 때 사용합니다. 


그럼 2억대 펌웨어 다운로드 구성 역시 분산 네트워크 처리 아닌가요? 

이건 저 집중형과는 또 다른 이야기 입니다. 2억대의 동일 디바이스가 한국에만 있을 방법이 있나요? 

즉, 이건 L모사의 핸드폰이 전세계 2억대 팔렸을 때 주기적인 펌웨어를 개발사에서 한 군데에만 올리면 신속하게 전세계 엣지에 뿌려서 사람들이 쉽게 받을 수 있는 프리로딩을 위한 네트워크 확보 경험과 그에 대한 엣지 버전 관리 경험을 어필할 때 사용하는 것이랍니다. 


그리고 1.76PB 머신러닝 팜 설계가 있죠. 

제가 S모 생명에서 32TB데이터를 머신러닝 하기 위해서 로딩했을 때 경험 부족으로 크게 혼났던 적이 있습니다. 

32TB를 그냥 로딩하면 되는거 아냐? 라고 생각하셨겠죠? 

그 때는 Couchbase라는 NoSQL을 썼는데, Couchbase의 특징은 쿼리서비스노드가 무한히 확장되서 헤더에 대한 병목이 없다는 장점에 도입을 했는데, 이놈의 가장큰 문제가 데이터를 인서트 할 때마다 인덱스 관리를 메모리에서 한 뒤에 디스크에 저장하는 방식으로 메모리 이상의 데이터를 집어 넣는 경우 급격히 속도가 떨어지는 문제를 가지고 있다는 점입니다. 

아마 대부분의 NoSQL이 가지고 있는 고질적인 문제인 메모리 요구량 때문인데요, 

이런 NoSQL의 한계등을 경험하여 로드할 때 자르는 최적화나 전처리를 얼마나 끊어서 하느냐, 

ML처리를 전체를 못하는 경우 이미 처리된 h5파일 위에 추가 러닝하는 방법이나 그 한계를 경험하고 확장을 어떻게 할 것이냐 라는 노우하우가 있어 1.76PB까지 경험해봤다는 것을 이야기 하는 것입니다. 


이것 뿐만 아니라, 

대규모 데이터 처리가 되면 기존에 책이나 동영상 등에서 배우셨던 방법은 아무 쓸모가 없다는 것도 아셔야 하는데요.. 많은 높으신 분들이 제가 설계하면 비웃다가 당해보고나야 저를 평가하는 부분이 바로 여기 있습니다. 지금까지 내용으로도 충분했다구요? 

아닙니다. 


이제부터가 대규모 데이터 처리경험의 진수입니다. 


테이블에서 쿼리를 돌리는데 5개의 게임에서 콜라보 이벤트를 합니다. 각각 이벤트에 따라서 서로 다른 게임 디비에 데이터를 넣기 때문에 이기종 게임들의 데이터를 보려면 다음날 배치로 한 군데로 몰아서 게산후에 봐야 합니다. 


이걸 가능하게 했던게 64대 이기종 DB서버를 엮어서 M-OLAP과 R-OLAP으로 연결후 이벤트 결과만 R-OLAP으로 리얼타임으로 끌고와서 통계를 볼 수 있게 한다거나, 


하나의 서비스내에서도 유저들의 이벤트 통계를 유저들에게 리얼타임으로 보여주어 경쟁심을 유발시키려고 할 때 게속 수억 로우를 group by 를 써야 하는 경우 RDBMS에서 제공하는 캐시 테이블은 휘발성이기 때문에 캐시테이블용 테이블을 만들어 캐시처럼 사용하는 기법이라던가, 


기존 샤딩 기법으로 하면 효율적이지만 급격하게 늘어난 2천만 유저를 커버하기 위해서 한 대에 서비스에 필요한 모든 것을 때려 넣고 서버를 이미지화 해서 병렬로 늘린 뒤에 gateway서버를 만들어 유저의 번호당 샤딩을 하고 어느정도 지나 유저가 줄어든 서버들끼리 통합하는 로직을 보면 많은 분들이 그게 무슨 샤딩이냐고 비웃지만, 그게 엄연히 최고 성능을 보여준 샤딩 기법이었다거나, 


테이블이 많아지면 필드명 만으로는 알아먹기 힘들어집니다. 

단일 DBMS에서 12만개의 테이블도 관리해본 저로서는 

지금도 ERD를 그릴 때 이미 Entity와 Attribute의 룰을 정하고 모든 처리는 프로시저화 하여 웬만한 부하는 RDBMS에서 가지도록 설계합니다. 

그리고 필드명만 봐도 어떤 Entity에서 왔는지, 무슨 역할을 하는지 명확하면서도 길지 않게 만드는 룰을 가지고 있지요. 

Document가 없어도 프로시저만 열어보면 변경이력과 이 필드가 누가 왜 무엇때문에 만들었는지를 나타냅니다. 


이런 사소한 것에 이르기까지, 

프로젝트에 들어갈 때마다 불편하다고 불평만 하면서 다음 프로젝트도 똑같이 하는게 아니라, 

바꾸지 않으면 다음이 없는 환경을 얼마나 경험했느냐가 

바로 퍼포먼스를 이야기할 수 있고, 

나 좀 대규모 해봤어 라고 할 수 있지 않을까요? 


하지만 그 전에 대 전제가 있습니다. 

어떤 서비스를 설계 하더라도 대규모로 되었을 때 흔들리지 않으면서도 

Lean start가 되는 구조를 설계하는건 버릇이 되어 있어야 합니다. 


그런 연습도 없이 갑자기 규모가 커졌을 때 대응할 수 있을까요? 

------------------------------

인프라 비용이 비싸서 수익이 나지 않는 구조라면 여러분들은 지금 잘못하고 있는 것입니다. 

인프라 비용을 줄이고 대규모 처리가 되는 구조를 잘 짜는 사람이 실력이 있는 것이지요. 


지금 하고 있는 감정인식 인공지능 모델 서비스조차도 

제가 들어가고 나서 대규모 처리를 위한 부하 분산 구조를 추가하고도 

개발사에서 제시한 비용의 1/3 정도로 구성을 해 주었습니다.


그럼에도 서비스 단가 대비 인프라 비율을 봤을 때는 

조금 더 복잡해지더라도 인프라 비용을 줄이는 방향으로 더욱 튜닝을 해서 

지금은 초기 예산의 1/5 정도가 되었는데요, 


에전에 이야기 했던 오라클 시스템의 최적화 및 하드웨어 이전으로 

초기 30억원 매년 10억원짜리 비용을 초기 5000만원 + 알파와 연간 1800만원 정도로 낮추었지요. 

어느 누구도 이렇게 제안한 적이 없고 제안할 수도 없었을 겁니다. 


이로서 이 기업은 매출이 있음에도 마이너스였던 사업이 순식간데 매년 수익 10억원 가까이 플러스가 되어 만세를 부르고 있죠. 

--------------------------------------

그러니 지금 아무리 사소한 프로젝트를 하고 있더라도 

이렇게 하면 확장 가능할까? 

불필요한 비용이 지금 나가고 있지 않을까를 항상 생각하면서 

같은 시스템이라도 다양하게 튜닝하고 재설계를 연습하신다면, 

그 경험의 수만큼 많은 능력을 가지실 수 있을 겁니다 !


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 여기서 다운로드 이런 커넥터 들을 붙일 때마다 콘피그를 수정해 줘야 하지만, 몇 번만...