본문 바로가기
조회 수 66 추천 수 0 댓글 0

단축키

Prev이전 문서

Next다음 문서

수정 삭제

단축키

Prev이전 문서

Next다음 문서

수정 삭제
Extra Form

이 글의 내용을 요약하면, "대량의 TCP / WebSocket 동시 연결(최소 65K 이상, 가능하다면 10M)을 처리하기 위한 환경을 구성하고 Tornado를 사용해 이를 테스트하는 간단한 프로그램을 만들어 보았다”이다. 일반적으로 재미있을만한 주제가 아니므로, 관심이 없는 내용이라면 뒤로 가기 버튼을 눌러 재빨리 빠져나가도록 하자.

 

이 작업을 시작한 이유는, 그 동안 개인 프로젝트(Fountain)를 진행하면서 Scale-up에 대해 생겼던 궁금점을 해결하기 위함이었다. 대량의 웹 트래픽 처리에 관심이 있는 사람이라면 C10K problem(=10,000개 이상의 네트워크 동시 연결Concurrent connection을 지원하는 서버를 구축하는 문제)에 대해 들어본 적이 있겠지만, 사실 유닉스 계열 운영체제에서 이 문제는 시스템에서 사용 가능한 file descriptor 숫자만 늘려주면 된다. 예전에야 컴퓨터의 리소스가 한정되어 있어 극단의 최적화가 필요했겠지만, 어쨌든 요즘 나오는 PC라면 최대 fd 수만 늘려줌으로써 (성능이야 어떻든) 10K 이상의 소켓 연결을 처리할 수 있다.

 

나는 TCP / WebSocket 연결을 지원하는 리얼타임 서버를 만들어야 했었고, Tornado로 이걸 구현하기로 했다. fd 숫자를 늘리고, local port range를 조정하고, 간단한 서버 / 클라이언트 코드를 작성해서 50,000개의 연결이 제대로 생성되고, 메시지를 주고받는 것을 확인하였다. 이게 작년의 이야기. (C10K tuning에 관련된 내용은 구글에 검색해 보면 많이 있으므로 그 내용을 참고하시라)

 

그리고 시간은 흘러서 얼마 전 모 회사에서 인터뷰를 할 일이 있었는데, 리얼타임 서버에 대한 이야기가 나왔다. 이 시점까지 나는 리얼타임 서버가 50K 이상의 연결을 처리할 일이 있을까에 대한 생각 자체를 해보지 않았다. 예를 들어보자면, 안드로이드를 지원하는 Push notification 서버 혹은 Messaging server 같은 경우 실제 트래픽은 상대적으로 적지만 대량의 연결을 계속 유지해야 하는 경우가 있다. 이런 유형의 서버가 있을 때 Scale-up을 어떻게 할지에 대한 질문을 받은 것이었다. inbound traffic을 모니터링하면서 상대적으로 가벼운 인스턴스를 계속 spawn하면 되지 않겠느냐 했지만 그것은 올바른 대답이 아니었다(…)

 

계속 인터뷰는 이어져서 내 개인 프로젝트에 대한 이야기가 나왔을 때, 내 서버가 얼마나 많은 동시 연결을 처리할 수 있냐는 질문에 ’5만개 연결까지는 테스트해봤지만 아직 그 이상 scale-up에 대해서는 아직 고민해보지 않았는데요’고 대답하니 ‘5만개요? (시무룩)’이라는 반응이 돌아왔다. 여기서 좀 당황했는데, 이때까지 나는 5만 개 이상의 동시 연결을 처리하는 서버를 구현할 일이 있을까라는 생각 자체를 해 본 적이 없기 때문이었다. 아니 이제 5만 개 동시 연결을 처리하는 걸로도 부족한 시대가 되었단 말인가!

 

새삼 궁금해져서 집에 돌아와 관련 내용을 검색해보니 이런 아티클을 찾을 수 있었다:

