2023-02-18 09:02:08 來源:騰訊云
可擴展和彈性伸縮系統(tǒng)設計
可擴展架構基礎
可擴展架構的背景
軟件系統(tǒng)是可以隨著需求變化或者技術變化而不斷擴展和迭代的,我們常見的各種軟件系統(tǒng)比如操作系統(tǒng)、各種知名開源軟件系統(tǒng)都是如此。而在這個過程中,我們如何通過較小的代價去擴展我們的系統(tǒng),是我們要重點考慮的。
可擴展的基本思想:拆分(流程、服務、功能)
可擴展性架構的設計方法雖然很多,但是最核心的思想就是拆分。將大系統(tǒng)拆分為小系統(tǒng)、小模塊,然后針對其中的子系統(tǒng)或者模塊來進行擴展,這樣可以通過較小的改動去實現(xiàn)整個系統(tǒng)的擴展能力,可以同時滿足擴展需求和改動的風險。
(資料圖)
拆分的方式包括 流程、服務、功能 三部分,理解這三種思路的關鍵就在于如何理解“流程”“服務”“功能”三者的聯(lián)系和區(qū)別。從范圍上來看,從大到小依次為:流程 > 服務 > 功能。以 TCP/IP 協(xié)議棧為例,來說明“流程”“服務”“功能”的區(qū)別和聯(lián)系:
流程對應 TCP/IP 四層模型,因為 TCP/IP 網絡通信流程是:應用層 → 傳輸層 → 網絡層 → 物理 + 數據鏈路層,不管最上層的應用層是什么,這個流程都不會變。服務對應應用層的 HTTP、FTP、SMTP 等服務,HTTP 提供 Web 服務,F(xiàn)TP 提供文件服務,SMTP 提供郵件服務,以此類推。功能每個服務都會提供相應的功能。例如,HTTP 服務提供 GET、POST 功能,F(xiàn)TP 提供上傳下載功能,SMTP 提供郵件發(fā)送和收取功能。可擴展架構模式
根據拆分的思想,典型的可擴展系統(tǒng)架構有:
面向流程拆分(分層架構)。由于系統(tǒng)做了合理的分層,因此擴展的時候,可能只需要修改其中一層就可以進行功能擴展。一個典型的分層架構系統(tǒng)的擴展就是對數據層的擴展,比如之前只支持 MySQL,現(xiàn)在需要同時支持 MySQL 和 Elasticserach,那么只需要 在數據層進行修改擴展即可不太常見的 2 層架構(C/S 架構、B/S 架構)。通過用戶交互維度來劃分,和用戶交互的是一層、支持交互的后端系統(tǒng)是一層。常見的是 3 層架構(MVC、MVP 架構)。一般通過業(yè)務功能職責來劃分。還有一些 2 層架構(C/S 架構、B/S 架構)。通過用戶交互維度來劃分,和用戶交互的是一層、支持交互的后端系統(tǒng)是一層。常見的邏輯分層架構。比如操作系統(tǒng)的邏輯分層架構、比如一般我們后臺業(yè)務系統(tǒng)里面的分層架構。面向服務拆分(SOA、微服務)。這個是現(xiàn)在最常見的架構設計,因為都是微服務形態(tài),那么擴展的時候,只需要針對每個獨立運行的微服務進行擴展,其他服務無感知,這樣修改的粒度很小,擴展會比較容易。面向功能拆分(微內核架構)。這個是我最近才了解到的一種架構設計,針對這種架構,對某個功能擴展,或者要增加新的功能時,只需要擴展相關功能即可,無須修改所有的服務。響應時間 和 可伸縮性 的關系
可擴展性(Scalability)與性能是不能混為一談的,性能 != 可擴展。性能是指系統(tǒng)提供一定響應時間的能力;可擴展性是指我們可以很容易的通過擴容集群、擴容數據庫、擴容實例等簡單的方式來提供整體的并發(fā)能力,這樣的話,只要請求訪問量增加,我們就可以通過擴展機器的方式來適應請求量的增加。系統(tǒng)可以是高性能的,但可能是不可擴展的。
性能(performance)-> 響應時間: 接口請求的響應時間可伸縮性(Scalability): 包括橫向擴展(Scaling Out)和縱向擴展(Scaling Up )橫向擴展(水平擴展): 增加實例、增加機器縱向擴展(垂直擴展): 增加硬件配置如 CPU 核數;使用更高性能的 CPU、網卡等;增加內存容量;但是這里需要注意的是響應時間 和 可伸縮性可能不是同步的或者是線性的,也就是說當請求量增加,并且進行各種擴容后,雖然抗住了請求量,但是響應時間不見得會變短,可能會變長,因為請求量的增加導致底層的各種系統(tǒng)資源消耗較多或者下游的依賴壓力較大從而導致響應時間變長。
系統(tǒng)資源 和 水平擴展的關系
請求量增加的時候,要進行擴容,擴容最容易和最常見的方式是水平擴展服務,也就是擴容無狀態(tài)實例。但是,針對一些系統(tǒng)資源或者依賴資源,比如數據庫(MySQL)、緩存(Redis)等,這些有狀態(tài)的不能無限擴容,因此就一定考慮他們的性能,他們的性能才是底線,如果 redis 、ES 等扛不住,那么擴容再多無狀態(tài)實例也是白費。這里需要特別注意這些底層依賴資源的性能以及無狀態(tài)服務和他們連接的一些連接池、并發(fā)數等。
可擴展和 彈性伸縮的關系
可擴展性是指系統(tǒng)適應更大的負載的能力,只需通過增加資源,使硬件更強大(擴展)或增加額外的節(jié)點(擴展)。
彈性伸縮是指動態(tài)地適應應對負載所需的資源的能力,通常與擴展性有關。因此,當負載增加時,你通過添加更多的資源來擴大規(guī)模,而當需求減弱時,你就縮減并刪除不需要的資源。 彈性伸縮在云環(huán)境中非常重要,一方面你要按使用量付費,不想為你目前不需要的資源付費,另一方面要在需要時滿足不斷增長的需求。
可擴展架構設計(Scalability)
可擴展架構設計的最佳實踐
一些最佳實踐可以參考(翻譯) OpenShift 的 Best Practices for Scaling Out 這篇文章,這里在此基礎上做進一步的整理和總結:
微服務化設計,盡量讓我們的系統(tǒng)模塊化、組件化,從而實現(xiàn)高內聚,低耦合的思想,提高復用性,擴展性。這樣每個微服務可以獨立進行擴展,而且一個服務掛掉并不會導致整個服務不可用;這個也同樣適用于數據庫的拆分邏輯。分層設計,可擴展架構設計的基本要求就是我們服務要先進行分層,然后每一層都要能夠單獨擴展,并且需要用到負載均衡技術。消息隊列:模塊化的系統(tǒng)通過消息隊列進行交互,使模塊之間的依賴解耦。隊列的引入可以緩解流量突峰,也可以流程異步化,提高性能、穩(wěn)定性。 高并發(fā)、大流量下,同步機制會使得整體響應非常慢,因此當前一般的高并發(fā)系統(tǒng)都是異步處理的,一般我們可以通過消息隊列實現(xiàn)異步。分布式服務:公用模塊服務化,提供其他系統(tǒng)使用,提高可重用性,擴展性。聯(lián)系緊密的服務盡量部署到同一個集群,避免跨集群訪問帶來的延遲、帶寬增加等應用程序應該盡量采用無狀態(tài)服務,而不是采用有狀態(tài)服務;將需要存儲的狀態(tài)統(tǒng)一用分布式存儲、分布式緩存來存儲。善用分布式緩存;訪問緩存比訪問數據庫或者文件系統(tǒng)性能高很多,避免直接操作數據庫,可以極大提高性能設計模式:應用面向對象思想,原則,使用設計模式,進行代碼層面的設計。網關入口要使用負載均衡層,常見的是 Nginx 和 HAProxy,當做 7 層代理集群,然后后面再接入應用服務。使用代理層是可擴展架構的必要前提。不要過度設計,根據情況考慮是否最初就設計為可擴展架構,不必從一開始就構建可伸縮的體系結構,擴展的關鍵是先于用戶發(fā)現(xiàn)瓶頸。不要強迫將自己熟知的技術運用到不恰當的領域來解決特定領域的問題;所用來解決問題的技術方案應該是某個技術所擅長的領域盡可能的自動化所有事情,好的監(jiān)控統(tǒng)計系統(tǒng)非常重要,可以幫助我們了解系統(tǒng)的運行狀態(tài)、回溯問題、分析問題;及時告警,這個不僅僅是針對擴展架構,所有服務架構都是一樣的。可擴展代碼的一些最佳實踐
參考(翻譯)Rackspace Writing Code that Scales 的寫出高擴展和高性能代碼的工程原則:
首先就要編寫壓力測試計劃。比如支持 10w 個并發(fā)連接、響應設計小于 200ms。這個就是我們的預期目標,我們接下來的設計、規(guī)劃都要圍繞這個目標以及超過目標來進行善于緩存。包括分布式緩存、本地緩存。少量頻繁訪問的可以本地緩存大部分情況下都能夠使用分布式緩存解決我們的數據緩存問題。(Redis)需要外網進行網絡傳輸的數據,能夠壓縮的盡量壓縮后傳輸??蛻舳撕头斩酥g的數據交互,盡可能的壓縮。數據壓縮后的傳輸可以大大減少外網傳輸時間,并提高了單位時間的連接處理能力。壓縮的傳輸一定會比未壓縮后傳輸的效率高,相比網絡傳輸的時間,CPU 用來壓縮和解壓縮的時間是可以忽略的。關于磁盤 IO 如果有大量的數據需要存儲到磁盤上,然后需要讀寫,那么要進行壓縮后存儲,雖然存儲便宜,但是 IO 消耗卻很大,壓縮后可以有效的提高 IO 吞吐量盡可能將隨機 IO 模式替換為順序 IO 模式降低每個連接的開銷。一般而言,每個連接都需要一定的內存,比如一個最基本的 TCP 連接可能需要 2k 的內存;減少每個連接的開銷可以支持更多的連接處理更多的事情。入口流量設計準入控制,需要有限流設計、隊列設計。后端服務雖然可以自動擴縮容,但是它們的承受能力可能會有一個極限值,因此在極限值的時候就需要有限流措施,可以允許有一定的隊列任務堆積,但是不能無限制的增長隊列,當請求量超過一定的極限后,這個時候不能繼續(xù)等待,而應該快速失敗。如果持續(xù)等待,不加以限流措施,那么很可能會導致讓整個系統(tǒng)變得更慢,從而壓垮整個系統(tǒng)。關于通信協(xié)議,如果應用程序的組件通過外網相互通信,或者在客戶端和服務器之間進行了大量通信,盡可能將文本分析協(xié)議的使用降至最低,也即是減少 xml、json 協(xié)議,而應該使用二進制協(xié)議如 pb,彈性伸縮設計
因為可擴展和彈性伸縮是非常緊密的,因此這里也同時看看,要實現(xiàn)彈性伸縮,需要有哪些設計。
目前云上的架構,基本都有自動彈性伸縮功能,服務部署到公有云或者私有云上,應該是都能根據 CPU 使用率等基本指標來自動伸縮的。但是,當我們想要自己設計一個自動伸縮的架構,那么該怎么設計?
無狀態(tài)服務設計
要能夠彈性伸縮,服務一定是要無狀態(tài)的才能比較好的保證,有狀態(tài)服務的不太好實現(xiàn)彈性伸縮。
基礎鏡像輕量、快速啟動
實例啟動的時間很重要,如果不能快速啟動,那么當檢測到需要伸縮的時候,如果擴容很久才啟動新實例,那么擴容期間是有損的,因此快速啟動是必須的。快速啟動的一個必要條件就是基礎鏡像要比較輕量,這樣的話,從拉取鏡像到啟動鏡像的過程就會比較快速;這個在容器時代的優(yōu)勢比較明顯,通過 Docker 可以比較好的滿足我們的訴求。
健康檢查
最好要有健康檢查模塊,能夠保證擴容后的實例是可以正常 work 的,要不然擴容了也沒用。同時如果服務異常,那么需要及時摘掉。當然,其他基礎模塊也會對服務做健康檢查,這個設計就要根據整體架構做取舍,看是否有更合適的健康檢查模塊,如果沒有,那么健康檢查放到哪里更為合適。
如果是在自動伸縮架構中的健康檢查,那么需要檢測:
業(yè)務程序是否部署成功?需要有一個探測接口用來探測業(yè)務程序是否正常運行業(yè)務服務是否能夠對外提供流量操作系統(tǒng)級別是否出現(xiàn)了異常在 k8s 容器平臺下,健康檢查一般會有兩個地方來保證:
K8s 本身的 kubelet 來保障負載均衡代理層來保障服務優(yōu)雅關閉
當我們要自動縮容服務實例的時候,一個非常關鍵的地方就是,實時運行的服務,如果直接關閉,勢必會對流量有損,這樣對業(yè)務服務、對客戶都有一定的影響。作為一個極致的技術人,我們必須要能夠保證服務可以優(yōu)雅關閉、優(yōu)雅下線。
一般會有如下幾個方式:
通知服務退出的時候,服務延遲退出,先摘掉流量,不讓新的請求進來,然后預留時間把當前正在處理的任務繼續(xù)處理完畢之后再退出。 這個就要求業(yè)務服務和彈性伸縮架構能夠配合聯(lián)動起來,需要設計這么一個機制。K8s 就有這樣的機制,當收到 TERMINATED 退出信號之后 Pod 可以不馬上退出,而是可以延遲一定的時間后再退出自定義指標來執(zhí)行彈性伸縮
一般來說,通過 CPU 、內存的使用率來進行彈性伸縮是最常用的功能,也挺有效果;在此基礎之上,我們還可以自定義一些指標,可以更貼合業(yè)務,比如 QPS,通過這些個指標來進行彈性伸縮。
比如我們的 K8s 平臺,我們就擴展了 QPS 指標,還有一些比如流量帶寬之類的,但是 CPU 和 QPS 指標是最常用的彈性伸縮指標。
縮放比例尺設計
使用彈性縮放比例時,刪除實例時,應用程序將具有一定的縮放比例。應用程序必須妥善處理要刪除的實例。以下是處理 scalein 的一些方法:
最好可以監(jiān)聽關閉(退出)事件,然后優(yōu)雅關閉。服務的客戶/消費者應支持瞬時故障處理和重試。對于長時間運行的任務,應該使用檢查點或“ 管道和過濾器”模式來分解工作。將工作項放在隊列中,以便另一個實例可以接管工作(如果在處理過程中刪除了一個實例)。卸載資源密集型任務
盡可能將需要大量 CPU 或 I/O 資源的任務移至后臺作業(yè),以最大程度地減少處理用戶請求的前端負載。
確定整個系統(tǒng)的瓶頸
擴展并不是解決每個性能問題的靈丹妙藥,要先確定整個系統(tǒng)中哪個環(huán)境是瓶頸,這樣才能更好的擴展。
推薦閱讀
推薦閱讀我的其他文章:
《高并發(fā)架構和系統(tǒng)設計經驗》
《TCP 長連接層的設計和 在 IM 項目中實戰(zhàn)應用》
《萬字解讀云原生時代,如何從 0 到 1 構建 K8s 容器平臺的 LB(Nginx)負載均衡體系》
《高可用架構和系統(tǒng)設計經驗》
- 加快虛擬仿真實訓基地建設 啟動職業(yè)學校信息化建設試點很必要
- “雙減”后如何在滿足學生多樣需求方面做“加法”?
- 處于生理活躍期且心理發(fā)展不成熟 高校開設公共衛(wèi)生必修課很必要
- 價格低于相應蔬菜零售價 西安投放約1萬噸政府儲備蔬菜
- 深受年輕消費群體所青睞 國潮風商品成為年貨新選擇
知識
- 他把銀行卡賣給騙子,“黑吃黑”“截胡”十萬元
- “老司機”4S店試駕豪車 結果油門當剎車撞了
- 新開工改造城鎮(zhèn)老舊小區(qū)5.34萬個
- 發(fā)動巡河志愿者2萬余名 “用心護好每一條河”
- 假客服的套路:偽裝成大平臺客服,層層布局引人上鉤
人物
- 浙江兩輪核酸檢測結果均為陰性 無新增本土陽性感染者
- 新疆阿克蘇地區(qū)庫車市發(fā)生4.1級地震 震源深度18千米
- 抵返哈爾濱人員須持48小時內核酸檢測陰性證明
- 浙大紫金港校區(qū)已解封 有7337人有序離開該校區(qū)
- 2021年廣東省第七屆風箏錦標賽落幕
- 黑龍江訥河市啟動全員核酸檢測 目前訥河市全員核酸檢測結果均為陰性
- 【同心粵港澳 攜手大灣區(qū)】南頭古城,搭建深港澳三地文化創(chuàng)意活動交流平臺
- 重慶入河排污口整治工作推進至全市26個區(qū)縣
- 四川省第二批政法隊伍教育整頓:立案審查調查省級政法機關干警58人
- 長三角區(qū)域生態(tài)環(huán)境部門“云簽約”長江大保護倡議書
- 古老長城重煥新生機
- 藏不住了!你同事里有許多“武林高手”……
- 浙江杭州2例無癥狀感染者系感染德爾塔變異株
- 喜馬拉雅的深情和誓言
- 浪漫之城打造山海城一體新地標
- 讓老年人更適應數字生活
- 內蒙古通遼市新增1例本土確診病例、1例無癥狀感染者
- 徐州無新增確診病例 核酸檢測55515人結果均為陰性
- 甘肅培樹“農家巧娘”增技能:返鄉(xiāng)創(chuàng)業(yè)掌勺又“掌柜”
- 內蒙古通遼市科爾沁區(qū)一地調整為中風險地區(qū)
- 上海本輪疫情涉及閉環(huán)管理的醫(yī)療機構全面恢復門急診
- 青年學生成艾滋病感染高發(fā)人群 “社會疫苗”如何打?
- 內蒙古滿洲里新增本土確診病例1例 當地開展第二輪大規(guī)模核酸檢測
- 江西無新增本土確診病例 上饒全面恢復正常生產生活秩序
- 中老鐵路上會四國語言的列車長:用心維護中老友誼的橋梁
- 海南首次發(fā)現(xiàn)有環(huán)志的世界極危鳥種勺嘴鷸
- 一場“網絡勸生者”和“網絡勸死者”的戰(zhàn)役
- 內蒙古通遼新增本土確診和無癥狀感染者各1例 軌跡公布
- 江西中煙工業(yè)有限責任公司原總經理姚慶艷接受審查調查
- 寧夏45例新冠肺炎確診病例均已治愈出院
- 內蒙古通遼市科爾沁區(qū)發(fā)現(xiàn)2名初篩陽性人員
- 生活在鬧鐘里的丈夫:自己遲一秒,漸凍癥妻子就會多一分疼
- 遼寧新冠肺炎確診病例零新增
- 11月28日16-24時,內蒙古新增本土確診病例1例
- 奧密克戎毒株為何“需要關注”?現(xiàn)有防疫工具還有效嗎?
- 黑龍江新增本土無癥狀感染者1例
- 這輩子一定要去趟這個公園 在這里“有種愛叫放手”
- 那年今日 | 一張漫畫漲知識之11月29日
- 寒潮預警!我國中東部迎大范圍降溫 黑龍江等地降幅可達12℃
- 冷空氣繼續(xù)影響我國中東部 華北黃淮等地有霧和霾天氣