更新時間:2024-08-12 11:55:06作者:佚名
眾所周知,分布式緩存是提升系統性能的銀彈,在大型分布式系統中使用頻率很高,對提升系統性能起著不可或缺的作用。近些年,分布式和集中式系統在整個IT行業大行其道,CRM基于高內聚、低耦合的原則,逐漸演化為多中心分布式部署架構。由此產生的中心間交互,在日益復雜的業務催化下,對PAAS平臺組件提出了更高的要求。不出意外,分布式緩存在業務生產中也面臨著諸多挑戰。
02 理想與現實的沖突
業務系統引入分布式緩存的初衷是為了提升系統性能,為用戶帶來快速、簡潔、靈活的操作體驗。為了盡快享受到分布式緩存帶來的好處,加速系統建設中分布式緩存的引入,采用惰性加載(讀取時觸發)模式——當緩存中沒有數據時,先從DB讀取,再加載到分布式緩存中。這種模式在很多系統建設初期很常見。
隨著時間的推移和業務需求的變化,人們會發現單純使用分布式緩存已經不能滿足復雜業務的需求,因此會加入應用服務器作為二級緩存,減少應用與遠程分布式緩存的交互次數,經過調整后,系統的緩存使用架構變成了兩級模型。
在這個架構模式下,我們發現在很多業務場景,比如商品查詢、品銷關系查詢等,系統性能得到了很大的提升。然而這也帶來了一些緩存使用上的問題:
1)緩存數據不透明:無論是遠程分布式緩存還是本地二級緩存都是巨大的黑盒子,目前還沒有可靠的可視化工具可以清晰的查看緩存的內容。尤其是緩存key/value在應用層處理之后,運維人員沒有辦法通過簡單的標識來查看緩存key對應的value。
2)多中心緩存刷新問題:在多中心架構下,多個中心可能需要同一套配置數據,那么在刷新的時候,如何保證每個中心的緩存都能被刷新?如何保證錯過的刷新能被及時發現并靈活處理?
3)緩存數據一致性問題:如何保證遠程分布式緩存、本地二級緩存、DB的數據一致性?如何及時發現不一致情況并進行預警。
在分布式緩存給業務系統帶來的理想性能提升面前,使用過程中還存在一些技術與業務融合的痛點,運維過程中也面臨一些比較實際的問題,解決理想與現實的沖突也是一大挑戰,我們該怎么辦?
03 直面挑戰,給出答案
日常生活中,我們經常會遇到房屋設施因時間、個人需求、人口規模等變化而變得陳舊過時的情況,需要時不時地進行整理或翻新。有趣的是,實際的 CRM 緩存優化過程與翻新舊房的過程類似。
圍繞“一個愿景、兩個目標、四項提升、七項舉措”,各CRM中心緩存模塊的重構優化分為兩大部分:一是主體改造部分,二是微調打磨部分。
04 主體改造-緩存刷新重構改造前期-現有功能拆解
改造前期,梳理原有功能邏輯的過程需要對現有業務支撐強度有一定的了解。拆解原有頁面所有組件,包括按鈕、表單等,記錄每個按鈕的功能。拆解是一個機械的過程,不需要任何額外的判斷。所有需要優化的部分都會在后面的步驟中決定出來。這樣方便后期區分哪些業務功能需要保留,哪些邏輯需要重組。
設計階段:確定整體風格,進行總體設計
經過拆解梳理現有功能,我們已經知道系統中現有的功能,發現原來舊版的頁面功能比較混亂,有些邏輯冗余,有些功能存在缺陷,經過梳理,我們按照業務維度進行整理歸納,確定了整體優化方案,制定了統一刷新的整體事項及方案:
重新設計的統一刷新架構如圖所示
優化重構第一步:拆除工作-消除不必要的冗余邏輯
經過功能分解和專項設計階段,發現緩存刷新口徑有十余個,分散在各個中心,如此多的口徑和頁面,難免讓運維人員感到無所適從,這就需要對各個中心分散的緩存管理功能進行取精去糟粕,剔除分散的頁面和冗余的業務邏輯,將各個中心保留的頁面功能整合到門戶統一的管理頁面中。
第二步:隱藏構建項目-統一緩存刷新機制及統一zk命令發布監控模式
在分布式架構中,對于要求性能更高、可用性更好的數據,緩存往往會設計成多級結構。如果有數據更新,需要考慮如何保證各個主機節點進程中緩存數據的一致性。為了保證緩存刷新的一致性,我們采用一種新的刷新模式,通過刷新頁面的方式發起緩存刷新請求。應用收到緩存刷新請求后,生成緩存刷新命令修修補補,并將命令寫入ZK節點。各個中心后端應用都有zookpper提供的API用于實時監控。當監控到ZK節點數據發生變化時,各個應用獲取節點命令,解析命令,并調用命令緩存刷新API,刷新本地應用節點進程內的緩存數據。
步驟3:基礎構建項目-根據用戶角色提供刷新接口
緩存操作涉及的角色有版本發布、故障運維人員、規范數據操作等,不同角色的操作習慣有所不同,為了使緩存管理功能更加強大,我們針對不同角色提供了個性化的刷新接口和邏輯。
1、對于運維或者數據操作人員,我們提供查看緩存數據的接口,可以通過key值進行刷新。
2、對于版本發布者,我們只需要提供表和字段對應的KV關系刷新接口即可。
步驟4:通用裝修-緩存可視化、緩存檢查、緩存操作日志
要解決緩存可視化問題網校頭條,必須將緩存內容以結構化的方式展現出來。在業務系統中,我們緩存的數據可能是單一的KV映射值,也可能是復雜的業務對象數據。因此,為了給運維人員提供可視化的展現,我們需要在內部對key和value進行封裝,然后提供給運維人員。以某產品的配置數據緩存結構為例,其結構是由不同的分表緩存對象構成的。
完成結構化的梳理后,增加頁面緩存數據的結構化展示,使得結果更加清晰直觀。
在完成緩存刷新動作之后,無法檢查操作是否成功,以及緩存的數據狀態。為了解決這個問題,還需要一個可視化的檢查功能。操作完成后可以在頁面發起請求,后端根據key值循環調用各個應用節點獲取key對應的緩存值進行審計,對比本地緩存是否與數據庫一致,標記數據不一致的應用節點,同時組裝本地緩存對象的數據值。
將檢測結果可視化,并對比差異數據,效果如下圖所示:
檢查
數據差異對比
05 微調完善-改善緩存引擎的使用
舊房裝修完成后,基本已經達到入住標準,但業主在裝修前保留的家具等物品需要妥善整理擺放,才能入住。俗話說“三分雕琢,七分打磨”,在完成主要功能的優化重構后,常用的核心功能也需要細化打磨,提高緩存使用效率:
原子能力細化與封裝
對于部分緩存的API進行了原子性的封裝,并針對每個API給出了詳細的描述,以保證其優秀性、規范性,也為后續研發人員提供了方便。
緩存補償與緩存攔截機制
為了防止系統產生臟數據,需要對異常數據進行防范和清洗。對于緩存數據缺失值修修補補,需要有補償機制;對于異常值,增加緩存校驗攔截機制。
獨創功能-灰度制作緩存無縫切換
CRM灰度環境的應用,可以讓部分用戶進行版本升級內測,很大程度上規避了因為版本問題導致生產失敗的風險。在架構設計時,對灰度和生產環境的緩存做了隔離。但是這樣的做法也帶來一些問題,當灰度驗證的業務數據沒有及時完成,灰度切換到生產環境后,生產中無法讀取原有的灰度業務數據。因此我們改造了應用的讀取策略,將一套實例數據(用戶、訂單、費用等)緩存與生產和灰度共享,這樣灰度環境中的訂單在生產環境中也能查詢和續費。系統切換后,用戶無需重新下單驗收,實現了灰度和生產環境的無縫切換。
06 客戶評價
不同時期的業務對系統性能的要求不同,在性能要求不滿足時對系統設計的要求也不同。解釋起來有點困難,但總之,系統在不斷支持和演進的過程中,會遇到前期設計不足、不完善導致的問題。解決此類問題,可以謹慎,只治不好的地方;也可以大刀闊斧,一路砍掉。對于這種不治之癥就會一直縈繞在病床上的問題,修修補補可以暫時緩解,但果斷重構才是負責任的表現。