Best Practices für RTB-Anwendungen

In diesem Leitfaden werden Best Practices erläutert, die Sie bei der Entwicklung von Anwendungen gemäß dem RTB-Protokoll berücksichtigen sollten.

Verbindungen verwalten

In Kontakt bleiben

Das Herstellen einer neuen Verbindung erhöht die Latenz und beansprucht an beiden Enden weitaus mehr Ressourcen als die Wiederverwendung einer vorhandenen Verbindung. Wenn Sie weniger Verbindungen schließen, können Sie die Anzahl der Verbindungen reduzieren, die wieder geöffnet werden müssen.

Erstens erfordert jede neue Verbindung einen zusätzlichen Netzwerk-Roundtrip. Da wir Verbindungen auf Anfrage herstellen, hat die erste Anfrage an eine Verbindung eine kürzere effektive Frist und es ist wahrscheinlicher, dass eine Zeitüberschreitung auftritt als bei nachfolgenden Anfragen. Zusätzliche Zeitüberschreitungen erhöhen die Fehlerrate, was dazu führen kann, dass Ihr Bidder gedrosselt wird.

Zweitens: Viele Webserver erstellen für jede hergestellte Verbindung einen speziellen Worker-Thread. Das bedeutet, dass der Server einen Thread herunterfahren und verwerfen, einen neuen Thread zuweisen, ihn ausführbar machen und den Verbindungsstatus erstellen muss, bevor er die Anfrage schließlich verarbeiten kann. Das ist ein unnötiger Mehraufwand.

Verbindungen nicht schließen

Passen Sie zuerst das Verbindungsverhalten an. Die meisten Serverstandardeinstellungen sind auf Umgebungen mit einer großen Anzahl von Clients zugeschnitten, die jeweils nur eine kleine Anzahl von Anfragen stellen. Bei RTB sendet dagegen ein kleiner Pool von Maschinen Anfragen im Namen einer relativ großen Anzahl von Browsern. Unter diesen Bedingungen ist es sinnvoll, Verbindungen so oft wie möglich wiederzuverwenden. Wir empfehlen Folgendes festzulegen:

  • Zeitlimit für die Inaktivität auf 2,5 Minuten.
  • Maximale Anzahl von Anfragen für eine Verbindung auf den höchsten möglichen Wert.
  • Legen Sie die maximale Anzahl von Verbindungen auf den höchsten Wert fest, der von Ihrem RAM unterstützt wird. Achten Sie dabei darauf, dass die Anzahl der Verbindungen diesen Wert nicht zu sehr annähert.

In Apache würde das beispielsweise bedeuten, dass KeepAliveTimeout auf 150, MaxKeepAliveRequests auf null und MaxClients auf einen Wert festgelegt werden muss, der vom Servertyp abhängt.

Nachdem Sie das Verbindungsverhalten optimiert haben, sollten Sie auch dafür sorgen, dass Ihr Bidder-Code Verbindungen nicht unnötig schließt. Wenn Sie beispielsweise Front-End-Code haben, der bei Backend-Fehlern oder Zeitüberschreitungen die Standardantwort „Kein Gebot“ zurückgibt, achten Sie darauf, dass der Code die Antwort zurückgibt, ohne die Verbindung zu schließen. So vermeiden Sie, dass Ihr Bidder überlastet wird, Verbindungen geschlossen werden und die Anzahl der Zeitüberschreitungen zunimmt, wodurch Ihr Bidder gedrosselt wird.

Verbindungen ausgewogen halten

Wenn Authorized Buyers über einen Proxyserver eine Verbindung zu den Servern Ihres Bieters herstellt, kann es im Laufe der Zeit zu einer Unwucht bei den Verbindungen kommen, da Authorized Buyers nur die IP-Adresse des Proxyservers kennt und nicht feststellen kann, welcher Bieterserver die einzelnen Aufrufe empfängt. Im Laufe der Zeit, wenn Authorized Buyers Verbindungen herstellt und schließt und die Server des Bieters neu gestartet werden, kann die Anzahl der Verbindungen, die jeweils zugeordnet sind, sehr unterschiedlich sein.

