Providing Multiple Classes of Service
상위 문서: Multimedia Networking
개요
오늘날 인터넷의 best-effort 서비스에서 가장 간단하게 성능을 향상시킬 수 있는 방식은 트래픽을 클래스 별로 나누고, 이들 각각에 대해 다른 수준의 서비스를 제공하는 것이다. 예를 들어, ISP는 지연에 민감한 VoIP나 화상 회의 트래픽에 더 높은 클래스의 서비스를 제공할 수 있다. 이때 주요한 것은 서비스의 차별화는 "연결" 단위가 아니라 트래픽이 속한 클래스 단위로 적용된다는 것이다.
Multiple classes of service: scenario

Figure 1은 두 개의 패킷 흐름이 하나의 LAN에 속하는 호스트 H1과 H2에서 시작되어, 다른 LAN에 있는 호스트 H3와 H4로 향하는 단순한 네트워크 시나리오를 보여준다. 두 LAN의 라우터는 1.5 Mbps 링크로 연결되어 있다. LAN 속도는 1.5 Mbps보다 훨씬 빠르다고 가정하고, R1 라우터의 출력 큐에 초점을 맞추자. 이때 H1에서 R2로 가는 1.5 Mbps 링크를 1 Mbps VoIP 애플리케이션과 HTTP 웹 페이지를 다운로드하는 애플리케이션이 공유한다고 가정하자.
"best-effort" 인터넷에서는 VoIP와 HTTP 패킷이 R1의 출력 큐에 섞여 들어오고, 일반적으로 FIFO 방식으로 처리된다. 이 경우, 웹 서버의 패킷 버스트로 인해 큐가 가득 차서 VoIP 패킷이 지연되거나 R1에서 오버플로우로 인해 손실될 수 있다. 이 경우 HTTP는 시간에 민감하지 않기 때문에, 직관적으로는 VoIP 패킷에 우선 순위를 주는 것이 좋다. 이에 따라 strict priority 스케쥴링 규칙에서는 R1 출력 큐에 있는 오디오 패킷이 HTTP 패킷보다 항상 먼저 전송된다. 이렇게 되면 R1에서 R2로의 링크는 VoIP 트래픽에 대해 전용 1.5 Mbps 링크처럼 보이고, HTTP는 오디오 트래픽이 없을 때만 이 링크를 사용하게 된다. 이를 위해서 라우터가 큐 안의 VoIP 패킷과 HTTP 패킷을 구분하려면, 각 패킷은 자신이 어떤 클래스에 속하는지 표시되어야 한다. 이로 부터 아래와 같은 원칙이 하나 도출된다.
패킷 마킹은 라우터가 서로 다른 트래픽 클래스에 속하는 패킷들을 구별할 수 있도록 해야 한다.
이제 라우터가 VoIP 클래스에 속한 패킷에 대해 우선 순위를 준다고 가정하자. 이때 출력 링크의 대역폭이 1.5 Mbps이므로, HTTP 패킷은 낮은 우선순위를 가지더라도 평균적으로 0.5 Mbps는 받을 수 있다. 하지만 만약 오디오 응용이 1.5 Mbps 이상의 속도로 패킷을 전송하기 시작하면, HTTP 패킷은 아예 서비스를 받지 못할 수 있다. 따라서 아래와 같은 원칙을 도출할 수 있다.
트래픽 클래스 사이에는 일정 수준의 격리(isolation)가 필요하다.
트래픽 클래스 사이에 격리를 제공하기 위한 일반적인 방식 중 하나는 트래픽 폴리싱(traffic policing) 을 수행하는 것이다. 어떤 트래픽 클래스가 특정 기준(예: VoIP 흐름이 초당 1Mbps를 초과하지 않아야 함)을 충족해야 하는 경우, 이러한 기준이 실제로 지켜지도록 보장하기 위해 폴리싱 메커니즘을 수행할 수 있다. 만약 폴리싱의 대상 애플리케이션이 비정상적으로 동작하면, 해당 폴리싱 메커니즘은 기준을 위반하는 패킷을 드롭하거나 지연시키는 등의 조치를 취하여 실제로 들어오는 트래픽이 기준을 충족하도록 만든다.