Whatsapp은 어떻게 5억 명의 사용자, 11,000개의 cpu 코어, 초당 7천만개의 메시지 처리까지 성장하였나 (영문) http://highscalability.com/blog/2014/3/31/how-whatsapp-grew-to-nearly-500-million-users-11000-cores-an.html

 

위 글을 읽어보면 알겠지만, 해당 글이 쓰인 시점에서 Whatsapp은 150대의 챗 서버로 1억 5천만 개의 동시 연결을 처리하고 있었다. 챗 서버 한 대당 1백만 개의 동시 연결을 처리하고, peak time에는 150만개 연결을 처리하기도 했다고.

 

이걸 읽고 나서 처음 든 생각은, ‘그래, 그런 서버를 구현한다고 치고, 테스트는 어떻게 하지?’ 였다. OS가 개별 소켓을 식별하는 방법을 알고 있는 사람이라면 금방 이해하겠지만, 소켓은 보통 local address와 remote address 두 값의 쌍으로 식별되며 (address는 192.168.0.10:8080처럼 ip:port 형태로 표현된다), 이 두 값이 중복되는 소켓은 존재할 수가 없다. 만약 한 개의 호스트 내에서 8080 포트를 listen하는 서버를 실행하고, 클라이언트를 실행해서 여러 개의 소켓을 생성해 이 포트에 연결하면 다음과 같은 주소를 갖는 소켓들이 생성된다:

 

local address remote address
192.168.0.10:20001 192.168.0.10:8080
192.168.0.10:20002 192.168.0.10:8080
192.168.0.10:20003 192.168.0.10:8080
192.168.0.10:20004 192.168.0.10:8080

 

이게 뭐가 문제냐면, 포트 번호는 0~65,535까지로 한정되어 있기 때문에, 이 범위의 포트 번호를 전부 사용하고 나면 더 이상 local address를 위한 포트 번호를 할당할 수 없게 된다. 그러므로 이상적인 상황을 가정할 때 로컬에서 실행한 서버에 연결할 수 있는 최대 연결 수는 65,536개라는 이야기. (물론 실제로는 이런저런 제약 때문에 그 숫자가 더 작아진다) 물론, 서버 한 대와 클라이언트 여러 대가 포함된 테스트 환경을 구축한다면 이 문제는 피할 수 있다. local address에 여러 IP를 사용할 수 있다면 그 IP 개수 만큼 전체 연결 개수를 늘릴 수 있으니까. 하지만 서버 하나 테스트 하겠다고 그런 환경을 구축한다는 건 좀 에러고...

 

그래서 이를 피하기 위해 이용한 꼼수는, 서버가 여러 포트를 listen하게 하는 것. 그렇게 하면 이런 식으로 소켓을 생성할 수 있다:

 

local address remote address
192.168.0.10:20001 192.168.0.10:8080
192.168.0.10:20001 192.168.0.10:8081
192.168.0.10:20002 192.168.0.10:8080
192.168.0.10:20002 192.168.0.10:8081

 

위와 같이, local address가 같더라도 remote address가 다르면 소켓을 식별할 수 있으므로, 서버에 할당한 listen port 수 * 50K 만큼의 연결을 만들어 테스트할 수 있는 것이다. 천만 개의 소켓을 테스트하고 싶다? 서버에 listen port를 200개 할당하면 된다. 즉, 200 * 50,000 = 10,000,000 (10M). 호스트에 여러 IP를 할당하는  것도 한 가지 방법이기는 하지만, 네트워크 설정을 수동으로 변경해야 하므로 귀찮다.

 

 

