隊列并不能解決“超載”

人文精神  >>>  技術話題—商業文明的嶄新時代

  文/馬德奎 

  人們總是錯誤地使用隊列,最壞的情況是用它解決“超載(overload)”問題。Fred Hebert 是《Learn You Some Erlang for Great Good!》一書的作者。在這本 Erlang 入門書籍中,他結合生動的插圖、恰當的實例以淺顯易懂的方式講解了技術問題。近日,他以同樣的方式闡釋了為什么“隊列不能解決超載”。

  他將系統比作一個洗手池,如下所示:

  在正常的操作下,數據只從左側流入,出口可以處理所有數據。但在一些重大活動期間,比如圣誕節,可能會出現如下情況:

  數據從左右兩側同時流入系統。如果數據輸入越來越快,那么出口就可能會無法及時處理所有數據。這時,人們通常會考慮增加一個隊列緩沖區(如上圖的水槽)存儲臨時數據。但不管隊列多大,持續的超載都會導致如下情況的發生:

  隊列滿了,系統崩潰。這時候,開發人員會查看堆棧跟蹤、隊列、數據庫查詢以及調用的 API。但經過各種優化,甚至更換更大的服務器后,系統仍然無法承受這種持續的超載,因為瓶頸在出口(下圖中紅箭頭所示的位置):

  該瓶頸可能是數據庫,可能是磁盤、帶寬或 CPU。不消除這種瓶頸,任何優化都是徒勞。所以此時,開發人員應該做的是阻塞輸入,即“反壓(back-pressure)”或者丟棄數據,即“卸載(load-shedding)”。可能有人會認為,反壓會招致用戶的不滿。但實際上,即使不主動反壓,當系統負載達到一定程度后,速度也會降低,甚至崩潰。所以,雖然反壓會降低用戶的輸入速度,但卻可以保證系統的運行。另外,引入隊列作為一種優化機制會違背端到端原則。因此,開發人員應該設置更多允許超時的地方,提供故障檢測方法,并將其反饋給用戶。

  如上圖所示,開發人員可以在識別出系統瓶頸后設置相應的反壓機制,避免數據流入過快。而依據檢查點的不同,開發人員可以對延遲和吞吐量實現不同層次的優化。

  借助反壓或卸載,開發人員可以獲得以下好處:

  • 合適的服務質量指標
  • 減少緊急修復的次數
  • 根據賬戶限制和優先通道收費的方式
  • 系統更穩定

  總之,如果 API 設計考慮了端到端原則和冪等性,那么反壓或卸載對調用者而言通常不會成為問題,因為它們可以安全地重試請求。


  感謝郭蕾對本文的審校。


InfoQ 2015-05-19 00:39:03

[新一篇] 阮一峰:版權的邊界

[舊一篇] 閱讀的理解、速度及多少
回頂部
寫評論


評論集


暫無評論。

稱謂:

内容:

驗證:


返回列表