大型網站背後的高性能系統架構設計

1. 性能測試

1.1. 性能指標

網站性能測試的主要指標有:前端

  • 響應時間 - 響應時間(RT)是指從客戶端發一個請求開始計時,到客戶端接收到從服務器端返回的響應結果結束所經歷的時間,響應時間由請求發送時間、網絡傳輸時間和服務器處理時間三部分組成。
  • 併發數 - 系統同時處理的請求、事務數。
  • 吞吐量 - TPS(每秒事務數)、HPS(每秒 HTTP 請求數)、QPS(每秒查詢數)。
  • 性能計數器 - 系統負載、對象與線程數、內存使用、CPU 使用、磁盤與網絡 IO 等。這些指標也是系統監控的重要參數。

1.2. 性能測試方法

  • 性能測試
  • 負載測試
  • 壓力測試
  • 穩定性測試

1.3. 性能測試報告

性能測試報告示例:sql

1.4. 性能優化策略

  1. 性能分析 - 若是請求響應慢,存在性能問題。須要對請求經歷的各個環節逐一分析,排查可能出現性能瓶頸的地方,定位問題。檢查監控數據,分析影響性能的主要因素:內存、磁盤、網絡、CPU,多是代碼或架構設計不合理,又或者是系統資源確實不足。
  2. 性能優化 - 性能優化根據網站分層架構,大體可分爲前端性能優化、應用服務性能優化、存儲服務性能優化。

2. 前端性能優化

2.1. 瀏覽器訪問優化

  1. 減小 HTTP 請求 - HTTP 請求須要創建通訊鏈路,進行數據傳輸,開銷高昂,因此減小 HTTP 請求數能夠有效提升訪問性能。減小 HTTP 的主要手段是合併 Css、JavaScript、圖片。
  2. 使用瀏覽器緩存 - 由於靜態資源文件更新頻率低,能夠緩存瀏覽器中以提升性能。設置 HTTP 頭中的 Cache-Control 和 Expires 屬性,能夠設定瀏覽器緩存。
  3. 啓用壓縮 - 在服務器端壓縮靜態資源文件,在瀏覽器端解壓縮,能夠有效減小傳輸的數據量。因爲文本文件壓縮率可達 80% 以上,因此能夠對靜態資源,如 Html、Css、JavaScrip 進行壓縮。
  4. CSS 放在頁面最上面,JavaScript 放在頁面最下面 - 瀏覽器會在下載徹底部的 Css 後纔對整個頁面進行渲染,因此最好的作法是將 Css 放在頁面最上面,讓瀏覽器儘快下載 Css;JavaScript 則相反,瀏覽器加載 JavaScript 後當即執行,可能會阻塞整個頁面,形成頁面顯示緩慢,所以 JavaScript 最好放在頁面最下面。
  5. 減小 Cookie 傳輸 - Cookie 包含在 HTTP 每次的請求和響應中,太大的 Cookie 會嚴重影響數據傳輸。

2.2. CDN

CDN 通常緩存的是靜態資源。數據庫

CDN 的本質仍然是一個緩存,並且將數據緩存在離用戶最近的地方,使用戶已最快速度獲取數據,即所謂網絡訪問第一跳。編程

2.3. 反向代理

傳統代理服務器位於瀏覽器一側,代理瀏覽器將 HTTP 請求發送到互聯網上,而反向代理服務器位於網站機房一側,代理網站服務器接收 HTTP 請求。瀏覽器

反向代理服務器能夠配置緩存功能加速 Web 請求,當用戶第一次訪問靜態內容時,靜態內容就會被緩存在反向代理服務器上。緩存

反向代理還能夠實現負載均衡,經過負載均衡構建的集羣能夠提升系統整體處理能力。安全

由於全部請求都必須先通過反向代理服務器,因此能夠屏蔽一些攻擊 IP,達到保護網站安全的做用。性能優化

3. 應用服務性能優化

3.1. 分佈式緩存

網站性能優化第必定律:優先考慮使用緩存優化性能。bash

緩存原理

