본문 바로가기

컴퓨터/노트북/인터넷

IT 컴퓨터 기기를 좋아하는 사람들의 모임방

조회 수 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)가 사용되었다.

 

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

 

 

 


컴퓨터/노트북/인터넷

IT 컴퓨터 기기를 좋아하는 사람들의 모임방

List of Articles
번호 분류 제목 조회 수 날짜
공지 뉴스 구글 최신 뉴스 file 1384 2024.12.12
HOT글 일반 아 진짜 요새 SKT 해킹 뭐시기 때문에 신경 쓰여 죽겠어 ㅠㅠ 2 237 2025.05.20
공지 사랑LOVE 포인트 만렙! 도전 4660 2025.03.19
공지 🚨(뉴비필독) 전체공지 & 포인트안내 2 25848 2024.11.04
공지 URL만 붙여넣으면 끝! 임베드 기능 20431 2025.01.21
10640 일반 Synology의 4 베이 NAS 장비 "DiskStation DS416j" 1456 2016.02.08
10639 일반 태블릿 PC의 충전을하면서 주변 기기를 사용할 수있는 OTG 지원 USB 허브 1434 2016.02.08
10638 일반 카페베네 상장 난항에 투자자 눈물 776 2016.02.15
10637 일반 주식, 욕심은 화를 부르고. 그 화는 고스란히 가족들에게 짜증을 부릴겁니다 789 2016.02.22
10636 일반 원익IPS 추천합니다 676 2016.02.22
10635 일반 장이 너무 안좋네요 ㅜㅜ 707 2016.02.22
10634 일반 주식투자와 관련된 주식명언 999 2016.02.22
10633 일반 i5-6600 i5-6500 비교 1 1434 2016.02.22
10632 일반 ssd좀봐주세요 2 906 2016.02.27
10631 일반 크라운제과 어떻게 보시나요? 458 2016.02.28
10630 일반 흑자예상하며 기다린보람이 있군 471 2016.02.28
10629 일반 세계 주식 주요 지수 보는곳 입니다.모르시는분들을 위해 646 2016.02.28
10628 일반 한 2월 말쯤 총선테마가 시작될걸로 예상합니다. 562 2016.02.28
10627 일반 대중관계 악화로 중국에서 돈버는 기업들 급락이네요 684 2016.02.28
10626 일반 주식 생초보인데 알려주실수 있으신가요? 515 2016.02.28
10625 일반 11시정도만 잘 넘기면 될거같은데.. 478 2016.02.28
10624 일반 요즘 한종목에 꽂혀서 분할매수하는데요. 565 2016.02.28
10623 일반 본인 명의로 핸드폰 두개 개설 하면 문제 생기나요? 1 1154 2016.03.01
10622 일반 단말기대금 일시불납 가능한가요? 1 781 2016.03.05
10621 일반 노트4 배터리 공유?? 1 1749 2016.03.05
10620 일반 금호타이어 어떻게 보시나요? 650 2016.03.05
10619 일반 해외에서 사용하던 도메인을 구입했는데 헉.. 568 2016.03.09
10618 일반 축구 페널티킥 선방 탑10 469 2016.03.12
10617 일반 SSD의 성능을 유지하기위한 유지 관리 기술 1068 2016.03.15
10616 일반 저렴한 Skylake 버전 Xeon 마더보드 'GA-X150M-PRO ECC」 874 2016.03.15
10615 일반 G5 vs S7 1 626 2016.03.18
10614 일반 스테레오믹스 소리가 안납니다 1 1104 2016.03.19
10613 일반 스피커를 항상 켜 놓는데요. 노이즈??? 소리가 납니다. 1 850 2016.03.19
10612 일반 M2 메모리 추천 1 911 2016.03.19
10611 일반 모니터 단자 HDMI, DP & 오디오 관련 문의 1 865 2016.03.19
Board Pagination Prev 1 2 3 4 5 6 7 8 9 10 ... 355 Next
/ 355