根據二八定律,尋找什么是必須優化的,什么是可以不優化的,使用一些工具,比如火焰圖,
根據奧姆剃須刀原理,分離核心業務和非核心業務,把必須做的做到最好,把低回報業務降低優先級,甚至砍掉,
洗掉冗余的代碼邏輯、空閑時重構,提高復用度,核心目的是減少無用的資料拷貝,優化資料結構,優化資料型別,比如SQL和索引的優化,本質是資料型別、資料結構和資料拷貝的優化,能使用整型的就不使用字串,
避免過早優化,時刻考慮對全域的影響而非區域過早優化,增量更改,做好回滾的準備,并在性能和可讀性之間進行tradeoff,
計算和存盤相互分離,并尋找二者的結合點/平衡點,優先優化存盤IO,使用連接池進行連接復用,合并sql邏輯來減少IO次數,修改業務邏輯,減少單次IO資料量,
快取策略,最常用的優化利器,根據動靜分離原則分出最好是讀多寫少,甚至是不寫的昂貴資料,并且資料量盡可能少,盡量使用CPU快取,行程內本地快取,或者分布式快取,或者作業系統檔案頁快取,比如對于dockerfile撰寫,每一行都是一個鏡像層,不可變的盡量靠前,命中快取,
批量處理,對于大資料量進行批量整合,利用空間/時間局域性原理,一次進行CPU運算/IO/記憶體拷貝,提高CPU/記憶體/磁盤快取命中率,比如對性能敏感的服務介面,必須提供批量介面,
流處理,對于大量連續資料,使用分批/分頁獲取,或者完全的流式讀寫/計算,打散請求時間,避免巨大的耗資源請求導致一瞬間CPU/記憶體/網路占用飆高,避免大物件導致FullGC停頓,
異步處理,對于同步呼叫在一定時間無法解決的,拆分為異步呼叫,異步的目的是減少同步等待時間/更好地利用執行緒池/連接池等池化技術,
池化策略,池化資源往往是需要預加載/預分配/預熱,提高資源復用度,常見的包括連接池、行程/執行緒/協程池、連接池、物件池、記憶體池、機器池,通過調參和自定義擴展資源池行為,調整資源數量/任務佇列大小/資源回收時間進行優化,
隨機打散策略,提高時間分攤均勻度,比如定時任務,需要進行隨機打散策略,避免CPU毛刺導致的長尾延遲,快取設定隨機時間淘汰,避免雪崩,
緩沖區,對于同步阻塞IO,使用緩沖區、雙緩沖區、零拷貝、記憶體池等策略,將IO轉化為非阻塞/異步,減少阻塞時間,
鎖粒度,降低鎖粒度,即減少臨界區代碼的運行時間,而且鎖盡量用輕量級鎖,能使用版本號/時間戳比如MVCC,就不用鎖進行并發控制,能用執行緒鎖就不用行程鎖,能用行程鎖就不用檔案鎖,更不用分布式鎖,更不用定時輪詢,
訊息傳輸,系統/模塊之間傳遞訊息,要使用訊息佇列承接壓力,并做好持久化,消費要考慮背壓,盡量使用客戶端拉取模式,而非服務端推送模式,如果不得不使用服務端推送,則要考慮客戶端和服務端二者的壓力,
請求合并,對短時間高并發的同一請求進行合并,使用異步佇列定量/定時完成對下游服務的批量介面呼叫,優點是降低下游服務壓力,增加吞吐量,缺點是回應時間取決于單次呼叫時長和定時時長,
重試策略,rest介面必須可重試,必須對部分/階段性失敗的請求進行重試,降低整體流程中斷后恢復的時間,重試方法可以使用退避演算法、把失敗訊息放入本地訊息表,已成功/未成功資料在記憶體中快取等等,
請求對沖,對已失敗的請求進行取消和重試,降低長尾延遲,
預處理策略,對于有順序的讀寫資料項串列/資料流,可使用預加載策略,結合業務流程進行優化,提高多個作業流并行度,減少虛席以待的業務等待時間,
對于讀寫檔案,盡量使用順序IO而非隨機IO,可以命中作業系統預讀/快取/回寫,比如WAL資料庫預寫日志,ext3日志檔案系統,kafka訊息寫segment檔案,
延遲策略,通過延遲減少操作次數,比如對齊并寫入socket緩沖區延遲網卡訪問,去掉volatile改用uunsafe+unlock延遲寫回主存,資料庫延遲鎖定提高并發度,寫時拷貝降低Linux行程創建開銷,
空間換時間,將時間復雜度轉換為空間復雜度,使用記憶體占用等換取計算耗時,比如資料庫設計中的反范式,還有哈希表,布隆過濾器,
拆分策略,類似MapReduce思想拆分大任務,使得任務可通過多執行緒/多實體并發處理,要注意基于計算和存盤的親和性,將任務拆分和合并的開銷最小化,避免類似分庫分表中產生的笛卡爾積,比如Numa架構下的CPU系結,
合并策略,和MapReduce相反,尋找正確的拆合點,對于不適合并發的邏輯,能使用for回圈合并在一個執行緒/實體解決的任務,盡量不拆分到多個執行緒/實體,相關的還有批處理策略,時空局域性原理,降低CPU背景關系切換/IO等開銷,
指標思想,使用資料物體的參考,而非資料物體本身,這會極大地降低資源開銷,比如軟連接而不是拷貝檔案,物件淺拷貝而不是深拷貝,表欄位存盤檔案路徑而非檔案內容,還有資料庫的覆寫索引避免了回表,
增量原則,根據偏移量增量而非全量獲取資料,比如多人更新同一份代碼,
獨立原則,每個任務/請求,盡量要享有自己的資源(記憶體,CPU,磁盤,網卡,暫存器)
無狀態原則,服務狀態上浮到用戶界面,或者下沉到資料庫,避免服務內維護資料狀態,目的是提高橫向擴展能力,類似的比如,介面無狀態,提高介面可重試/冪等性/組合復用能力,
分離原則,比如cache按照資料和指令分離,由dcache,icache,比如冷熱資料分離,不變化的分層沉淀并相對固定,讓經常變換的資料改動不影響固定的靜態資料,
外推原則,架構應盡可能簡單,控制橫向拆分的服務層數,服務呼叫鏈盡量短,把用戶需要的資源盡可能推送到用戶側,比如可以借助前端快取以及CDN加速,減少鏈路開銷,
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/283215.html
標籤:其他
上一篇:一個自動化專案的思考總結
下一篇:Nginx基本簡介