트래픽 클래스들 간의 격리를 제공하는 보완적 접근 방식은 링크 수준의 패킷 스케줄링 메커니즘이 각 클래스에 고정된 링크 대역폭을 명시적으로 할당하는 것이다. 예를 들어, VoIP 클래스는 R1에서 1Mbps, HTTP 클래스는 0.5Mbps를 할당받을 수 있다. 이 경우, figure 2와 같이 VoIP와 HTTP 흐름은 각각 1.0Mbps와 0.5Mbps의 용량을 가진 논리적 링크가 구성된 것과 같다. 이때 링크 수준에서의 대역폭 할당이 엄격하게 시행된다면, 하나의 클래스는 오직 자신에게 할당된 만큼의 대역폭만 사용할 수 있고, 다른 클래스가 현재 사용하지 않고 있는 대역폭도 사용할 수 없다. 하지만 대역폭은 "사용하지 않으면 사라지는(use-it-or-lose-it)" 자원이기 때문에, 오디오 트래픽이 사용하지 않는 대역폭을 HTTP 트래픽이 사용하는 것을 막을 이유는 없다. 따라서 아래와 같은 원칙이 또 도출된다.
클래스나 흐름 간의 격리를 제공하면서도, 가능한 한 자원(예: 링크 대역폭과 버퍼)을 효율적으로 사용하는 것이 바람직하다.
이때 다양한 네트워크 트래픽 속한 패킷들이 다중화되고, 링크에 연결된 출력 버퍼에서 전송 대기 상태로 큐에 저장된다. 이 큐에 저장된 패킷들이 링크로 전송되도록 선택되는 방식은 링크 스케줄링 방식(link-scheduling discipline)이라 한다. 그 중에서도 WFQ 방식은 트래픽 클래스들을 격리하는 데 있어 특히 중요한 역할을 한다.
The Leaky Bucket
위 문단에서의 핵심 중 하나는 어떤 클래스의 패킷이 네트워크에 주입되는 속도를 제어하는 것(폴리싱)이 중요한 QoS 메커니즘이라는 것이다. 이때 트래픽의 패킷 전송률(rate)에서 어떠한 요소를 폴리싱해야 할지는 아래와 같은 세 가지 기준이 존재한다:
- Average rate: 네트워크는 한 흐름의 패킷이 네트워크에 투입될 수 있는 장기적인 평균 속도(단위 시간당 패킷 수)를 제한하고 싶어할 수 있다.
- 이때 평균 속도를 측정하는 시간 간격은 상당히 중요하다.[1]
- Peak rate: 이는 짧은 시간 내에 보낼 수 있는 최대 패킷 수를 제한한다. 예를 들어, 평균 속도가 분당 6,000패킷이더라도, 최고 속도가 초당 1,500패킷으로 제한된다면 순간적으로 패킷을 너무 많이 보내는 것은 허용되지 않는다.
- Burst size: 네트워크는 매우 짧은 시간 동안 네트워크에 보낼 수 있는 최대 패킷 수("버스트")도 제한해야 할 수 있다.
- 극한의 경우, 시간 간격이 0에 가까워질 때, 버스트 크기는 한 번에 보낼 수 있는 패킷 수를 제한한다.

리키 버킷(Leaky bucket) 메커니즘은 이러한 폴리싱을 모델링하는데에 사용되는 추상적인 개념이다. Figure 3와 같이, 리키 버킷은 최대 b개의 토큰(token) 을 담을 수 있는 버킷으로 구성된다. 토큰은 다음 방식으로 추가된다. 새 토큰은 항상 초당 r개의 토큰 이 생성되며 버킷에 추가될 수 있다. 버킷에 현재 b개보다 적은 토큰이 있다면 새로 생성된 토큰이 추가되며, 그렇지 않으면 버려지고 버킷은 b개의 토큰으로 유지된다.
이때 네트워크로 패킷이 전송되기 전에, 반드시 토큰 버킷에서 토큰 하나를 제거해야 한다고 가정하자. 만약 토큰이 없으면, 해당 패킷은 토큰이 생길 때까지 대기해야 한다. 이러한 메커니즘은 트래픽을 폴리싱한다. 버킷에는 최대 b개의 토큰 만 들어갈 수 있으므로, 리키 버킷으로 폴리싱된 흐름의 최대 burst size는 b이다. 또한, 토큰 생성률이 r이라면, 길이가 t인 시간 간격 내에 네트워크에 들어갈 수 있는 최대 패킷 수는 rt + b이다. 따라서 r은 패킷이 네트워크에 들어가는 average rate를 의미한다. 이를 수식으로 정리하면 다음과 같다:
Average rate = r Burst size = b number of packets over interval of length t = rt + b

리키 버킷과 WFQ를 결합하면 라우터 큐에서의 지연에 상한(bound)을 설정할 수 있다. n개의 트래픽이 있고, 각각이 리키 버킷으로 폴리싱되며, 매개변수는 각각 bi 와 ri (i = 1,...,n) 라고 하자. 이 트래픽들은 WFQ 스케쥴링으로 다중화된다. 이는 figure 4에 나타나 있다. WFQ 스케쥴링에서는, 트래픽 i는 링크의 대역폭이 R일 때, 만큼의 대역폭을 보장받는다. 이때 트래픽 1의 b1개의 패킷들이 리키 버킷을 통과한 뒤, WFQ에서 겪는 최대 queueing delay인 d_max은 아래와 같이 계산된다:
각주
- ↑ 예를 들어, 평균 속도가 초당 100패킷으로 제한된 흐름은 분당 6,000패킷으로 제한된 흐름보다 더 제약이 크다. 같은 평균 속도라 해도 시간 간격이 길면 순간적으로 훨씬 많은 패킷을 보낼 수 있기 때문이다.