기본 콘텐츠로 건너뛰기

태국 개발자들이 버리고 간 폭타




얼마전 태국 개발팀이 만들고 운영하던 서비스를 인수인계 받았는데요.. 

인수인계를 받으면서 
서비스 회사의 대표에게서는 태국 개발자들의 대응이 너무 느리다고 불만이 많았고, 
태국 개발자들은 일이 많은데 알아주지 않는다고 불만이 많았습니다. 

저야 인수인계를 받는 입장이다보니 양쪽 비위를 맞추어 최대한 잘 받아내야 하므로
이런저런 불만을 계속 들어주면서 어르고 달래서 최대한 받아냈죠..

인수인계를 받고 한달 남짓..
아직도 이 서비스를 100% 이해를 못했습니다. 
하지만, 점점 양쪽의 입장을 이해하기 시작했습니다. 

일단은 구조를 보시죠.. 

이 구성도 역시 타이 개발자들이 준게 아니라
그냥 디플로이 매뉴얼과 
어카운트 정보 표를 보고 하나하나 들어가서 보면서 만든겁니다. 
즉, 아직도 빠진게 있을지도 모른다는 것..

구조를 보면 이상한 툴들이 많이 보이죠?
대부분의 대규모 경험을 한 사람일 수록
리스크 포인트를 줄이기 위한 노력을 합니다. 
그 결과가 단순화, 
그리고 장애시 빠른 복구가 가능한 구조, 
확장이 편리한 구조를 많이 생각하죠. 

이 말은 이 서비스는 MSA가 되어있느냐를 항상 질문하게 되죠.
MSA는 아주 작은 단위로도 독립적인 서비스로서 기동이 가능하게 만들어야 하구요.., 
그 기능들끼리 API등으로 연결해서 
장애시 장애 포인트의 확인이 쉽고, 
병목이 발생하면 그 부분만 확장이 가능한 구조를 가져가게 됩니다. 
그렇게 하면 쉽게 확장이 되고, 
운영이 간단하죠. 

즉, 특정 모듈이나 솔루션, 미들웨어를 설치할 때, 
이것 없이 더 단순화 할 수 있는지를 계속 물어가면서 만들어야 하구요, 
개발 공수보다 이 모듈을 넣는게 낫겠다면, 
그 모듈을 넣고나서 운영을 어떻게 편리하게 할지를 고민해야지요. 

이런 복잡한 구조가 되었다는 것은
경험이 부족한 사람들이 
인터넷에 있는 것을 짜집기 하다보니
뭐에 쓰는지도 모르고 다 올렸기 때문이죠..

그럼 다시 이 구조를 자세히 뜯어보겠습니다.

## 인증 시스템

인증 하나를 유지하기 위해서 
OpenLDAP과 KeyClock, Redis를 이용해서 관리를 합니다. 
그리고 OpenLDAP의 UI 관리 서버, KeyClock의 UI 관리 서버를 따로 쓰고 있습니다. 
OpenLDAP및 KeyClock은 프로세스만 띄우면 되지만 상태관리등을 위해서 UI서버를 별도로 두었지요. 
게다가 인증토큰 보관은 redis로 하고 있어요..
서버 한 대에 쓸걸 왜 굳이 또 redis를 쓰는거지?

제가 경험 했던 대규모 서비스는 
Oauth2를 확장한 자체 계정관리 시스템을 가지고 
Google등의 서드파티 어카운트를 연결합니다. 

이유는 계정 정보는 동시 처리가 가장 중요하고, 
인증만 받으면 되지 LDAP같은 세세한 디렉터리 보안 구조를 전부 로드할 필요가 없기 때문이죠. 
단일 서버에 가벼운 모듈 형태로 올려 서비스가 가능하고
유저의 규모에 따라 인증 서버를 병렬로 늘려도 
인증 정보를 클라이언트가 암호화 해서 가지고 필요시 인증서버에
유효한지만 날리면 되거든요.. 
굳이 서버에 남기겠다면 redis를 쓰는 것도 방법이지만, 
Redis역시 대규모에 취약한 대신 고속이구요, 
대규모 처리를 하게 되면 결국 redis를 변칙적으로 사용하거나
별도 세션 서버를 가지거나
결국 클라이언트에게 부담을 전가할 수 밖에 없습니다. 
수천만 유저를 메모리에 세션정보를 가지는 비용을 생각해야죠.. 

