일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 웹 커리큘럼
- 웹 스터디
- reactor core
- 웹앱
- reactor
- Spring Framework
- 서버운영
- ipTIME
- reactive
- Spring Batch
- 공유기 서버
- spring reactive
- Today
- Total
Hello World
UDP를 사용할 때 고려해야 할 것들 본문
안녕하세요. NHN엔터테인먼트 권오범입니다.
그 동안 TOAST Cloud 의 Real-Time Multiplayer 서비스를 개발하며, 경험한 부분에 대해서 간단히 정리 해보려고 합니다.
몇 년 전부터 UDP에 대한 언급이 많아진 것 같습니다. 사실 해외보다 국내에서 UDP는 다소 생소한 것 같습니다. 개인적 의견으로 최고 수준의 네트워크 인프라 때문이 아닌가 생각합니다. 하지만 북미의 경우, 2000년 초반만해도 게임 서버와 동영상 서비스의 주요한 프로토콜은 UDP였습니다. 아직도 대다수의 상용 게임 서버는 UDP를 주요한 프로토콜로 사용하고 있습니다. 하지만 국내에서는 2000년 이 전부터 TCP로 실시간 멀티플레이어 게임을 구현했습니다. 이런 이유로 TCP와 비교해서 UDP에 대한 정보는 다소 부족한 것이 사실입니다.
최근 UDP가 자주 언급되기 시작한 시기는 2013년 구글에서 발표한 Quic과 해외 상용 게임 네트워크 라이브러리와 서비스들이 국내에 공개되면서부터인 것 같습니다. 게임 관련 서비스 및 라이브러리는 애플과 구글의 P2P용 멀티플레이어 게임 API와 Photon, RakNet, 마지막으로 유니티의 UNet등이 대표적입니다. TCP와 UDP가 모두 구현되어 있지만 권장 프로토콜은 UDP입니다. 물론 국내에도 CGCII와 ProudNet 등과 같은 좋은 상용 라이브러리가 있습니다. 이런 라이브러리의 주요한 공통점은 Multiplexing, 선택적 암호화, 다양한 QoS지원 등을 들 수 있습니다. 그리고 Quic은 크롬으로 클라이언트 환경을 정복한 구글에서 네트워크 구간의 Web 성능 향상을 위해 만들어진 기술입니다. 기존 TCP와 비교해서 빠른 connection establishment와 head of blocking 방지 기능, Forward error correction, 효율적인 재전송 전략 등이 대표적인 기능입니다.
그럼 UDP를 사용했을 때, 자주 언급되는 내용에 대해서 간략히 살펴보겠습니다.
멀티플랙싱
멀티플랙싱을 사용하는 주요한 이유는 head of blocking을 방지하기 위해서입니다. 하나의 TCP는 단일 채널을 사용하므로, 의미 단위 또는 도메인이 다른 데이터의 지연 및 패킷 유실이 다른 데이터에 영향을 줍니다. 그래서 여러 채널을 사용해 불필요한 지연을 막는 기법입니다. 그래서 웹 브라우저의 경우, 다수의 HTTP 요청을 처리하기 위해 일반적으로 6개 정도의 TCP 소켓을 사용합니다. 그리고 6개보다 많은 TCP 연결을 사용하게 되면 성능적인 문제점을 가지게 됩니다. 하지만 UDP를 사용하면 성능적으로 많은 장점을 가질 수 있습니다. 게임 역시 각 게임 오브젝트에 별도의 채널을 할당해서 성능 향상을 기대할 수 있습니다.
다양한 QoS 지원
TCP는 하나의 타입의 QoS를 제공하는 프로토콜입니다. 모든 데이터는 신뢰성 있게 차례로 전달됩니다. 즉, TCP가 제공하는 QoS는 모든 애플리케이션에 적용할 수 있지만, 모든 애플리케이션에 최적의 프로토콜이라고 할 수는 없습니다. 다양한 형태의 QoS가 있지만, 대표적으로 게임과 음성 및 화상 통화에서 많이 사용되는 QoS로 신뢰성은 없지만 차례로 전달되는 방식이 있습니다. 물론 게임과 화상 통화의 구현은 애플리케이션의 특성에 맞게 서로 다를 수 있습니다. 즉, UDP로 애플리케이션과 데이터의 특성에 맞게 프로토콜을 구현하는 것을 말합니다.
빠른 connection establishment
Quic에서 대표적인 장점으로 내 새우는 기술 중 하나입니다. TCP로 SSL을 사용하는 경우, 3-way 핸드쉐이크를 진행하고 암호화를 위해서 데이터 교환이 이루어진 후에야 연결이 성립되므로 4회의 Round trip이 발생합니다. 이것을 UDP를 사용해서 한 번의 Round Trip으로 완료하는 것을 말합니다. HTTP 프로토콜을 생각해 봤을 때, 아주 유용한 기술입니다. 반면 특별한 기술도 아닙니다. 생각해보면 한 번의 Round Trip으로 연결을 성립하는 것은 그리 어렵지 않습니다. 문제는 웹 서비스가 아닌 다른 타입의 서비스에 적용했을 때, IO 측면에서 성능 문제를 가지고 올 수 있다는 점입니다. 사실 이 부분에 관한 설명을 하자면 글이 너무 길어지기 때문에 여기서 줄입니다.
혼잡 방지 알고리즘
TCP가 사용하는 대표적인 혼잡 방지 알고리즘은 Cubin과 Reno 등이 있습니다. 개인적으로 혼잡 방지 알고리즘은 Nash equilibrium을 떠오르게 합니다. TCP의 혼잡 제어 알고리즘은 커널 레벨에서 구동하므로 혼잡 방지 알고리즘을 변경하기 위해서는 커널 레벨의 변경이 필요합니다. 서버는 가능하겠지만 클라이언트 환경은 결코 쉬운 일이 아닙니다. 더욱이 모바일 환경이 보편화 됨에 따라 네트워크 환경에 따라 동작하는 혼잡 방지 알고리즘은 때에 따라 적합하지 않을 수 있으며 리소스 낭비로 이어질 수 있습니다. 하지만 UDP의 경우, 혼잡 제어 알고리즘을 유저 레벨에서 구현 하므로 상황에 따라 혼잡 제어 알고리즘을 변형할 수 있는 큰 장점을 가지게 됩니다.
Forward error correction
FEC는 무선 통신 및 VoIP에서 많이 사용하는 기술입니다. 데이터양이 많지 않고 무선 통신과 같이 데이터의 송수신 비용이 비싼 경우 FEC를 사용해 해당 구간의 재전송을 줄이는 기술입니다. 애플리케이션 특성이 한 번에 송신하는 데이터가 약 400byte 이하일 경우 아주 효율적으로 동작합니다.
Wi-Fi Cellular handover
모바일 환경에서 Wi-Fi 네트워크와 Cellular 네트워크 전환은 빈번하게 발생합니다. 하지만 TCP 는 IP 를 기준으로 연결을 유지하므로 이런 환경 변화에 대응하기에는 다소 부적합 합니다. 하지만 UDP 를 사용하면 IP 변화에 유연하게 대처할 수 있습니다. 적어도 Cellular에서 Wi-Fi 로의 전환은 아주 쉽게 이루어집니다. 하지만 Parking-lot problem이라고 불리는 사용자가 천천히 Wi-Fi 에서 Cellular 로 이동하는 시나리오를 처리하기는 쉽지 않습니다.
암호화
암호화는 네트워크 프로토콜과는 구분되지만, 필수적인 요소로 같이 사용되기 때문에, 일반적으로 네트워크 라이브러리에 포함되어 같이 제공됩니다. 실제로 기능상 독립성 때문에 TCP에서 네트워크 연결과 TLS를 별도로 수행하는 동작은 기능적으로 부족한 것이 아니라 합리적이라고 할 수 있습니다. 하지만 UDP를 사용하면 불필요한 Round trip을 줄일 수 있습니다. 암호화가 적용된 형태도 차이가 있는데, Quic은 암호화를 내장하여 전체 데이터에 대해서 암호화를 수행한다고 알려졌지만, 게임과 같이 데이터 지연에 민감한 애플리케이션의 경우, 꼭 필요한 경우만 암호화를 수행할 수 있도록 제공하는 것이 일반적입니다. 대다수의 암호화 알고리즘은 디피-헬만 키 교환 알고리즘 수행 후, 일회성 대칭 키를 생성해서 암호화를 수행합니다. 아이러니한 것은 암호화 기능을 구현할 때, 어려운 부분은 갑자기 폭주하는 사용자에 대한 성능 처리입니다.
지금까지 살펴본 내용만으로, 구현뿐만 아니라 때에 따라서는 사용하기조차 쉽지 않을 수 있다는 것을 알 수 있습니다. 게다가 UDP는 특정 환경에서는 동작을 안 할 수도 있습니다. 그런데도 모바일 환경과 글로벌 진출을 고려한다면 한번 고민해볼 만합니다. 하지만 UDP를 고려하기 전에 적용할 애플리케이션의 특성에 대한 이해가 선행되어야 하며 적용했을 때 얻을 수 있는 장단점에 대한 고려가 필수적입니다.
UDP 프로토콜 관련해서, 고민하시는 많은 개발자 분들께 도움이 되었으면 좋겠습니다.
고맙습니다.
출처: http://meetup.cloud.toast.com/posts/52
'Back-End > 좋은글' 카테고리의 다른 글
utf8_general_ci와 utf8_unicode_ci 차이 (0) | 2016.01.10 |
---|---|
[펌]Spark Streaming으로 유실 없는 스트림 처리 인프라 구축하기 (0) | 2016.01.10 |
[강추]Best Practices for Designing a Pragmatic RESTful API (0) | 2016.01.10 |
[펌]리눅스 명령어를 이용한 시스템 모니터링 하기 (0) | 2016.01.10 |
Elastic 제품 정리 (0) | 2016.01.10 |