영상버전 : https://youtu.be/4N0v9QUGD_I
얼마전 태국 개발팀이 만들고 운영하던 서비스를 인수인계 받았는데요..
인수인계를 받으면서
서비스 회사의 대표에게서는 태국 개발자들의 대응이 너무 느리다고 불만이 많았고,
태국 개발자들은 일이 많은데 알아주지 않는다고 불만이 많았습니다.
저야 인수인계를 받는 입장이다보니 양쪽 비위를 맞추어 최대한 잘 받아내야 하므로
이런저런 불만을 계속 들어주면서 어르고 달래서 최대한 받아냈죠..
인수인계를 받고 한달 남짓..
아직도 이 서비스를 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년 고생했다 드디어 올해 들어와서 포기한 프로젝트를 알려드릴께요..
수천만만의 유저를 접하는 순간
내가 알고 있는 상식이 통용되지 않는 세상을 만나게 됩니다.
그러면서 드디어 눈이 뜨이게 되는 것이지요.
책에선 그렇게 이야기 안하는데요.. 라던가
유명한 유튜버가, 또는 블로거가 이렇게 하랬어요
라고 한다면 언제나 태클 주세요.
그 구성이면 어느 정도에서 터지는지 이야기 해드리겠습니다.
이번에도 어떤 구성을 하는 것이 좋은지
직접 만드는 시스템에 참고가 되었길 바랍니다.
댓글
댓글 쓰기