LDAP이란 개념도 오래 되었잖아요?

그렇게 말씀하시는 분들이 계시죠?
하지만 LDAP은 현재도 윈도우즈 AD로도 쓰고, 
리눅스나 유닉스의 계정 시스템으로도 쓰고 있습니다. 
LDAP이란 Light Directory Access Protocol라는 것으로 
유저들이 서버 리소스에 접근할 떄 필요한 
세세한 권한을 컨트롤 하는데 사용하는 인증 시스템입니다. 
다단계 트리구조 멤버십 데이터를 엑세스 하는 방식이기 때문에
DB에서 쉽게 가져오는게 아니라 
쿼리할 때마다 연결된 속성을 전부 가져와서 비교해야 하므로 성능이 현저히 저하되죠. 
그리고 데이터를 메모리에 올려놓지 않으면 쿼리가 너무 느려지기 때문에
데이터 사이즈에 맞는 메모리가 필요하게 됩니다. 



100만명 이상의 액티브 유저를 가정하면
순간 피크 10만 인증처리 (로그인, 세션 유지)를 상정해야 하고, 
그러기 위해서는 단순히 10대의 서버가 필요합니다. 

하지만 대규모 서비스를 만들 때 4000만명이 하루에 들어오는 서비스를 만들 때 
독자 인증 시스템으로는 장애 때문에 4대로 했지 성능은 두 대로 충분 했지요. 

인증만 이렇게 복잡한가요?

도메인 리졸빙 방법을 보면,
Cloud Flare 의 네임서버에서 
델리게이트를 받아 VM에 DNS를 띄운 뒤에
거기서 하나의 IP로 전부 Resolving된 뒤에
Nginx Proxy 서버를 열어서 거기에서 Host Forwarding을 시켰네요.. 
Nginx Proxy는 HTTP헤더에서 도메인별 포워딩이 가능하기 때문에 
한 군데 모아서 필요에 따라 배분해주는 기능이 가능합니다. 
어떻게 보면 L7 로드 밸런싱을 효율적으로 만든 것 같잖아요?

이건 무슨 문제를 일으킬까요?

우선 DNS하나만으로 충분한걸 DNS 두 번 거치구요, 
거기에 다시 NGINX proxy를 다시 거쳐서 결국 VM으로 들어가게 됩니다. 
불필요한 노드가 3개 늘면 네트워크 장비까지 생각하면 최소 6홉이 늘어납니다. 
홉이 늘어날 수록 latency가 떨어지기 때문에 응답이 느려져 자연스럽게 퍼포먼스가 떨어지죠.

게다가 이 노드 수 만큼의 리스크 포인트가 늘어납니다. 

가장 중요한 것은 한 서버에 모든 트래픽이 집중하게 되어 
Nginxproxy 가 트래픽이 많아지면 터집니다. 

LB는 크게 In-Line구조와 one arm구조로 나뉘고
https://skstp35.tistory.com/221?utm_source=chatgpt.com
이들이 다시 DSR, Reverse Proxy, NAT, ECMP등 다양한  방식으로 나뉘는데, 
이 중에 In-Line구조가 되는 NginxProxy 등은 모든 트래픽을 다 받아서 분리를 하게 됩니다. 
제가 맨날 ALB쓰면 혼내는 것 같은거죠.. 

메인 트래픽의 한계를 넘어서는 서비스를 할 수 없구요, 
트래픽 비용이 엄청나게 나옵니다. 

하지만, One-Arm구조가 되는 DNS같은 서비스는 
최종 위치만 묻지 트래픽은 전혀 받지 않습니다. 
즉, 트래픽 만 정확하게 파악해서 분산해버리면
이론상 무한대로 트래픽을 받을 수 있는 구조인거죠. 
중간에 ALB가 있는 곳에 Router가 있지 않냐구요?
Router는 단순 방향 지시만 하기 때문에 
ALB같은 L4/L7에 비해 수 배에서 수십배의 처리능력을 가지게 됩니다. 
비용역시 ALB에 비하면 물리적 가격으로도 1/10정도 하지요. 
그렇기 때문에 AWS에서는 라우터 비용을 책정하지 않고, 
트래픽 제한도 없는 것입니다. 
당연히 물리적으로는 있지만 VM단위로 QoS를 걸어 놓기 때문에
충분히 여유가 있는 것이죠.

