隊列并不能解決“超載”

jopen 10年前發布 | 6K 次閱讀 隊列

        文/馬德奎 

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

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

隊列并不能解決“超載”

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

隊列并不能解決“超載”

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

隊列并不能解決“超載”

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

隊列并不能解決“超載”

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

隊列并不能解決“超載”

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

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

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

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


        感謝郭蕾對本文的審校。

來自: InfoQ
                    <span id="shareA4" class="fl">                  
                        </span>
 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!