應用程序自動規模伸縮以適應負載需求確實非常理想,但其中也蘊含著嚴重的復雜性與潛在風險。
不管大家有沒有聽說過,最近幾年市場上出現了一類極具吸引力的新方案——也就是云服務器。雖然這個名稱本身并沒有實際意義,但大家可以將云服務器理解成一系列包含有計算與I/O資源的實例,我們能夠根據自己的需求隨時將其實例化或者關閉。總之,亞克西。
不過單靠云技術概念還遠不足以構建起理想國。沒錯,它的出現讓構建可擴展環境變得非常輕松,但管理這類環境同樣非常復雜——特別是考慮到由業務變動引發的自動縮放與服務增長問題。在這種情況下,大家可能會突然發現自己找不到一種能夠搞定一切狀況的標準化方案。
我們過去一直將可擴展能力視為一種相對比較緩慢的調整選項。如果我們剛剛招徠到一大批新員工,那么IT部門就需要為他們提供額外的擴展服務器資源以支撐其存儲與應用需求,有時候甚至還得另行構建強大的數據庫集群等方案。我們需要花幾個月甚至幾年時間來不斷規劃規模伸縮機制。相比之下,大型互聯網站點則包含有大量物理服務器,而不必考慮當前實際負載——這是因為他們需要為時刻可能出現的峰值以及日常狀態下的平穩資源需求做好準備。而在多數情況下,這些服務器設備都處于閑置狀態。
但現在規模縮放已經成為一項能夠瞬間完成的任務。我們可以根據意愿生成新的實例,并在負載峰值結束后將其棄用。我們能夠在幾分鐘而非像過去那樣利用幾個月完成規模伸縮調整。不過這種自動化機制當中也包含有潛在風險,而且很難得到準確調整。自動化應用程序在規模伸縮當中包含眾多變量與調整空間,而不同應用在這些方面擁有著獨特的要求——換言之,對某款應用非常適用的方案在遷移至另一應用時往往效果極差。總結來講,細節就是其原罪。
舉例來說,我們可以設想一套典型的分層Web應用程序。在這里,我們擁有數據庫、存儲以及前端應用服務器這幾大元素。為了能讓這套基礎設施根據負載變化情況實現動態規模伸縮,我們需要監控所有這些組成部分,并根據實際負載決定其變動方式——同時又要考慮到其它部分負載給其帶來的影響。
如果我們的前端服務器開始出現峰值,那么我們則需要引入更多前端資源,但同一時間數據庫服務器的負載強度可能并沒那么大,這代表著我們需要在增加前端服務器數量的同時降低數據庫服務器數量。接下來,存儲I/O又會帶來新的問題,因此我們也需要為其添加更多資源。
在此之后,當負載開始重新回歸平穩時,我們則需要在基礎設施當中釋放這些多余資源——但不能釋放得太多,也不能釋放得太快。我們還需要在調整規模的同時為各處負載添加標簽,因為一個區域的容量降低可能會對另一區域產生負面影響。如果我們減少了數據庫資源,那么應用程序服務器上的負載可能會因此出現瓶頸,同時前端服務器則不受影響——總之,我們需要對其關聯保持高度關注。而且單純增長應用程序服務器而不解決負載資源緊張的問題,顯然也是于事無補。
正如大家所見,在這種情況下我們的決策樹將變得極為龐大,而且其中很可能包含有重大缺陷。我們需要部署大量監控機制與計時工具,記錄等待狀態、閾值以及計數。此外,我們還得將無數聲明與比較規則納入進來以構建起一套自適應基礎設施,且其邏輯本身也需要受到監控與調整。這絕不僅僅是一項單純的目標,而是一段不斷延續的摸索過程。
如果基礎設施的實際復雜程度超出我們之前設定的簡單Web應用,那么可能還會涉及多種公共API集成、緩存與查詢服務器、隊列 NoSQL數據庫服務器或者數量不等的現代服務組件,這將使得動態負載管理機制的復雜性呈指數級增長。很明顯,這絕不是一句簡單的“如果一臺服務器超載了,就使用另一臺”所能概括。
哦,另外需要強調的是,我們還沒有考慮到相關應用程序在設計當中是否考慮到了快速規模伸縮場景。如果答案是否定的,那么我們將很難甚至根本無法對后端資源進行調整。
動態規模伸縮能力帶來的收益是顯而易見的。它能夠以更低的使用成本為我們提供理想的性能水平與可用性表現,這無疑是一種雙贏局面。然而,要發揮其固有優勢也需要大家投入心血與代價,各位千萬不要等閑視之才好。