RTB 애플리케이션 권장사항

이 가이드에서는 RTB 프로토콜에 따라 애플리케이션을 개발할 때 고려해야 할 권장사항을 설명합니다.

연결 관리

연결 유지

새 연결을 설정하면 지연 시간이 증가하고 기존 연결을 재사용하는 것보다 양쪽에서 훨씬 더 많은 리소스가 사용됩니다. 연결을 더 적게 닫으면 다시 열어야 하는 연결 수를 줄일 수 있습니다.

첫째, 모든 새 연결을 설정하려면 추가 네트워크 왕복이 필요합니다. 연결은 필요에 따라 설정되므로 연결의 첫 번째 요청은 유효 기한이 더 짧고 후속 요청보다 시간 초과될 가능성이 더 큽니다. 추가 제한 시간은 오류율을 증가시켜 입찰자가 제한될 수 있습니다.

두 번째로, 많은 웹 서버는 설정된 각 연결에 대해 전용 작업자 스레드를 생성합니다. 즉, 연결을 닫고 다시 만들려면 서버가 스레드를 종료하고 삭제한 후 새 스레드를 할당하고 실행 가능하도록 만들고 연결 상태를 빌드한 다음 최종적으로 요청을 처리해야 합니다. 불필요한 오버헤드가 많습니다.

연결 닫기 방지

먼저 연결 동작을 조정합니다. 대부분의 서버 기본값은 각각 소수의 요청을 실행하는 다수의 클라이언트가 있는 환경에 맞게 조정됩니다. 반면 RTB의 경우 상대적으로 소수의 머신 풀이 다수의 브라우저를 대신하여 요청을 전송합니다. 이러한 조건에서는 연결을 최대한 많이 재사용하는 것이 좋습니다. 다음을 설정하는 것이 좋습니다.

  • 유휴 제한 시간을 2.5분으로 설정합니다.
  • 연결의 최대 요청 수를 가능한 가장 높은 값으로 설정합니다.
  • 최대 연결 수를 RAM이 수용할 수 있는 가장 높은 값으로 설정하고 연결 수가 이 값에 너무 근접하지 않도록 합니다.

예를 들어 Apache에서는 KeepAliveTimeout를 150, MaxKeepAliveRequests를 0, MaxClients를 서버 유형에 따라 달라지는 값으로 설정해야 합니다.

연결 동작이 조정되면 입찰자 코드가 연결을 불필요하게 종료하지 않는지 확인해야 합니다. 예를 들어 백엔드 오류 또는 시간 초과 시 기본 '입찰 없음' 응답을 반환하는 프런트엔드 코드가 있는 경우 코드가 연결을 닫지 않고 응답을 반환해야 합니다. 이렇게 하면 입찰자가 과부하되면 연결이 닫히기 시작하고 제한 시간 수가 증가하여 입찰자가 제한되는 상황을 방지할 수 있습니다.

연결 균형 유지

승인된 구매자가 프록시 서버를 통해 입찰자의 서버에 연결하는 경우 시간이 지남에 따라 연결이 불균형해질 수 있습니다. 승인된 구매자는 프록시 서버의 IP 주소만 알 수 있으므로 각 호출을 수신하는 입찰자 서버를 확인할 수 없기 때문입니다. 시간이 지남에 따라 승인된 구매자가 연결을 설정하고 닫고 입찰자의 서버가 다시 시작되면 각 서버에 매핑된 연결 수가 크게 달라질 수 있습니다.

일부 연결이 과도하게 사용되면 그때는 필요하지 않으므로 열려 있는 다른 연결이 대부분 유휴 상태로 유지될 수 있습니다. 승인된 구매자의 트래픽이 변경되면 유휴 연결이 활성 상태가 되고 활성 연결이 유휴 상태가 될 수 있습니다. 연결이 잘못 클러스터링된 경우 입찰자 서버에 불균형한 부하가 발생할 수 있습니다. Google은 요청이 10,000회가 되면 모든 연결을 닫아 이를 방지하고 시간이 지남에 따라 핫 연결의 균형을 자동으로 조정합니다. 여전히 환경에서 트래픽 불균형이 발생하는 경우 취할 수 있는 추가 조치가 있습니다.

  1. 프런트엔드 프록시를 사용하는 경우 연결당 한 번이 아닌 요청당 백엔드를 선택합니다.
  2. 하드웨어 부하 분산기 또는 방화벽을 통해 연결을 프록시하고 연결이 설정되면 매핑이 고정된 경우 연결당 최대 요청 수를 지정합니다. Google은 이미 연결당 요청의 상한선을 10,000개로 지정했으므로 환경에서 여전히 핫 커넥션이 클러스터링되는 경우만 더 엄격한 값을 제공하면 됩니다. 예를 들어 Apache에서 MaxKeepAliveRequests를 5,000으로 설정합니다.
  3. 입찰자의 서버가 요청 비율을 모니터링하고 동료에 비해 지속적으로 너무 많은 요청을 처리하는 경우 자체 연결 중 일부를 닫도록 구성합니다.