Wenn einige Verbindungen stark ausgelastet sind, bleiben andere geöffnete Verbindungen möglicherweise größtenteils inaktiv, da sie derzeit nicht benötigt werden. Wenn sich der Traffic von Authorized Buyers ändert, können inaktive Verbindungen aktiv werden und aktive Verbindungen inaktiv. Dies kann zu einer ungleichmäßigen Auslastung Ihrer Bieterserver führen, wenn die Verbindungen schlecht gruppiert sind. Google versucht, dies zu verhindern, indem alle Verbindungen nach 10.000 Anfragen geschlossen werden, um überlastete Verbindungen im Laufe der Zeit automatisch neu auszubalancieren. Wenn die Zugriffe in Ihrer Umgebung immer noch ungleichmäßig verteilt sind, können Sie weitere Maßnahmen ergreifen:

  1. Wählen Sie das Backend pro Anfrage und nicht einmal pro Verbindung aus, wenn Sie Frontend-Proxys verwenden.
  2. Geben Sie eine maximale Anzahl von Anfragen pro Verbindung an, wenn Sie Verbindungen über einen Hardware-Load Balancer oder eine Firewall proxyn und die Zuordnung nach dem Herstellen der Verbindungen festgelegt ist. Google gibt bereits ein Oberlimit von 10.000 Anfragen pro Verbindung an. Sie sollten also nur einen strengeren Wert angeben, wenn in Ihrer Umgebung weiterhin Verbindungen mit hoher Auslastung auftreten. Legen Sie in Apache beispielsweise MaxKeepAliveRequests auf 5.000 fest.
  3. Konfigurieren Sie die Server des Bieters so, dass sie ihre Anfrageraten überwachen und einige eigene Verbindungen schließen, wenn sie im Vergleich zu anderen Bietern regelmäßig zu viele Anfragen verarbeiten.

Überlastungen reibungslos bewältigen

Idealerweise sollten die Kontingente so hoch sein, dass Ihr Bidder alle Anfragen erhält, die er verarbeiten kann, aber nicht mehr. In der Praxis ist es schwierig, die Kontingente auf einem optimalen Niveau zu halten. Überlastungen können aus verschiedenen Gründen auftreten: Ein Backend fällt während Spitzenzeiten aus, der Traffic-Mix ändert sich, sodass für jede Anfrage mehr Verarbeitung erforderlich ist, oder der Kontingentwert ist einfach zu hoch. Daher sollten Sie überlegen, wie sich Ihr Bidder bei zu viel Traffic verhalten soll.

Um vorübergehende Verkehrsverlagerungen (bis zu einer Woche) zwischen Regionen zu berücksichtigen (insbesondere zwischen Asien und West-USA sowie zwischen Ost-USA und West-USA), empfehlen wir einen Puffer von 15% zwischen dem 7-Tage-Höchstwert und der QPS pro Handelsstandort.

Bidder lassen sich in Bezug auf ihr Verhalten bei hoher Auslastung in drei allgemeine Kategorien unterteilen:

Der Bieter, der auf alles antwortet

Dieser Bieter ist zwar einfach zu implementieren, schneidet aber bei Überlastung am schlechtesten ab. Es wird einfach versucht, auf jede eingehende Gebotsanfrage zu reagieren, unabhängig davon, was passiert. Alle Anfragen, die nicht sofort ausgeführt werden können, werden in die Warteschlange gestellt. Das Szenario sieht oft so aus:

  • Mit steigender Anfragerate steigen auch die Anfragelatenzen, bis bei allen Anfragen eine Zeitüberschreitung auftritt.
  • Latenzen steigen sprunghaft an, wenn die Anzahl der Zusatzinformationen den Höchstwert erreicht
  • Die Drosselung wird aktiviert und die Anzahl der zulässigen Zusatzinformationen wird stark reduziert.
  • Die Latenz beginnt sich zu erholen, wodurch die Drosselung reduziert wird.
  • Der Zyklus beginnt von vorn.

