即時出價應用程式最佳做法

本指南將說明依據即時出價通訊協定開發應用程式時,應考慮的最佳做法。

管理連線

維持連線

建立新連線會增加延遲時間,且在兩端使用比重複使用現有連線所需的資源多得多。關閉的連線數越少,就越少需要重新開啟的連線。

首先,每個新連線都需要額外的網路來回連線才能建立。由於我們會視需要建立連線,因此連線的首要要求有效期限較短,因此比後續要求更有可能逾時。任何額外的逾時都會提高錯誤率,進而導致出價方受到節流。

其次,許多網路伺服器會為每個建立的連線產生專屬的工作執行緒。也就是說,如要關閉並重新建立連線,伺服器必須關閉並捨棄執行緒、分配新的執行緒、讓其可執行,並建立連線狀態,最後再處理要求。這會造成許多不必要的負載。

避免關閉連線

請先調整連線行為。大多數伺服器預設值都是針對擁有大量用戶端的環境所量身打造,每個用戶端都會發出少量要求。相較之下,RTB 會由少量機器人代表大量瀏覽器傳送要求。在這些情況下,建議盡可能重複使用連線。建議您設定下列項目:

  • 將閒置逾時時間設為 2.5 分鐘。
  • 連線要求數量上限為最高可能值。
  • 連線數量上限為 RAM 可容納的最高值,但請注意,連線數量不得過於接近該值。

舉例來說,在 Apache 中,您必須將 KeepAliveTimeout 設為 150,將 MaxKeepAliveRequests 設為零,並將 MaxClients 設為取決於伺服器類型的值。

調整連線行為後,您也應確保出價方程式碼不會不必要地關閉連線。舉例來說,如果您的前端程式碼在後端錯誤或逾時的情況中傳回預設的「無出價」回應,請確定程式碼是在未關閉連線的情況下傳回回應。這樣一來,您就能避免在出價工具超載的情況下,連線開始關閉且逾時數目增加,因而導致出價工具受到節制。

維持平衡的連線

如果授權買家透過 Proxy 伺服器連線至出價方伺服器,由於只知道 Proxy 伺服器的 IP 位址,授權買家無法判斷哪個出價方伺服器會接收每個呼叫,因此連線可能會隨著時間而失去平衡。隨著時間推移,授權買方建立及關閉連線,以及出價方伺服器重新啟動,對應至每個連線的連線數量可能會變得相當多變。

當部分連線使用率很高時,其他已開啟的連線可能會處於閒置狀態,因為當下並不需要這些連線。隨著授權買方的流量變化,閒置連線可能會變成有效連線,有效連線也可能變成閒置連線。如果連線的叢集方式不佳,可能會導致出價方伺服器的負載不均。Google 會在 10,000 次要求後關閉所有連線,以便自動重新平衡熱門連線。如果您仍發現環境中的流量不平衡,可以採取其他步驟:

  1. 如果您使用前端 Proxy,請為每項要求選取後端,而非為每個連線選取一次。
  2. 如果您是透過硬體負載平衡器或防火牆代理連線,且連線建立後會固定對應,請指定每個連線的要求數量上限。請注意,Google 已指定每個連線的上限為 10,000 個要求,因此如果您仍發現熱門連線在環境中形成叢集,才需要提供更嚴格的值。例如,在 Apache 中將 MaxKeepAliveRequests 設為 5,000
  3. 設定出價方伺服器,監控其要求率,並在出價方持續處理比同儕過多的要求時,關閉部分連線。

妥善處理過載

理想情況下,配額應設為足夠高,讓出價方能夠接收所有可處理的要求,但不要超過這個數量。實際上,要讓配額維持在最佳水準是一項艱鉅的任務,而且會發生超載的情況也有很多種:後端在尖峰時段停機、流量組合發生變化,導致每個要求需要更多處理作業,或是配額值設定過高。因此,請考量出價方在流量過多時的行為。

為因應各地區 (尤其是亞洲與美國西部、美國東部與美國西部) 之間的暫時流量轉移 (最多一週),建議您在 7 天高峰值和每個交易地點的 QPS 之間保留 15% 的緩衝空間。

在高負載情況下,出價方可分為以下三類:

「回應所有內容」出價工具

雖然這個出價方實作起來很簡單,但在超載時的表現最差。無論如何,它都會嘗試回應收到的每項出價請求,並將無法立即放送的請求排入佇列。接著發生的情況通常如下所示:

  • 隨著要求比率上升,要求延遲時間也會增加,直到所有要求都開始逾時為止
  • 隨著呼叫率接近峰值,延遲時間會急遽上升
  • 開始進行節流,大幅減少允許的呼叫數量
  • 延遲時間開始恢復,導致節流減少
  • 週期又開始了。

