minzzl

QUIC 톺아보기 (1) 본문

논문/QUIC

QUIC 톺아보기 (1)

minzzl 2023. 7. 10. 15:28
728x90
반응형

개요

 

졸업 논물을 위해 사전 논문들을 분석하던 중, 인터넷 서비스 향상을 위한 Google의 연구 개발 분석 이라는 논문을 가장 처음으로 읽게 되었습니다.

 

 

해당 논문을 읽고 저의 향후 논문에 도움을 줄 수 있을 것 같아 좋았던 단락이나,

떠오르는 자유로운 생각들을 기반으로, 질문에 답하는 형식으로 정리해보겠습니다.

 

 

본론

 

향후 논문에 도움이 될 만한 단락

 

" IETF(Internet Engineering Task Force)의 발표에 따르면 인터넷 트 래픽의 약 90% 이상이 TCP를 이용하여 전송되고 있다[2]. 하지만, 네트워크의 속도가 지속적으로 고속화 되는 반면에 기존의 TCP 혼잡 윈도우 크기 조절을 통한 패킷 전송방식은 네트워크 자원을 충분하게 활용 하지 못하는 것으로 밝혀지게 되었다 " 

 

" 이후, Google은 인터넷 서비스 향상을 위해서 웹페이지 반응속도 개선을 전송계층에 서 처리하는 연구개발을 시작 " 

 

" 이러한 매우 높은 시장점유율의 원인에는 여러가지가 있겠지만, Google의 인터넷 서비스 향상을 위한 다양한 연구개발이 중요한 역할을했을 것으로 판단된다. "

 

" SPDY의 궁극적인 목표는 HTTP/1.1의 성능 제한을 해결하여 웹페이지의 로딩 시간을 50%로 줄이는 것 이다. 이를 실현하기 위한 SPDY의 핵심 기술은 새 바이너리 프레이밍 계층을 도입하여 하나의 커넥션으로 동시에 여러개의 메시지를 주고 받을 수 있는 요청/응답의 다중화를 지원한다

또한, 특정 자원의 수신이 늦어질 경우, 의존성 있는 자원도 렌더링이 늦어지는 문제가 발생할 수 있는데 이러한 문제를 해결하기 위 해 자원간 의존관계를 설정하는 우선순위 지정을 지 원하며, HTTP 특성상 헤더가 중복적으로 전송하는 경우가 많은데 여러 요청에 대해 중복값이 존재하는 경우 성능향상을 위한 헤더 압축을 지원함으로써 기 본TCP 연결을보다더효율적으로사용할수있도록 했다."

 

"파일을 읽고 쓰는 것보다 파일을 열고 닫는 것이 자원이 많이 드는 것처럼 네트워크 소켓을 열고 닫는 부분에 대해서도 비슷한 현상이 있다"

 

"TCP 연결 을 여는 것은 자원을 소비하기 때문에 근본적으로 성 능상의 제약을 발생시킨다. Google2011년 분석 결 과, 비록 그 당시에도 TCP 연결 횟수를 줄이고자 HTTP/1.1의 경우 영속적인 연결(Persistent Connection)을 위한 Keep-Alive 기법을 사용하고 있 었지만, 크롬에서 발생한 HTTP 연결의 33%정도가 여전히 새로운 TCP 연결을 요청하는, 즉 단기적 연결 을사용하고있는것으로나타났다. 또한 그 당시웹 브라우저는 서버당 연결 개수를 높여 빠르게 웹페이 지를 로딩하려고 하고 있었는데 이는 TCP 연결 재사 용을 제한하였다.

"

 

 

 "

기존 TCP에서 전통적으 로 사용해 왔던 혼잡제어 알고리즘은 인터넷 사용자 가 갑자기 증가하거나 대규모 다운로드 및 업로드 등 네트워크 트래픽이 갑자기 발생하는 경우 패킷손실이 발생하면 자동적으로 네트워크 전송속도를 절반으로 줄여 혼잡제어를 수행하고 이를 통해 패킷손실을 방 지하게 된다.