Das Diagramm der Latenz für diesen Bieter ähnelt einem sehr steilen Sägezahnmuster. Alternativ können anstehende Anfragen dazu führen, dass der Server mit dem Auslagern von Arbeitsspeicher beginnt oder etwas anderes tut, was zu einer langfristigen Verlangsamung führt. Die Latenzen normalisieren sich erst wieder, wenn die Spitzenzeiten vorbei sind, was zu niedrigen Auslöseraten während der gesamten Spitzenzeit führt. In beiden Fällen werden weniger Zusatzinformationen gesendet oder darauf geantwortet, als wenn das Kontingent einfach auf einen niedrigeren Wert gesetzt worden wäre.

Der Bieter „error on overload“

Dieser Bieter akzeptiert Zusatzinformationen bis zu einer bestimmten Rate und gibt dann für einige Zusatzinformationen Fehler zurück. Dies kann durch interne Zeitüberschreitungen, das Deaktivieren der Verbindungswarteschlange (von ListenBackLog in Apache gesteuert), die Implementierung eines probabilistischen Aussetzmodus, wenn die Auslastung oder Latenz zu hoch wird, oder einen anderen Mechanismus erfolgen. Wenn Google eine Fehlerrate von über 15 % feststellt, wird die Bandbreite gedrosselt. Im Gegensatz zum Bieter, der auf alles antwortet, „begrenzt dieser Bieter seine Verluste“, sodass er sich sofort erholen kann, wenn die Anfrageraten sinken.

Das Diagramm der Latenz für diesen Bieter ähnelt bei Überlastungen einem flachen Sägezahnmuster, das sich um die maximal zulässige Rate herum befindet.

Der Bieter vom Typ „Kein Gebot bei Überlastung“

Dieser Bieter akzeptiert Zusatzinformationen bis zu einer bestimmten Rate und gibt dann bei Überlastung Antworten vom Typ „kein Gebot“ zurück. Ähnlich wie beim Bietertyp „Fehler bei Überlastung“ kann dies auf verschiedene Arten implementiert werden. Der Unterschied besteht darin, dass kein Signal an Google zurückgegeben wird. Deshalb werden Zusatzinformationen nie gedrosselt. Die Überlastung wird von den Front-End-Maschinen absorbiert, die nur den Traffic weiterleiten, den sie verarbeiten können.

Das Diagramm für die Latenz dieses Bieters zeigt ein Plateau, das (künstlich) die Anfragerate zu Spitzenzeiten nicht mehr parallelisiert, und einen entsprechenden Rückgang des Anteils der Antworten, die ein Gebot enthalten.

Wir empfehlen, den Ansatz „Fehler bei Überlastung“ mit dem Ansatz „Kein Gebot bei Überlastung“ zu kombinieren. Gehen Sie dazu so vor:

  • Die Front-Ends überprovisionieren und bei Überlastung auf Fehler setzen, um die Anzahl der Verbindungen zu maximieren, auf die sie in irgendeiner Form reagieren können.
  • Bei einer Überlastung können die Front-End-Maschinen eine vordefinierte Antwort vom Typ „Kein Gebot“ verwenden und müssen die Anfrage nicht einmal parsen.
  • Implementieren Sie eine Systemdiagnose für die Back-Ends, damit bei keiner ausreichende Kapazität verfügbar ist, eine Antwort vom Typ „Kein Gebot“ zurückgegeben wird.

So kann eine gewisse Überlastung abgefangen werden und die Back-Ends haben die Möglichkeit, genau so viele Anfragen zu bearbeiten, wie sie bewältigen können. Sie können sich das als „Kein Gebot bei Überlastung“ vorstellen, wobei Front-End-Maschinen auf „Fehler bei Überlastung“ zurückfallen, wenn die Anzahl der Anfragen deutlich über den Erwartungen liegt.