제가 프로젝트 매니징 할 때는 
처음부터 Route53을 쓰도록 개발을 시키는 이유가 
바로 이것입니다. 

물론 별로 규모도 안되면서 이렇게 할 필요는 없으나, 
서비스를 만든다는 것은 성공을 목표로 만드는거 아닌가요?
10만명 받으면 우린 더이상 안받을거야 하는 서비스를 만들건가요?

각각이 장단점은 있습니다. 
개발이 편한 것이 ALB이고, 
수백만 이상 세션을 받으려면 Route53같은 
One-arm 기반 LB 말고는 없다고 보시면 됩니다. 

이것과 같은 것이 F5의 BIG-IP라는 수천에서 수억에 달하는 장비나
CDN서비스에 사용되는 GLB, Azure의 Front Door등이 있죠. 
순간 10GB이상 트래픽을 유발하는 서비스라면 다들 쓰시는 것이죠.. 
최대 20Mbps도 안쓰는 서비스만 경험하셨다면
이해할 수 없을 구성이 되죠.. 

마지막으로 체크해야할 리스크 포인트는..

Docker관리가 귀찮으니
Kubernetes를 쓰는것도 모자라
Proxmox를 이용해서 Kubernetes를 관리하네요. 
쉽게 VM과 Docker를 통합 관리하니까 좋잖아 라고 하실 수 있겠지만, 

이걸 설치하기 위해서 

Proxmox, Kubernetes, Docker, Rancher 를 설치하고, 
서비스별 디스크 영역을 관리하기 위해 NAS를 설치하고 NFS를 추가로 설치했죠. 

이 모두가 장애포인트이고, 
서로 복잡하게 연결되어 뭐 하나 장애가 발생하면 
서로 얽혀 있어 전체 장애가 납니다..

아마도 인터넷 찾아가면서
뭐가 좋더라 하는 기사 보면서 하나씩 개고생해서 연결한 거 같은데요.. 

Docker는 써보신 분은 아시겠지만, 
자주 업데이트하지 않는 소스를 콤포넌트, MW와 같이 묶어 배포하기 좋은 툴이지, 
매일 개발하여 일주일치 몰아서 하루만에 업데이트하거나 하는 경우 Docker를 쓰다보면
이미지를 묶는 시기도 맞추기 어렵고, 
배포 직전에 수정하게 되면 오히려 큰일이 납니다. 

차라리 github에서 CI/CD로 
서비스 중인 인스턴스 마다 설정해두고 
서비스에 맞춰서 일제히 deploy하거나 
노드 마다 시간을 두어 deploy하면서 LB에서 뺐다 넣었다 하면
무정지 업데이트도 가능해지죠. 

둘 다 쓴다구요?
복구용 이미지는 docker를 써도 됩니다. 
단지, 그럴 거면 cloud에서 제공하는 vm이미지로 정기적으로 만들어두면
굳이 docker를 쓰지 않아도 한 달에 이미지 비용 천원 정도만 내면 됩니다. 
Rancher에서 복잡하게 얽힌 순서대로 디플로이 하다가 하나 망가지면
개고생하는 운영은 전 사양하고 싶네요..

요즘처럼 많아지는 툴 속에 
뭐가 좋다고 무조건 도입하다보면
이런 복잡한 구조에서 운영이 힘들어 손을 들게 됩니다. 

개발을 하던 설계를 하던
이 서비스에 가장 맞는 규모를 찾고, 
운영 방식을 고려해서 최소한의 설계를 하면
확장도 쉽고 운영도 쉽게 되지요.. 

만약 저라면 이렇게 했을 겁니다. 

----
제안 구성 도..(영상참조)
---

이 정도로도 동일한 기능을 할 수 있고, 
확장도 쉽고 무한하게 확장이 가능합니다. 