어쨌든 이런 방법을 사용하면 개발 환경에서도 10M 연결을 테스트할 수 있다. 하지만 주의사항이 있는데, 어떤 이유에서인지 모르겠지만 OS X에서는 이 방법을 사용해도 65K 이상의 연결을 생성할 수 없다. netstat으로 확인한 결과 OS X에서는 remote address가 서로 다르더라도 local address가 중복되는 경우가 없으며, 무조건 local address를 사용하여 소켓을 식별하는 것으로 추정된다. (추정일 뿐이라 정확하지 않을 수 있다. 이 방식을 변경할 수 있는 설정이 어딘가 있을 것 같기도 한데, 불행하게도 찾지 못했다) Ubuntu Server 14.10에서는 확실히 동작하는 것을 확인했으므로, 삽질이 귀찮다면 Ubuntu Server 14.10를 사용하시기를 권한다. 뭔가 잘못되어도 내가 도울 수 있는 부분이 없다;

 

그러면 이제 OS 튜닝으로 넘어가야 하는데… 사실 이 튜닝에 대한 방법은 OS마다 서로 다르고, 어떤 종류의 서버를 구현하느냐에 따라 필요한 설정이 달라지는 관계로 스스로 검색하면서 필요한 내용을 찾아보는 수 밖에 없다. 내 경우만 해도 Ubuntu와 OS X를 같이 세팅해야 했던 상황이라 설정 내용을 공유하기도 그렇고… 이 작업을 하면서 도움이 되었던 링크 몇 개를 공유하는 것으로 대신한다 (모두 영문):

 

The C10K problem

http://www.kegel.com/c10k.html

 

Performance Tuning the Network Stack on Mac OS X Part 2

https://rolande.wordpress.com/2014/05/17/performance-tuning-the-network-stack-on-mac-os-x-part-2/

 

Linux TCP/IP tuning for scalability

http://www.lognormal.com/blog/2012/09/27/linux-tcpip-tuning/

 

RED HAT ENTERPRISE LINUX 7 PERFORMANCE TUNING GUIDE (CentOS에도 적용 가능)

https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/Performance_Tuning_Guide/index.html

 

The C10M(!) problem

http://c10m.robertgraham.com/p/manifesto.html

 

 

 

그리고 이를 테스트하기 위해 급조한 코드를 여기 공유한다:

https://github.com/kenial/tornado-test-c10m

 

위 코드는 TCP / WebSocket을 지원하는 Echo 서버와 클라이언트로 구성되어 있는데, 클라이언트에는 대량의 소켓을 생성하거나 메시지를 전송할 수 있는 기능이 구현되어 있다. Python으로 작성되어 있고, 사용하려면 Tornado를 설치해야 한다. PyPy를 사용할 경우 성능 향상이 있기는 한데, 이 프로그램이 하는 일은 대부분 I/O에 관련된 작업이다보니 패킷 전송에는 그다지 성능 향상이 없었고, 연결 생성에는 상당한 성능 향상이 있었다.

 

 

 

Ubuntu Server 14.10에서 실행해 본 소감은, 메모리를 무지하게 먹는다. 위 프로그램을 실행해보면 TCP는 연결당 10.5KB, WebSocket은 연결당 15.5KB 정도가 할당된다. 이는, 만약 1백만 개의 연결을 생성하면 TCP 연결의 경우 1,000,000 * 2 * 10,500 = 21,000,000,000B = 21GiB의 메모리를 사용한다는 의미. (중간에 2를 곱한 것은 소켓이 생성될 때 서버에서 한 개, 클라이언트에서 한 개가 생성되기 때문이다) WebSocket의 경우에는 오버헤드가 더 있어서 31GiB 정도를 사용한다는 계산이 나온다. 1천만 개의 연결이라면? 각각 210GiB, 310GiB가 될 것이다. 케냘 소유의 PC 중에서는 21GB가 넘는 메모리를 가진 시스템이 없기 때문에 1백만 개의 연결 생성조차 테스트할 수가 없었고(…) EC2에 인스턴스를 생성해서야 테스트가 가능했다. 테스트에는 r3.4xlarge 타입의 인스턴스(122GiB memory)가 사용되었다.

 