반면, BBR 알고리즘은 여러 라우터에 걸쳐 쓰루풋과 트래픽 처리시간을 지 속적으로 체크한다. , 손실될 패킷의 현재 위치와 이동 경로를 미리 예측하여 네트워크에 트래픽이 갑 자기 증가하더라도 전송 속도가 느려지는 것을 방지 할 수 있다. 이를 기반으로 패킷이 네트워크를 통해 전송되는데 걸리는 시간을 계산하고 네트워크가 감당할수있는 트래픽 전송 속도를 조절한다.

.

 

논문을 읽으면 들었던 궁금한점 그리고 답변

 

 

 

1.

 

SPDY에 바이너리 프레이밍 계층을 도입했다고 되어있는데, 이게 왜 필요하고 어떤 역할을 하는가?

 

HTTP/2의 모든 성능 향상의 핵심은 새로운 바이너리 프레이밍 계층으로, HTTP 메시지가 캡슐화되어 클라이언트와 서버 간에 전송된다.

 

 

 

바이너리프레이밍계층 (출처: https://web.dev/performance-http2/)

이 때 "계층"은 소켓 인터페이스와 애플리케이션에 노출되는 상위 HTTP API 사이에 최적화된 새로운 인코딩 메커니즘을 도입하기 위한 설계 선택을 의미한다. 동사, 메서드, 헤더와 같은 HTTP 의미론은 영향을 받지 않지만 전송 중에 인코딩되는 방식이 달라졌다. 줄 바꿈으로 구분된 일반 텍스트 HTTP/1.x 프로토콜과 달리 모든 HTTP/2 통신은 더 작은 메시지와 프레임으로 나뉘며, 각 프레임은 바이너리 형식으로 인코딩된다.

따라서 클라이언트와 서버는 서로를 이해하기 위해 새로운 바이너리 인코딩 메커니즘을 사용해야 한다. HTTP/1.x 클라이언트는 HTTP/2 전용 서버를 이해할 수 없으며, 그 반대의 경우도 마찬가지이다. 다행히도 클라이언트와 서버가 우리를 대신해 필요한 모든 프레이밍 작업을 수행하기 때문에 애플리케이션은 이러한 모든 변경 사항을 인식하지 못한다.

 

새로운 바이너리 프레이밍 메커니즘의 도입으로 클라이언트와 서버 간에 데이터가 교환되는 방식이 변경되었다. 이 과정을 설명하기 위해 HTTP/2 용어에 대해 알아봅시다:

 

Stream : 하나 이상의 메시지를 전달할 수 있는 설정된 연결 내에서 바이트의 양방향 흐름.
Message : 논리적 요청 또는 응답 메시지에 매핑되는 프레임의 전체 시퀀스.
Frame :  HTTP/2에서 가장 작은 통신 단위로, 프레임 헤더를 포함하며 최소한 프레임이 속한 스트림을 식별합니다.

 

이 용어들의 관계는 다음과 같이 요약할 수 있다:

모든 통신은 양방향 스트림을 얼마든지 전달할 수 있는 단일 TCP 연결을 통해 수행된다.
각 스트림에는 양방향 메시지를 전달하는 데 사용되는 고유 식별자와 선택적 우선순위 정보가 있다.
각 메시지는 하나 이상의 프레임으로 구성된 요청 또는 응답과 같은 논리적 HTTP 메시지.
프레임은 특정 유형의 데이터(예: HTTP 헤더, 메시지 페이로드 등)를 전달하는 가장 작은 통신 단위.

서로 다른 스트림의 프레임은 인터리빙된 후 각 프레임의 헤더에 내장된 스트림 식별자를 통해 재조합될 수 있다.

 

 

간단히 말해, HTTP/2는 HTTP 프로토콜 통신을 바이너리 인코딩된 프레임의 교환으로 분해한 다음 특정 스트림에 속한 메시지에 매핑하고, 이 모든 것이 단일 TCP 연결 내에서 다중화된다. 이는 HTTP/2 프로토콜이 제공하는 다른 모든 기능과 성능 최적화를 가능하게 하는 기반이다.

 

HTTP/1.x에서 클라이언트가 성능 향상을 위해 여러 개의 병렬 요청을 하려면 여러 개의 TCP 연결을 사용해야 한다.  이러한 동작은 연결당 한 번에 하나의 응답(응답 대기열)만 전달할 수 있도록 하는 HTTP/1.x 전달 모델의 직접적인 결과이다. 더 나쁜 것은 이로 인해 헤드오브라인 차단이 발생하고 기본 TCP 연결이 비효율적으로 사용된다는 점이다.

HTTP/2의 새로운 바이너리 프레이밍 계층은 이러한 제한을 없애고 클라이언트와 서버가 HTTP 메시지를 독립적인 프레임으로 분할하여 인터리빙한 다음 다른 쪽 끝에서 재조합할 수 있도록 함으로써 완전한 요청 및 응답 멀티플렉싱을 가능하게 한다.

기존의 HOL 문제는 패킷이 순서대로 처리되어야하기 때문에, 앞선 패킷의 지연이 일어나면 뒤의 패킷도 함께 지연이 일어나서 발생하는 문제이다. HTTP/2에서는 순서가 뒤바뀌어나 심지어 인터리빙될 수도 있기 때문에 이러한 HOLB가 없다.

 

 

위의 그림은 동일한 연결 내에서 전송 중인 여러 스트림을 캡처한 것이다. 클라이언트는 데이터 프레임(스트림 5)을 서버로 전송하고, 서버는 스트림 1과 3에 대해 인터리브된 프레임 시퀀스를 클라이언트로 전송한다. 결과적으로 3개의 병렬 스트림이 전송 중이다.

HTTP 메시지를 독립적인 프레임으로 분해하고 인터리빙한 다음 다른 쪽 끝에서 재조립하는 기능은 HTTP/2의 가장 중요한 개선 사항이다. 실제로 이 기능은 모든 웹 기술의 전체 스택에 걸쳐 수많은 성능상의 이점을 가져다주는 파급 효과를 가져온다.

HTTP/2의 새로운 바이너리 프레이밍 계층은 HTTP/1.x에서 발견된 헤드 오브 라인 차단 문제를 해결하고 요청과 응답의 병렬 처리 및 전달을 위해 다중 연결의 필요성을 없애줍니다. 그 결과 애플리케이션을 더 빠르고, 더 간단하고, 더 저렴하게 배포할 수 있다.

 

 

2.

"

HTTP/1.1는 기본 적으로 하나의 연결(Connection)당 하나의 요청을 처리하도록설계되어있었다.이때문에동시전송이 불가능하고 요청과 응답이 순차적으로 이루어지다 보 니웹문서안에포함되어있는이미지,CSS,스크립 트등여러가지다양한자원를처리하려면요청할리 소스 개수에 비례해서 대기 시간(Latency)이 길어지게 되었다. HTTP1.1에서 하나의 연결당 하나의 요청을 처리하는문제를개선할수있는기법중파이프라이 닝(Pipelining)이 존재하는데 이것은 하나의 연결을 통 해서 다수개의 파일을 요청/응답 받을 수 있는 기법을 의미한다. 이 기법을 통해서 어느 정도의 성능 향상을 얻을 수 있었으나 큰 문제점이 발생하였는데 바로 HOL 차단(Head-of-line block)이며 속도 문제를 일으 키는 주요 원인이었다. HTTP/1.1의 HOL 차단 문제 는 HTTP/2가 TCP 상에서 멀티플렉싱을 허용함으로 써 문제를 해결했으며, 많은 HTTP 요청과 응답은 응 용 프로그램 프로토콜을 차단하지 않고 동시에 처리 될수있다.

"

 

-> 논문에 HTTP/2가 멀티플렉싱 문제를 허용함으로써 HOL 차단 문제를 해결하였다고 명시되어있다. 그러나 내가 알기로는 HTT/2에서 개선하지 못했고, 이후 QUIC에서 멀티플렉싱을 통해 HOL 차단 문제를 해결했다고 알고있음.

 

그렇다면 뭐가 맞을까?

 

HTTP/2는 여전히 TCP 수준에서 또 다른 종류의 HOL을 겪고 있다. TCP 스트림에서 하나의 패킷이 손실되면 모든 스트림이 해당 패킷이 다시 송수신될 때까지 대기하게 된다. 따라서 HTTP/2가 HOL 문제를 해결한 것은 맞지만 TCP를 기반으로 작동하기 때문에 HOLB 문제에서 완전히 벗아났다고 할 수 없다. 

 

2. 

 

"파일을 읽고 쓰는 것보다 파일을 열고 닫는 것이 자원이 많이 드는 것처럼 네트워크 소켓을 열고 닫는 부분에 대해서도 비슷한 현상이 있다"

 

-> 논문에서 다음과 같이 언급했는데, 그렇다면 파일을 열고 닫는 것이 왜 자원이 많이 들까?

 

TCP에서의 3-Way Handshake 과정이 있기 때문이다.

전통적인 TCP에서는 3-way handshake (SYN, SYN-ACK, ACK) 과정이 완료되어야 송신자(클라이언트)와 수신자(서버)가 모두 실제 데이터 교환을 시작할 수 있다. 이러한 과정 때문에 대기 시간이 늘어나며 전반적인 웹페이지 로드 속도가 감소한다.

또한 TCP의 3-way handshake 방식은 연결할 때마다 이루어지기 때문에 송수신자 모두에게 부하를 준다. 따라서 TFO가 등장했다.

 

 

3.

 

3-way handshake는 왜 필요할까?

 

클라이언트와 서버간의 신뢰할 수 있는 통신을 제공하도록 한다.

 

인터넷 초창기에는 인터넷프로토콜, 즉 IP 만이 인터넷 연결에 사용하는 유일한 프로토콜이었다. 그러나 IP는 메시지를 보내도 수신자가 메시지를 받은지의 여부를 확인할 수 없다는 것이었다. 

이를 위해 TCP/IP가 확린되었고, 이는 보내는 모든 데이터가 수신자에게 도달하도록 보장한다. 데이터를 전송하기 전에 클라이언트와 서버에 3-way handshake라는 보안 연결을 제공함으로써 이 작업을 수행한다. 

 

이러한 초기 상호작용은 안전한 연결을 만드는데 필수적이다. 이 단계에서 클라이언트와 서버는 수신 및 발신 데이터 패킷을 확인한다. 이러한 매개변수는 TCP 세그먼트 형태가된다.

 

 

사실 TCP/IP 연결에서 전송되는 모든 데이터는 TCP 세그먼트라고 하는 구간에서 잘라내어 구조화해야한다. 이러한 세그먼트에는 IP 주소, 포트, 플래그 비트, 시퀀스 번호, 승인번호, 선택적 데이터 또는 페이로드와 같은 정보가 포함된다.

 

처음 세번의 핸드셰그에서는 페이로드나 펌부 데이터가 없는 TCP 세그먼트 헤더만 포함이 된다.

 

TCP 세그먼트

위의 그림은 TCP에만 해당이된다. 전체 TCP/IP 세그먼트는 위의 TCP 세그먼트 위에 발신자와 수신자의 IP 주소가 모두 필요하다.

클라이언트가 서버와 통신할 때마다 양 당사자는 상호작용을 TCP 세그먼트 형식으로 형식화 해야한다. TCP 세그먼트는 전송하려는 데이터에 첨부된 TCP 세그먼트 헤드로 구성된다. 발신자는 세그먼트 헤드에 필요한 정보를 입력해야한다.

 

  • Source port : 발신자의 포트를 식별한다.
  • Destination port : 수신자의 포트를 식별한다.
  • Sequence number : 세그먼트 시퀀스를 나타냄
  • Acknowledgement Number : 주어진 시퀀스 번호에 1을 더하여 세그먼트가 승인되었음을 나타냄.
  • Flag bit : 총 6개가 있으며 핸드쉐이크에서는  다음 중 2개만 필요함.
    • SYN: 시퀀스 번호를 제공한다. 이 시퀀스 번호는 나머지 상호작용에서 수신되는 모든 세그먼트 시퀀스를 계산하는데 사용됨
    • ACK : SYN 번호의 수신자가 주어진 SYN 번호에 1을 더하여 연결 요청을 수락했음을 나타냄

이제 3 way handshake 과정을 알아보자.

이는 클라이언트와 호스트가 서로의 정보를 교환하고 시퀀스 번호를 확인하면 성립된다.

이름에서 알 수 있듯이 세단계로 이루어짐

 

먼저 클라이언트는 연결을 원하다는 순수 SYN 세그먼트를 보낸다.

 

그 다음으로 서버는 요청을 승인하고 클라이언트가 승인할 수 있도록 자체 SYN 번호를 전송한다는 의미의 SYN-ACK세그먼트로 응답한다.

 

마지막으로 클라이언트는 서버의 SYN 번호가 승인되었으며 향후 연결에 사용될 것임을 알리기 위해 서버에 ACK 세그먼트를 보낸다.

 

 

 

핸드셰이크 이후 클라이언트와 서버는 데이터 전송을 시작한다.

이렇듯 시퀀스 번호가 있는 이유는 세그먼트가 나중에 재조립될 때 순서를 알기위해서이다. 승인 번호는 발신자에게 세그먼트가 수신되었는지, 수신 세그먼트의 시퀀스와 일치하는지 확인하기 위한 것이다.

 

이렇듯 시퀀스 번호를 세그 확인하는 과정을 통해서 TCP가 누락된 데이터 없이 데이터를 안정적으로 전송할 수 있다.

 

4. 

그렇다면 왜 굳이 3-way handshake일까 ? 2번의 왕복으로는 부족할까?

 

이를 위해서 핸드 셰이크가 어떤 동작을 하는지 세분화해볼 필요가 있다.

 

TCP에서 두 당사자는 시퀀스 번호를 사용하여 전송한 내용을 추적한다. 사실상 시퀀스 번호는 전송된 모든 데이터의 실행 바이트 수가된다. 수신 당사자는 상대방의 시퀀스 번호를 사용하여 수신한 내용을 확인할 수 있다.

 

하지만 시퀀스 번호는 0에서 시작하는 것이 아니라 무작위로 선택된 값에서 시작된다. 그리고 TCP는 양방향 통신이기 때문에 양쪽 모두 말을 할 수 있다. 따라서 양쪽 모두 시퀀스 번호를 무작위로 생성해야한다. 즉 양쪽 모두 상대방에게 시작 무작위 번호를 알려야하기 때문에 3번의 handshake과정이 필요하다.

 

4. 

 

TFO란 무엇일까? 

TFO은 3-way handshake 방식으로 발생하는 전송왕복시간(RTT) 및 지연의 한계를 극복하려는 노력으로 TCP SYN과정 중에 데이터를 담아서 전달함으로써 보다 빠르게 웹 컨텐츠를 전송하기 위한 기술이다. 다음과 같이 송신자가 SYN 패킷을 수신자에게 전송할 뿐만 아니라 쿠키 요청을 전송하기 때문에 정상적인 TCP 3-way handshake 가 발생하면서 작동한다. 송신자와 수신자 사이의 TFO 과정의 첫단계에서 송신자가 쿠키 요청과 함께 SYN 패킷을 보낸다. 그러면, 수신자는 요청된 쿠키를 생성한 후 쿠키와 함께 SYN-ACK를 송신자 에게 보낸다. 송신자가 특정 수신자의 IP에 대한 쿠키 를캐시한다. 송신자가수신자에의해생성된쿠키 를캐시했으므로그이후송수신자의TFO과정은다 음과같다.송신자가SYN,TFO쿠키및데이터가포 함 된 패킷을 보낸다. 그러면, 수신자는 TFO 쿠키의 유효성을 검사하고 응용 프로그램에서 데이터를 사용 할 수 있다. 수신자는 SYN-ACK을 되돌려 보내고 송 신자로더많은데이터패킷을계속전송한다. 그다 음 송신자가 수신자에게 ACK를 다시 보낸다. 이와 같은 과정이 완료되면 TCP가 정상적으로 계속되며 이를통해송신자가즉시데이터를전송할수있고통 신을더일찍시작할수있다.기존TCP의혼잡제어 (Congestion Control)는 따로 수정할 필요가 없으며 기존의 sendto, sendmsg와 같은 시스템 호출을 활용 하여 쉽게 쓸 수 있게 했다.

TCP fast open 과정

3. 

 

TFO 를 하는 특정 경우가 정해져 있는가?

 

이미 서로와 TCP 연결을 한적 있는 호스트와 클라이언트 사이는 다시 연결하고자 할 때 사용한다.

 

TFO는 TCP의 3 way handshake로 발생하는 RTT 및 Latency의 한계를 극복하려는 노력이다.

Handshake 할 때부터 컨텐츠를 담아 전달한다.

 

새로운 TCP 연결에 대한 요청은 Cold Request, 이미 연결된 TCP 연결에대한 요청을 Warm request 라고 정의한다.

새로운 연결(Cold Request) 하는데 Cost가 8~28% 더 든다.

 

TFO는 클라이언트와 서버 간에 한 번의 전체 RTT를 피하기 위한 전송 계층 솔루션이다. 반복 연결 시 TCP-3 방식의 핸드셰이크를 피할 수 있다.

일반적인 TCP 연결에서는 연결 설정에 한 번의 RTT가 낭비되고 세 번째 패킷부터 실제 통신이 시작된다. TFO에 따르면 클라이언트는 첫 번째 패킷 자체에서 1 RTT를 낭비하지 않고 GET 요청을 보낼 수 있다. 하지만 그렇게 하기 위한 몇 가지 조건이 있다:

 

(1) 새로운 연결이 아니어야함

 

TFO는 암호화 쿠키가 필요하기 때문에 반복 연결에서만 작동한다.

클라이언트가 서버와 처음으로 상호 작용할 때 3방향 핸드셰이크를 수행하며, 이 핸드셰이크에서 서버는 암호화 쿠키를 클라이언트와 공유한다.

이후에는 클라이언트가 SYN 패킷 자체의 GET 요청과 쿠키를 피기백합니다. 그런 다음 서버는 쿠키를 사용하여 클라이언트를 인증하고 연결 요청을 수락한 후 ACK 패킷에 데이터를 전송합니다

 

(2) SYN 패킷으로 피기백 된 데이터 총량은 1460바이트를 패킷에 피기백할 수 있음. 따라서 한 세그먼트의 크기는 1460B가 된다.

 

(3) 특정 유형의 HTTP 요청만 TFO를 사용하여 전송할 수 있음

 

GET 요청만 지원된다. TFO는 서버에 쓰기 작업을 허용하면 해커가 서버에 심각한 피해를 줄 수 있는 악의적인 활동을 수행할 수 있기 때문에 POST 요청을 지원하지 않는다.

 

 

 

 

* 다음의 글을 참고하여 작성했습니다.

https://web.dev/performance-http2/

https://www.makeuseof.com/what-is-three-way-handshake-how-does-it-work/

https://knight76.tistory.com/entry/%EA%B5%AC%EA%B8%80-TCP-Fast-Open-paper-TFO%EB%A5%BC-%EC%9D%BD%EA%B3%A0

728x90
반응형