關於效能優化的一些實踐
背景
在海量併發業務的場景下,比如電商搶購、微信紅包這樣的場景下,我們經常會遇到各種各樣的效能問題,在應對這些問題的時候,應該有怎樣的方法論去指導我們解決問題,基於這幾年的開發經驗,做一個簡單的分享。效能優化包含兩個方面的理解:
業務層面的效能優化
框架層面的效能優化
在比較大的網際網路公司中,一般不會直接使用開源的框架做業務開發,這裡就涉及到框架的效能問題,一般的框架都需要解決幾個問題
鎖的粒度,在高併發的請求處理中,都需要解決輸入輸出佇列的鎖的問題,這是一個演化的過程,從古老的檔案鎖,到現在的無鎖迴圈佇列,對框架的處理效能是有質的飛躍
排程的粒度,在TX,比較老的框架,其實一開始都是多程式的框架,後面才慢慢有了多執行緒,以及後面的微執行緒的框架,越來越小的排程代價,減少核心態和使用者態的切換,能夠有效的帶來效能的收益。
拷貝的次數,一個請求,從請求進入之後,經歷過幾個流程的處理,經歷了幾次的記憶體拷貝,對整個框架的效能也有比較大的影響
技術手段
不過,本文不討論框架層面的效能優化,更多的是介紹業務層面的相關技術手段
前端保護後端
業務流程解耦(非同步化)
資料庫分庫分表
柔性可用,可降級
Set化部署
以上技術手段在MY微信紅包中的具體實現
1.前端保護後端
在高併發的場景中,瞬間的併發量是非常大的,因此請求應該呈現一個漏斗型往下遞減
所以,我們在前端CGI層利用快取(如redis、memcache等)做了一些優化,比如在搶紅包的場景中,用redis儲存紅包剩下的個數,每個人是否搶過這個紅包這些標識, 儘量只讓真正可以搶紅包的請求通過CGI層落入邏輯層,快速的過濾掉不合理的請求。
在前端,我們一般用CDN(或者類似的資料靠近服務)做前端頁面的加速;
接入層作為後端的第一個模組,接收最多的請求,一般的優化方式有合併請求,資料預載入等,在雲監控的場景中,前端接入層需要接收大量的資料點,需要遮蔽無效的資料點,這裡就會有資料預載入的請求,將接入的資訊(變更頻率很低)預載入到記憶體中,請求進來之後根據記憶體中的預儲存資料做資料的過濾。
2.業務流程解耦
在業務開發過程中,我們經常會遇到耗時的場景,比如在搶紅包入賬的場景中,入賬的操作是一個事務,耗時比較長,放在核心流程中,會影響整體的吞吐量,或者是在監控資料上報的場景中,後續的資料梳理和告警判斷都是很重的業務邏輯,這就需要我們去解耦這個流程,利用訊息佇列對這個入賬的流程或者其他的處理流程進行解耦,保證併發量 ,如下圖,是筆者最近開發的事件中心架構,就用到CKafka做業務的解耦
事件中心架構
3. 資料庫分庫分表
分庫分表作為一個比較老的手段,依然是很有效的增加併發能力的方法(因為我們很多不經意的查詢或者更新都會導致鎖表)。例如在紅包的根據紅包ID,將紅包落入不同的表中,這樣在搶紅包的場景中,DB的鎖的壓力就分散到各個表中,這裡如何做分表是調優的關鍵,核心思想就是均勻的分配資料。
本身如何均勻的做資料分配也是一個比較難的問題,我們在監控資料的儲存中,也會遇到這樣的問題,監控的資料一般會用KV儲存,基於LSM的HBASE和在這個基礎上做了優化opentsdb是比較主流的選擇,opentsdb不僅針對時序資料的特點做了優化,同時,針對rowKey的生成方式也做了比較多的改進,避免資料分佈不均導致資料熱點的產生,這裡不展開討論。
4. 柔性可用,過載保護可降級
在資料層發生災難、系統負載高的情況下,保證業務的最核心流程可用,犧牲一些使用者體驗來達到系統的穩定。例如對搶紅包的返回結果進行降級,不返回紅包列表等,只讓使用者看到自己搶的紅包的結果。
基於業務優先順序的過載保護
5. Set化部署
以最近參與的雲監控專案為例,騰訊雲現在的地域非常廣,最新的地域現在在俄羅斯(歡迎試用),海外地域到國內的資料延遲一般在300ms以上,這就要求我們在所有地域都有Set去做就近接入,減少因為網路延遲帶來的影響,雲監控現在在每個地域都是單獨部署,只有告警傳送模組等少量服務是集中部署的
set化部署
結論
工作接近五年,前面的三年多的時間一直從事的是2C產品的開發,經歷過苦哈哈的計算記憶體空間的時候,因為2C的資料體量遠比2B的產品要大,TX以前的A/B/C的伺服器效能也一般(從現在看來),在這種場景下成長起來的程式設計師都會比較摳門,更多的去想如何節省機器,當然現在我覺得也是有一定參考價值的,希望對你有用
公眾號推薦:
相關文章
- 基於 PageSpeed 的效能優化實踐優化
- 關於 es 資料同步的一次效能優化實踐優化
- TiDB 效能分析&效能調優&優化實踐大全TiDB優化
- 效能優化,實踐淺談優化
- Canvas 動畫的效能優化實踐Canvas動畫優化
- 前端效能優化原理與實踐前端優化
- ⚠️Flutter 效能優化實踐 總結⚠️Flutter優化
- FlutterWeb效能優化探索與實踐FlutterWeb優化
- Flutter效能優化實踐之TimelineFlutter優化
- 2022 前端效能優化最佳實踐前端優化
- 關於C# Span的一些實踐C#
- 讀小程式效能優優化實踐-筆記優化筆記
- HybridDBforPostgreSQL,Greenplum寫入效能優化實踐SQL優化
- Vue 專案效能優化 — 實踐指南Vue優化
- HBase最佳實踐-讀效能優化策略優化
- 陪玩原始碼介面效能優化,需要你掌握的關於呼叫的一些事原始碼優化
- 效能優化之關於畫素管道及優化(二)優化
- 小程式效能優化的幾點實踐技巧優化
- 聊聊關於效能優化和其他(一)優化
- TiDB 效能分析&效能調優&最佳化實踐大全TiDB
- 關於 React 效能最佳化和數棧產品中的實踐React
- 基於XDanmuku的Android效能優化實戰Android優化
- AndroidAPP效能優化的一些思考AndroidAPP優化
- ASP.NET Core 效能優化最佳實踐ASP.NET優化
- 記一次介面效能優化實踐總結:優化介面效能的八個建議優化
- 【效能優化實踐】優化打包策略提升頁面載入速度優化
- android 關於記憶體優化的一些總結Android記憶體優化
- 關於Java健壯性的一些思考與實踐!Java
- Tree-Shaking效能優化實踐 – 原理篇優化
- Redis大叢集擴容效能優化實踐Redis優化
- Hive常用效能優化方法實踐全面總結Hive優化
- 深析filemap.js——關於JS的演算法及優化的實踐JS演算法優化
- 前端效能優化實踐 之 百度App個人主頁優化前端優化APP
- Android效能優化,Startalk會話頁GIF記憶體優化實踐Android優化會話記憶體
- 基於mysql資料庫 關於sql優化的一些問題MySql資料庫優化
- 關於mysql的優化MySql優化
- 關於GC原理和效能調優實踐,看這一篇就夠了!GC
- 有關效能優化的感悟.2021優化