此出價方代碼的延遲時間圖表類似鋸齒狀圖案。另外,佇列要求會導致伺服器開始分頁記憶體或執行其他導致長期減速的動作,且延遲時間不會在尖峰時間結束後恢復,導致整個尖峰期間的呼叫率降低。無論是哪種情況,與單純將配額設為較低值相比,系統會發出或回應的說明文字會減少。

「error on overload」出價方

這個出價方會接受一定比率的說明文字,然後開始針對部分說明文字傳回錯誤。這可以透過內部逾時、停用連線佇列 (由 Apache 上的 ListenBackLog 控制)、在使用率或延遲時間過高時實作機率性捨棄模式,或透過其他機制來達成。如果 Google 觀察到錯誤率超過 15%,就會開始限流。與「回應所有」出價方不同,這個出價方會「減少損失」,因此在請求率下降時,可以立即恢復。

在超載期間,此出價方延遲時間的圖表會呈現淺淺的鋸齒狀圖案,並在可接受的最高頻率附近本地化。

「no-bid on overload」出價方

這個出價方會接受一定數量的說明文字,然後開始針對任何超載傳回「沒有出價」回應。與「錯誤超載」出價方類似,這項功能可以透過多種方式實作。差異在於不會向 Google 傳回信號,因此我們不會限制說明文字。前端機器會吸收超載,只允許它們可處理的流量繼續傳送至後端。

這位出價方延遲時間的圖表顯示,在尖峰時段,系統會 (人為地) 停止並平行處理要求率,而包含出價的回應比例也會相應下降。

建議您將「超載時發生錯誤」和「超載時不出價」這兩種做法結合使用,如下所示:

  • 為前端超額配置資源,並將其設為過載時發生錯誤,以便在某種形式下,盡可能提高前端可回應的連線數量。
  • 當前端機器發生超載錯誤時,可以使用預先編寫的「no-bid」回應,完全不需要剖析要求。
  • 實作後端的健康狀態檢查,如果沒有任何後端有足夠的容量,則會傳回「無出價」回應。

這可吸收部分超載情形,讓後端有時間回應能處理的所有要求。您可以將這項做法視為「超載時不出價」,當要求次數遠高於預期時,前端機器會改為「超載時發生錯誤」。

如果您有「回應所有」出價方,請考慮將其轉換為「超載時發生錯誤」出價方,藉由調整連線行為,實際拒絕超載。雖然這會導致傳回更多錯誤,但可減少逾時情形,並防止伺服器進入無法回應任何要求的狀態。

考慮對接

另一種減少網路延遲時間或變化的方法,就是與 Google 對等互連。配對功能有助於最佳化路徑流量,讓流量順利抵達出價方。連線端點保持不變,但中間連結會變更。詳情請參閱對等連線指南。將對等連線視為最佳做法的理由可歸納如下:

  • 在網路上,轉接連結的選擇主要透過「熱點路由」進行,這項功能會在網路外尋找最接近的連結,以便將封包傳送至目的地,並透過該連結將封包路由傳送。如果流量經過由我們有許多對等連線的供應商所擁有的骨幹網路部分,所選連結可能會位於封包開始的位置附近。在此之後,我們無法控制封包前往出價方的方式,因此封包可能會在途中轉送至其他自治系統 (網路)。

  • 相反地,如果已建立直接對等連結協議,封包一律會透過對等連結傳送。無論封包來自何處,都會穿越 Google 擁有或租用的連結,直到到達共用對等點為止,該點應位於出價方位置附近。反向路徑一開始會短暫跳轉至 Google 網路,並在後續路徑上維持在 Google 網路上。將大部分的旅程保留在 Google 管理的基礎架構中,可確保封包採用低延遲路徑,並避免許多潛在的變化。

提交靜態 DNS

我們建議買家一律向 Google 提交單一靜態 DNS 結果,並由 Google 處理流量放送作業。

以下是出價方 DNS 伺服器嘗試載入平衡或管理可用性時的兩種常見做法:

  1. DNS 伺服器會針對查詢發出一個位址或位址子集,然後以某種方式循環這個回應。
  2. DNS 伺服器一律會以相同的位址組合回應,但會循環回應中的位址順序。

第一種方法在負載平衡方面效果不佳,因為堆疊的多個層級都會快取大量資料,而且嘗試略過快取的做法可能也不會取得偏好的結果,因為 Google 會向出價方收取 DNS 解析時間費用。

第二種方法完全無法達到負載平衡,因為 Google 會隨機從 DNS 回應清單中選取 IP 位址,因此回應中的順序並不重要。

如果出價方變更 DNS,Google 會遵循 DNS 記錄中設定的 TTL(存留時間),但刷新間隔仍不明。