과부하를 적절하게 처리

이상적으로는 입찰자가 처리할 수 있는 모든 요청을 받을 수 있을 만큼 충분히 높게 설정해야 하지만 그 이상은 안 됩니다. 실제로 할당량을 최적 수준으로 유지하는 것은 어려운 작업이며 다양한 이유로 오버로드가 발생합니다. 예를 들어 최대 부하 시간에 백엔드가 다운되거나, 트래픽 믹스가 변경되어 각 요청에 더 많은 처리가 필요해지거나, 할당량 값이 너무 높게 설정된 경우 등이 있습니다. 따라서 트래픽이 너무 많아질 경우 입찰자가 어떻게 동작할지 고려하는 것이 좋습니다.

지역 (특히 아시아와 미국 서부, 미국 동부와 미국 서부 간의) 간에 일시적인 트래픽 이동 (최대 1주일)을 수용하려면 7일 최대치와 거래소 위치당 QPS 간에 15% 의 여유를 두는 것이 좋습니다.

부하가 많은 경우 입찰자는 크게 세 가지 카테고리로 나뉩니다.

'모든 것에 응답'하는 입찰자

구현하기는 쉽지만 오버로드되면 실적이 가장 나쁩니다. 들어오는 모든 입찰 요청에 응답하려고 시도하며 즉시 처리할 수 없는 요청은 대기열에 추가합니다. 그 후에는 다음과 같은 시나리오가 발생하는 경우가 많습니다.

  • 요청 수가 증가하면 요청 지연 시간도 증가하여 모든 요청이 타임아웃되기 시작합니다.
  • 콜아웃 비율이 최대치에 가까워질수록 지연 시간이 급격히 증가함
  • 제한이 적용되어 허용되는 콜아웃 수가 급격히 감소합니다.
  • 지연 시간이 회복되기 시작하여 제한이 완화됩니다.
  • 주기가 다시 시작됩니다.

이 입찰자의 지연 시간 그래프는 매우 가파른 톱니 모양 패턴과 유사합니다. 또는 대기열에 추가된 요청으로 인해 서버가 메모리 페이징을 시작하거나 장기적인 속도 저하를 일으키는 다른 작업을 실행하게 되고, 과도한 사용 시간이 끝날 때까지 지연 시간이 전혀 복구되지 않아 전체 과도한 사용 기간 동안 호출 비율이 저하됩니다. 어느 쪽이든 할당량을 더 낮은 값으로 설정했을 때보다 콜아웃이 더 적게 실행되거나 응답됩니다.

'오버로드 오류' 입찰자

이 입찰자는 일정 비율까지 콜아웃을 수락한 후 일부 콜아웃에 오류를 반환하기 시작합니다. 이는 내부 시간 초과, 연결 큐잉 사용 중지 (Apache의 ListenBackLog로 제어됨), 사용률 또는 지연 시간이 너무 길어질 때 확률적 삭제 모드 구현 또는 기타 메커니즘을 통해 수행할 수 있습니다. Google에서 오류율이 15%를 초과하는 것으로 확인되면 제한이 시작됩니다. '모든 요청에 응답'하는 입찰자와 달리 이 입찰자는 '손실을 줄입니다'. 따라서 요청 비율이 감소하면 즉시 회복할 수 있습니다.

이 입찰자의 지연 시간 그래프는 과부하 중에 허용되는 최대 비율을 중심으로 국지화된 얕은 톱니 모양 패턴과 유사합니다.

'과부하 시 입찰 없음' 입찰자

이 입찰자는 최대 비율까지 콜아웃을 수락한 후 오버로드에 대해 '입찰 없음' 응답을 반환하기 시작합니다. '오버로드 오류' 입찰자와 마찬가지로 여러 가지 방법으로 구현할 수 있습니다. 여기서 다른 점은 Google에 신호가 반환되지 않으므로 콜아웃이 다시 제한되지 않는다는 것입니다. 오버로드는 프런트엔드 머신에 의해 흡수되며, 프런트엔드 머신은 처리할 수 있는 트래픽만 백엔드로 계속 전달합니다.

이 입찰자의 지연 시간 그래프는 최대 부하 시간에 요청 비율과 평행을 이루지 않는 (인공적으로) 고원이 표시되고 이에 따라 입찰가가 포함된 응답의 비율이 감소합니다.