대규모 경험이 꼭 필요하다고 누누히 이야기 하는 이유이기도 하죠. 

책에서 배우는 최적화 이론은 이론일 뿐이고, 
소규모에서나 쓰는 것입니다. 
샤딩을 알고리즘이나 솔루션을 쓰는 것은 
1Gbps이상을 커버할 일이 없고
돈이 수억 남아도는 경우나 쓰는 것입니다. 

NoSQL도 제가 맨날 욕하잖아요.. 
NoSQL만으로 RDBMS없이 서비스 된다고 하시는 분들
동접 10만 경험 하지 못하신 분입니다. 
다들 대규모를 경험하시면 
두 번다시 NoSQL을 쳐다보지 않을 정도이죠. 

물론 NoSQL을 뼛속까지 잘 안다면
대규모 처리 중에 일부 RDBMS를 능가하는 
부분이 있습니다. 일부 이지만요..

다음번엔 SQL Server를 NoSQL로 이전하려고
3년 고생했다 드디어 올해 들어와서 포기한 프로젝트를 알려드릴께요.. 

수천만만의 유저를 접하는 순간
내가 알고 있는 상식이 통용되지 않는 세상을 만나게 됩니다. 
그러면서 드디어 눈이 뜨이게 되는 것이지요. 

책에선 그렇게 이야기 안하는데요.. 라던가
유명한 유튜버가, 또는 블로거가 이렇게 하랬어요
라고 한다면 언제나 태클 주세요. 
그 구성이면 어느 정도에서 터지는지 이야기 해드리겠습니다. 

이번에도 어떤 구성을 하는 것이 좋은지
직접 만드는 시스템에 참고가 되었길 바랍니다.



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

댓글

이 블로그의 인기 게시물

일본 두바퀴 여행(바이크 편)

영상버전 : https://youtu.be/P3vC17iVu1I 이번에는 일본으로 넘어와서 일본 종주하시는 바이커들을 위한 정보입니다.  일본에서의 2륜의 정의가 면허와 도로교통법이 조금씩 다르다고 합니다.  그래도 그렇게 크게 신경쓸 건 없으니 딱 세 종류로 말씀 드릴께요.  50cc는 원동기 1종이라고 하여 3차선 이상 교차로에서 우회전, 한국에선 좌회전 같이 크게 도는 것이지요..  이게 불가능합니다.  직진 신호로 넘어간 뒤에 방향을 틀고 다시 직진으로 두번 꺾어 가야 하구요,  두 명이 타면 안됩니다.  그리고 맨 가장자리 길로만 가야해서 애매하게 끝에서 두 번째 차선만 직진인 곳들이 있어서 난감할 때가 있지요. 그런데에 직진하면 걸리는 곳이 있다고 합니다. 어느 정도까지 걸리고 안걸리고는 정확히는 모르지만,  직좌 마크가 아닌 좌회전 마크만 있는 곳이 은근히 많으니 조심해야 하겠더라구요.  최고 시속도 30km를 넘기면 안되어 천천히 달려야 합니다.  아뭏든 제약이 엄청나게 많으므로 60cc이상을 가져오시거나 렌트 하시는 것을 추천하구요,  125cc미만은 겐츠키 2종이라고 하여 두 명이 타도 되고, 3차선 이상에서 우회전이 가능합니다.  상당히 제약이 풀리는 대신 고속도로를 탈 수가 없지요.  만약 국도로 천천히 올라오신다면 125cc미만으로도 충분합니다.  실제로 일본인 바이커들 중에서도 국도 종주하는 모습을 많이 볼 수 있구요,  도심에 가면 125cc미만까지만 주차 가능한 바이크 주차장도 꽤 많기 때문에 도심용으로는 메리트가 큰 것 같습니다.  뭐, 125cc대는 곳에 큰 바이크를 대는 경우도 자주 보는데, 아무도 뭐라 안하긴 합니다.  그도 그럴 것이, 일본의 바이크 등록대수는 1031만대 인데도 바이크 전용 주차장은 턱없이 부족하다고 합니다. 바이크 주차장이 저렴하기 때문에 웬만한 ...

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

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