緩存指將數據存儲在相對較高訪問速度的存儲介質中,以供系統處理。一方面緩存訪問速度快,能夠減小數據訪問的時間,另外一方面若是緩存的數據是通過計算處理獲得的,那麼被緩存的數據無需重複計算便可直接使用,所以緩存還起到減小計算時間的做用。服務器

緩存的本質是一個內存 HASH 表。

緩存主要用來存放那些讀寫比很高、不多變化的數據,如商品的類目信息,熱門詞的搜索列表信息、熱門商品信息等。

合理使用緩存

緩存數據的選擇:

  • 不要存儲頻繁修改的數據
  • 不要存儲非熱點數據

數據不一致和髒讀:

  • 緩存有有效期,因此存在必定時間的數據不一致和髒讀問題。若是不能接受,能夠考慮使用數據更新當即更新緩存策略

須要考慮緩存問題:緩存雪崩、緩存穿透、緩存預熱

3.2. 異步操做

異步處理通常是經過分佈式消息隊列的方式。

異步處理能夠解決一下問題:

  • 異步處理
  • 應用解耦
  • 流量削鋒
  • 日誌處理
  • 消息通信

3.3. 使用集羣

在高併發場景下,使用負載均衡技術爲一個應用構建一個由多臺服務器組成的服務器集羣,將併發訪問請求分發到多臺服務器上處理,避免單一服務器因負載壓力過大而響應緩慢,使用戶請求具備更好的響應延遲特性。

3.4. 代碼優化

多線程

從資源利用的角度看,使用多線程的緣由主要有兩個:IO 阻塞和多 CPU。

線程數並不是越多越好,那麼啓動多少線程合適呢?

有個參考公式:

啓動線程數 = (任務執行時間 / (任務執行時間 - IO 等待時間)) * CPU 內核數
複製代碼

最佳啓動線程數和 CPU 內核數成正比,和 IO 阻塞時間成反比。若是任務都是 CPU 計算型任務,那麼線程數最多不要超過 CPU 內核數,由於啓動再多線程,CPU 也來不及調度;相反若是是任務須要等待磁盤操做,網絡響應,那麼多啓動線程有助於任務並罰賭,提升系統吞吐量。

線程安全問題

  • 將對象設計爲無狀態對象
  • 使用局部對象
  • 併發訪問資源時使用鎖

資源複用

應該儘可能減小那些開銷很大的系統資源的建立和銷燬,如數據庫鏈接、網絡通訊鏈接、線程、複雜對象等。從編程角度,資源複用主要有兩種模式:單例模式和對象池。

數據結構

根據具體場景,選擇合適的數據結構。

垃圾回收

若是 Web 應用運行在 JVM 等具備垃圾回收功能的環境中,那麼垃圾回收可能會對系統的性能特性產生巨大影響。當即垃圾回收機制有助於程序優化和參數調優,以及編寫內存安全的代碼。

4. 存儲性能優化

4.1. 機械鍵盤和固態硬盤

考慮使用固態硬盤替代機械鍵盤,由於它的讀寫速度更快。

4.2. B+數和 LSM 樹

傳統關係數據庫的數據庫索引通常都使用兩級索引的 B+ 樹結構,樹的層次最多三層。所以可能須要 5 次磁盤訪問才能更新一條記錄(三次磁盤訪問得到數據索引及行 ID,而後再進行一次數據文件讀操做及一次數據文件寫操做)。

因爲磁盤訪問是隨機的,傳統機械鍵盤在數據隨機訪問時性能較差,每次數據訪問都須要屢次訪問磁盤影響數據訪問性能。

許多 Nosql 數據庫中的索引採用 LSM 樹做爲主要數據結構。LSM 樹可視爲一個 N 階合併樹。數據寫操做都在內存中進行。在 LSM 樹上進行一次數據更新不須要磁盤訪問,速度遠快於 B+ 樹。

4.3. RAID 和 HDFS

HDFS(分佈式文件系統) 更被大型網站所青睞。它能夠配合 MapReduce 併發計算任務框架進行大數據處理,能夠在整個集羣上併發訪問全部磁盤,無需 RAID 支持。

相關文章
相關標籤/搜索