다음과 같이 '오버로드 시 오류'와 '오버로드 시 입찰 불가' 접근 방식을 결합하는 것이 좋습니다.

  • 프런트엔드를 오버프로비저닝하고 과부하 시 오류로 설정하여 프런트엔드가 어떤 형태로든 응답할 수 있는 연결 수를 최대화합니다.
  • 오버로드 오류가 발생하면 프런트엔드 머신은 미리 준비된 '입찰 없음' 응답을 사용할 수 있으며 요청을 전혀 파싱할 필요가 없습니다.
  • 사용 가능한 용량이 충분하지 않은 경우 'no-bid' 응답을 반환하도록 백엔드의 상태 점검을 구현합니다.

이렇게 하면 일부 과부하를 흡수하고 백엔드가 처리할 수 있는 만큼 정확하게 요청에 응답할 수 있습니다. 이는 요청 수가 예상보다 훨씬 많은 경우 프런트엔드 머신이 '과부하 시 입찰 불가'로 대체되고 '과부하 시 오류'로 대체되는 '과부하 시 입찰 불가'로 생각할 수 있습니다.

'모든 것에 응답' 입찰자가 있는 경우 연결 동작을 조정하여 과부하를 거부하도록 하여 '과부하 시 오류' 입찰자로 변환하는 것이 좋습니다. 이렇게 하면 더 많은 오류가 반환되지만 제한 시간이 줄어들고 서버가 요청에 응답할 수 없는 상태가 되는 것을 방지할 수 있습니다.

피어링 고려

네트워크 지연 시간 또는 가변성을 줄이는 또 다른 방법은 Google과 피어링하는 것입니다. 피어링을 사용하면 트래픽이 입찰자에게 도달하는 경로를 최적화할 수 있습니다. 연결 엔드포인트는 동일하게 유지되지만 중간 링크는 변경됩니다. 자세한 내용은 피어링 가이드를 참고하세요. 피어링을 권장사항으로 생각하는 이유는 다음과 같이 요약할 수 있습니다.

  • 인터넷에서 전송 링크는 주로 'hot-potato 라우팅'을 통해 선택됩니다. 이 라우팅은 패킷을 대상에 전달할 수 있는 네트워크 외부의 가장 가까운 링크를 찾아 해당 링크를 통해 패킷을 라우팅합니다. 트래픽이 Google과 많은 피어링 연결을 맺은 제공업체가 소유한 백본의 섹션을 통과하는 경우 선택된 링크는 패킷이 시작되는 위치에 가까울 가능성이 높습니다. 이 지점을 지나면 Google에서는 입찰자에게 도달하기 위해 패킷이 따라가는 경로를 제어할 수 없으므로 패킷이 도중에 다른 자율 시스템(네트워크)으로 반송될 수 있습니다.

  • 반면 직접 피어링 계약이 체결된 경우 패킷은 항상 피어링 링크를 통해 전송됩니다. 패킷의 출처와 관계없이 Google에서 소유하거나 임대한 링크를 거쳐 입찰자 위치와 가까운 공유 피어링 지점에 도달합니다. 역방향 경로는 Google 네트워크로의 짧은 호핑으로 시작하여 나머지 경로에서는 Google 네트워크에 머뭅니다. Google 관리 인프라에서 대부분의 경로를 유지하면 패킷이 지연 시간이 짧은 경로를 사용하고 잠재적인 가변성을 많이 방지할 수 있습니다.

정적 DNS 제출

구매자는 항상 Google에 단일 정적 DNS 결과를 제출하고 Google에서 트래픽 전송을 처리하도록 하는 것이 좋습니다.

잔액을 로드하거나 가용성을 관리하려고 할 때 입찰자의 DNS 서버에서 사용하는 두 가지 일반적인 관행은 다음과 같습니다.

  1. DNS 서버는 쿼리에 대한 응답으로 하나의 주소 또는 주소 하위 집합을 제공한 다음 어떤 방식으로든 이 응답을 순환합니다.
  2. DNS 서버는 항상 동일한 주소 집합으로 응답하지만 응답에서 주소 순서를 순환합니다.

첫 번째 기법은 스택의 여러 수준에서 캐싱이 많이 이루어지므로 부하 분산에 적합하지 않습니다. 또한 캐싱을 우회하려고 하면 Google에서 입찰자에게 DNS 확인 시간을 청구하므로 원하는 결과를 얻지 못할 가능성이 높습니다.

두 번째 기법은 Google이 DNS 응답 목록에서 IP 주소를 무작위로 선택하므로 응답의 순서가 중요하지 않아 부하 분산을 전혀 달성하지 못합니다.

입찰자가 DNS를 변경하면 Google은 DNS 레코드에 설정된 TTL(수명)을 준수하지만 새로고침 간격은 여전히 불확실합니다.