Wenn Sie einen Bieter haben, der auf alles antwortet, sollten Sie ihn in einen Bieter mit der Funktion „Bei Überlastung Fehler zurückgeben“ umwandeln. Passen Sie dazu das Verbindungsverhalten so an, dass er sich effektiv weigert, überlastet zu werden. Dadurch werden zwar mehr Fehler zurückgegeben, aber es werden weniger Zeitüberschreitungen verursacht und der Server gerät nicht in einen Zustand, in dem er nicht mehr auf Anfragen reagieren kann.

Peering in Betracht ziehen

Eine weitere Möglichkeit, die Netzwerklatenz oder -variabilität zu reduzieren, besteht darin, eine Peer-Verbindung zu Google herzustellen. Mit Peering lässt sich der Pfad optimieren, über den Zugriffe zu Ihrem Bieter gelangen. Die Verbindungsendpunkte bleiben gleich, aber die Zwischenverbindungen ändern sich. Weitere Informationen finden Sie im Peering-Leitfaden. Die Gründe, warum Peering als Best Practice betrachtet werden sollte, können so zusammengefasst werden:

  • Im Internet werden Transit-Links hauptsächlich über das Hot-Potato-Routing ausgewählt. Dabei wird der nächstgelegene Link außerhalb unseres Netzwerks gefunden, über den ein Paket an sein Ziel gelangen kann, und das Paket wird über diesen Link weitergeleitet. Wenn Traffic einen Backbone-Abschnitt eines Anbieters durchläuft, mit dem wir viele Peering-Verbindungen haben, befindet sich der ausgewählte Link wahrscheinlich in der Nähe des Startpunkts des Pakets. Ab diesem Punkt haben wir keine Kontrolle über die Route, die das Paket zum Bieter nimmt. Es kann also auf dem Weg zu anderen autonomen Systemen (Netzwerken) weitergeleitet werden.

  • Im Gegensatz dazu werden Pakete bei einer direkten Peering-Vereinbarung immer über einen Peering-Link gesendet. Unabhängig davon, woher das Paket stammt, durchläuft es Verbindungen, die Google gehören oder die es mietet, bis es den gemeinsamen Peering-Punkt erreicht, der sich in der Nähe des Bieter-Standorts befinden sollte. Die Rückfahrt beginnt mit einem kurzen Hop zum Google-Netzwerk und bleibt den Rest der Strecke im Google-Netzwerk. Wenn der Großteil der Übertragung über die von Google verwaltete Infrastruktur erfolgt, nimmt das Paket einen Pfad mit geringer Latenz und es wird viel potenzielle Variabilität vermieden.

Statisches DNS einreichen

Wir empfehlen Käufern, immer ein einzelnes statisches DNS-Ergebnis an Google zu senden und die Traffic-Auslieferung Google zu überlassen.

Hier sind zwei gängige Praktiken von DNS-Servern von Bietern, um das Ladegleichgewicht zu verbessern oder die Verfügbarkeit zu verwalten:

  1. Der DNS-Server gibt als Antwort auf eine Abfrage eine Adresse oder eine Teilmenge von Adressen aus und durchläuft diese Antwort dann auf eine bestimmte Weise.
  2. Der DNS-Server antwortet immer mit denselben Adressen, aber die Reihenfolge der Adressen in der Antwort ändert sich.

Die erste Methode ist für das Load Balancing nicht geeignet, da es auf mehreren Ebenen des Stacks viel Caching gibt. Versuche, das Caching zu umgehen, führen wahrscheinlich auch nicht zu den gewünschten Ergebnissen, da Google die DNS-Auflösungszeit dem Bieter in Rechnung stellt.

Mit der zweiten Methode wird kein Load Balancing erreicht, da Google eine IP-Adresse aus der DNS-Antwortliste nach dem Zufallsprinzip auswählt. Die Reihenfolge in der Antwort spielt also keine Rolle.

Wenn ein Bieter eine DNS-Änderung vornimmt, berücksichtigt Google die in den DNS-Einträgen festgelegte TTL(Gültigkeitsdauer). Das Aktualisierungsintervall bleibt jedoch ungewiss.