應用效能設計的聖盃:讀寫擴散的概念與實踐
來源:阿里雲開發者
阿里妹導讀
概念的三層理解
基本理解: 經典讀寫擴散案例
方案一:往每個群員的收件箱中發一個訊息,這樣雖然要寫很多冗餘的資料,但是當每個群員閱讀訊息時,效能會好很多(因為只需要查詢自己的收件箱)。所謂 "寫擴散"; 方案二: 只往群聊中寫一條資料,每個群員都去群聊中拉取最新訊息,此時沒有資料冗餘,寫效能非常好,但是讀卻很容易產生熱點. 所謂 "讀擴散";
資料庫的規範化和反規範化: 日常開發中的讀寫擴散
在 MongoDB 中, "集合" 相當於一張 "表", "文件" 相當於表中的 "一行"
{ // 購物車記錄主鍵 "id": "123456", // 購物車中的商品冗餘資訊 "product": { "name": "康師傅泡麵", // 商品圖片 "pic": "商品價格 "price": 2 }, // 商品數量 "num": 10}
查詢驅動(query-driven)這個詞我最早是在 no sql 資料庫 Cassandra 的 官方文件 [參考1] 中讀到的, 這個詞簡潔地闡釋了所有 no sql 資料庫建模的本質。
上圖參考自 《HBase實戰》的第四章
應用的讀寫路徑: 不存在絕對的讀寫擴散
讀寫路徑的觀點參考自 《資料密集型應用系統設計》 釘釘考勤的案例參考自 @樂徐 的文件
寫擴散的使用場景
Twitter: 透過寫擴散分散讀熱點
該案例參考自 《HBase實戰》
Twitter 在很長的時間裡嚴格限制了推文的長度, 最多隻允許 140 個字元,所以每條推文都不大;
刷 Twitter 的使用者對延遲不太敏感,系統可以根據自己當前的水位,逐步將推文推送下去;
釘釘審批首頁: 查詢維度過於複雜, 分頁不好設計
員工本人是否有可見許可權;
員工所處的部門是否可見;
員工在企業中的角色是否可見;
審批單是否是特殊的 "業務審批單",一些特殊的 "業務審批單" 在首頁對所有員工不可見,只有在特定釘釘應用才會展示;
List result = new ArrayList();List 所有審批單 = 查詢企業所有審批單();for (審批單 : 所有審批單) { if (判斷審批單對使用者是否可見(使用者ID, 審批單)) { result.add(審批單); }}return result;
可以看出讀路徑非常複雜,需要逐個審批單按照各種維度進行過濾,是典型的 "讀擴散" 方案。當企業模板數量非常多時,首頁的載入時間就會特別長,所以我們限制了企業的審批單模板數量不能超過 1000 個,對大企業非常不友好。
審批首頁的案例參考自 @發靨 的文件
釘釘工作臺: 透過推送削峰填谷,降低伺服器壓力
工作臺的案例參考自 @北集 的文件
審批單搜尋: 業務功能需要特殊的儲存引擎實現
寫擴散的缺陷治理
實時性差
首先使用者寫的資料大多不是給自己看,比如推文是給粉絲看的,使用者很難發覺其中的延遲;
其次,即使寫入的資料是給自己看的,也可以在使用者提交完資料後,給使用者一個完成頁面,一定要使用者手動點選退出,才能看到自己寫入的資料。比如每次在淘寶提交訂單後,都會彈出一個 "訂單已完成" 頁面,要先點選退出,才能看到訂單列表;
資料一致性
資料對賬
定期全量重新整理,糾正增量鏈路中可能存在的無法核對的錯誤
冗餘資料無法寫入時(比如資料來源故障),記錄錯誤日誌,並實時同步到 odps,等到資料來源恢復後根據日誌再重新同步。
無效資料過多
上文中的釘釘審批首頁案例,我們可以做好使用者分層。對於審批單模板數量較小的企業,還是採用讀擴散,只有在審批單資料達到一定規模後,才觸發寫擴散的方案。"寫擴散" 就變成了一個針對大客戶的 "高階服務方案",甚至可以引導使用者付費購買超額的模板數量。
釘釘影片號中的大 V 擁有幾十萬的粉絲,大 V 一旦發一條影片,系統就需要在所有粉絲收件箱中推送這條記錄,造成了巨大的延遲和系統壓力。一個最佳化方案是,只給高活使用者收件箱進行推送(寫擴散),普通使用者等在下一次訪問時,才即時構建收件箱(讀擴散),這樣就能大大減少寫入的無效資料。
釘釘影片號的案例參考自 @定理 的文件
從讀寫擴散看業務發展的三階段
第一階段:業務剛剛啟動,還處於探索與試錯期。應用傾向於使用讀擴散方案快速迭代試錯。
第二階段:業務已經確定可行,很快就進入了快速規模增長期。之前快速迭代留下的坑,都隨著規模增長一一暴露。之前讀擴散的方案已經很難滿足業務要求,架構治理迫在眉睫,開發者們就會使用各種寫擴散的技術最佳化效能,以支援快速增長的規模。
第三階段:業務的規模已經達到天花板,進入 業務瓶頸期。之前因為規模和營收還在快速增長,所以寫擴散帶來的儲存成本,看起來沒什麼。但是到了業務瓶頸期,寫擴散帶來的成本,已經沒法帶來相應的規模增長了。此時很多開發者們的 OKR 都會變成 “降成本”, 讀擴散的方案因為儲存成本低,在很多場景又會被重新提出,最終變成 “讀寫混合” 的方案。
上圖只是對於一個成功業務的一般情況,現實情況會更加複雜,可能有很多業務在探索期就死了,或者有的業務瓶頸不高,即使在瓶頸期,也可以透過讀擴散和加機器硬撐下去。
參考資料:
[參考1] : Cassandra 資料庫官方文件:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70024924/viewspace-2993264/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Spring AOP:面向切面程式設計的核心概念與實際應用Spring程式設計
- Kubernetes 叢集和應用監控方案的設計與實踐
- framebuffer應用程式設計實踐程式設計
- 讀軟體開發安全之道:概念、設計與實施16安全開發最佳實踐
- 沒有杯子的世界:OOP設計思想的應用實踐OOP
- Unity應用架構設計(12)——AOP思想的實踐Unity應用架構
- 深度學習的應用與實踐深度學習
- 大型系統應用邊界設計原則與實踐
- Contravariance 概念在計算機程式設計中的應用計算機程式設計
- KubeSphere 助力提升研發效能的應用實踐分享
- 讀軟體開發安全之道:概念、設計與實施09安全設計
- 《遙感雲端計算與科學分析——應用與實踐》閱讀記錄
- Flink在美團的實踐與應用
- IRITA HUB的跨鏈實踐與應用
- BIGO 的資料管理與應用實踐Go
- 讀構建可擴充套件分散式系統:方法與實踐05分散式快取套件分散式快取
- BFC的概念與應用場景
- 讀軟體設計的要素01概念
- CSS Grid實現聖盃佈局CSS
- HarmonyOS:應用效能最佳化實踐
- mysql讀寫分離的最佳實踐MySql
- 系統設計概念:生產 Web 應用的架構Web架構
- 資料結構:用例項分析ArrayList與LinkedList的讀寫效能資料結構
- 讀軟體設計的要素02概念的目的
- 讀軟體設計的要素05概念的特性
- Web應用隱形後門的設計與實現Web
- 微前端的設計理念與實踐初探前端
- 稀疏陣列、佇列的概念與實踐陣列佇列
- Embedding技術與應用(3):Embeddings技術的實踐應用
- 《探索Python Requests中的代理應用與實踐》Python
- Flink 在中泰證券的實踐與應用
- Apache Flink 在鬥魚的應用與實踐Apache
- 淺談分散式 ID 的實踐與應用分散式
- 讀軟體開發安全之道:概念、設計與實施12不受信任的輸入
- 讀軟體開發安全之道:概念、設計與實施10安全設計審查
- union 的概念及在嵌入式程式設計中的應用程式設計
- ZooKeeper概念與應用
- 軟體效能測試分析與調優實踐之路-Java應用程式的效能分析與調優-手稿節選Java