실행 결과 화면을 첨부하는 것으로 이 글을 마무리할까 한다.

 

 

 


List of Articles
번호 분류 제목 날짜 조회 수
공지 사진📸 사랑LOVE 포인트 만렙! 도전 2025.03.19 4644
공지 안내 🚨(뉴비필독) 전체공지 & 포인트안내 2 2024.11.04 25845
공지 System URL만 붙여넣으면 끝! 임베드 기능 2025.01.21 20431
375786 유머 현재 너무 동안이라 난리난 예지원 엄마 newfile 2025.05.21 63
375785 유머 SKT 위약금 재점화... 법조계 불가의견 newfile 2025.05.21 60
375784 유머 엘리트 여대생이 60대 할배와 마약 SEX newfile 2025.05.21 61
375783 유머 한국으로 역이민오는 미국 한인들 newfile 2025.05.21 58
375782 유머 여자 노산이 장점도 있지 않아? newfile 2025.05.21 64
375781 유머 집앞에 연예인 왔다고 해서 1열에서 구경 중 newfile 2025.05.21 68
375780 유머 단독 ] 트럼프, 멜라니아 여사와 리벤지 포르노·딥페이크 범죄 대응 법안 서명 newfile 2025.05.21 55
375779 유머 단 1개의 영상으로 구독자 130만에서 27만으로 떨어진 유튜버 newfile 2025.05.21 66
375778 유머 남자가 뭔가 변하고있는걸 눈치챈 여초커뮤 newfile 2025.05.21 69
375777 유머 물로 설명하는 호텔경제학 newfile 2025.05.21 56
375776 유머 [단독]국내 최초 상업용 ESS, 10년만에 셧다운 newfile 2025.05.21 57
375775 유머 하사임관으로 인생이 망했던 한 선임 이야기 newfile 2025.05.21 58
375774 유머 홍콩서 30명 사망…잠잠하더니 중국 이어 태국도 코로나 재확산 new 2025.05.21 63
375773 유머 19) 700 만원에 왕대접 받을 수 있는 천조국 섹수투어 newfile 2025.05.21 54
375772 유머 대기업 비서가 2년만에 그만 둔 이유 newfile 2025.05.21 61
375771 유머 속보) 청년층 결혼 긍정 인식 대폭 증가 newfile 2025.05.21 72
375770 유머 공익 남친이 부끄럽다는 여자친구 newfile 2025.05.21 68
375769 유머 교사들이 교실에서 성관계 하다가 학생이 목격 new 2025.05.21 63
375768 유머 일본인만 가지고있는 유전자 ㄷㄷ new 2025.05.21 54
375767 유머 가족, 친구 사이에 여행 중 절대로 하면 안되는 말 new 2025.05.21 55
375766 유머 네이버웹툰 보고 비트코인 투자해 집 산 사람 new 2025.05.21 68
375765 유머 남녀 데이트 비용은 7:3이 적당하다는 여자 newfile 2025.05.21 63
375764 유머 얼공안한 여 스터디 반캠 실수 사건 newfile 2025.05.21 66
375763 유머 [속보] 경찰, '중국 간첩 99명' 보도한 스카이데일리 기자에 구속영장 신청 newfile 2025.05.21 63
375762 유머 안정환 가족 완전체 근황 newfile 2025.05.21 64
375761 유머 여친 몸매 위해서 희생하는 남친 newfile 2025.05.21 56
375760 유머 흑화한 번따남 newfile 2025.05.21 58
375759 유머 청년세대의 감성으로 "국민연금" 홍보 나선다 newfile 2025.05.21 55
375758 유머 남편이 고속도로에서 차를 세운이유 newfile 2025.05.21 55
375757 유머 [속보] 영등포에서 불심검문중 총기소지자 검거 newfile 2025.05.21 56
Board Pagination Prev 1 2 3 4 5 6 7 8 9 10 ... 12527 Next
/ 12527