2013-02-22 40 views
0

假設我有一個非常大的要發送到遠程主機的請求池。像任何服務器一樣,遠程主機的容量有限。所有的信息必須最終交付,及時性是可取的,但不重要。除了通過監視我發送的請求的響應時間和/或失敗率之外,我無法知道遠程主機的這種容量。速率限制遠程請求的算法

我需要開發一種算法,以最大化吞吐量的速率發送請求,而不會使遠程主機崩潰。

最佳輸出變量似乎是請求之間的時間段,例如請求N在請求N-1之後調度M納秒。

我應該如何處理確定最佳費率的問題?我能建立什麼文件嗎?或者任何人都可以想出一些奇蹟算法?任何人之前做過?

注意:令牌桶不是我正在尋找的答案。我已經在使用非常像令牌桶的東西了,但我正在尋找一種方法來確定令牌應該添加到存儲桶的速率。

+0

這將取決於服務器如果超載它會做什麼。它會翻倒死亡,還是隻是沒有迴應,然後在一些(未知的)時間後恢復?如果您經常超出限制,服務器是否會將您關閉? – 2013-02-22 23:48:18

+0

在這種情況下,這取決於。實際上,我管理着大約9000個獨立遠程主機的不同池,我無法控制這些主機。 編輯:點擊輸入太早 - 有些會超時,有些會拒絕連接,有些會返回HTTP 50x。除此之外,我並沒有預見到其他許多成果。 – Burke 2013-02-22 23:54:14

+0

另外,我應該提到多次提交相同的請求不是問題。 – Burke 2013-02-22 23:56:12

回答

3

當我編寫我的網絡爬蟲程序時,我沒有想出一個神奇的算法。我們使用了一些似乎做得相當不錯的啓發式方法,儘管當然並不完美。

首先,我們看了一下該網站的robots.txt文件。如果它有一個爬行延遲條目,我們承諾永遠不會超過它。

對於其他服務器,我們會保持最後n次請求所需時間的平均值(我認爲我們的值爲5),並且確保我們從未發送過請求的頻率比這更高平均。我們測量了從發出請求到完成響應的時間。

如果服務器超時,該請求的時間將進入運行平均值。

如果我們從服務器獲得了50x,那麼在向服務器發出另一個請求之前,我們會延遲相當長的時間(五分鐘或更長)。重複50次的回覆會導致我們停止提出請求,直到有人能夠看到問題出在哪裏。

我們也跟蹤了40倍的反應。很多未找到或訪問被拒絕將導致爬蟲停止處理一個域,並提出一個標誌,以便有人可以看看它。

我們有一個分佈式抓取工具。沒有單獨的爬蟲可以向同一個域發出併發請求,而且我們有一些跨服務器通信,這使得多個服務器向同一個域發出併發請求的情況並不常見。

我敢肯定,這並不是最大化吞吐量在任何特定的服務器,但它確實讓大型網站非常繁忙。對我們來說更重要的是,它阻止了我們(主要是無論如何)被許多網站阻止。

我們還對許多使用API​​的站點進行了特殊處理。有些人會說他們的請求限制是什麼,我們會調整我們對這些網站的設置,所以我們正好坐在線上。但我們只有幾十個。爲9000臺服務器手動配置請求頻率(然後跟上更改)並不現實。但是,您可能可以手動配置一兩個。