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

lihong發表於2019-05-06

1. 效能測試

1.1. 效能指標

網站效能測試的主要指標有:

  • 響應時間 - 響應時間(RT)是指從客戶端發一個請求開始計時,到客戶端接收到從伺服器端返回的響應結果結束所經歷的時間,響應時間由請求傳送時間、網路傳輸時間和伺服器處理時間三部分組成。
  • 併發數 - 系統同時處理的請求、事務數。
  • 吞吐量 - TPS(每秒事務數)、HPS(每秒 HTTP 請求數)、QPS(每秒查詢數)。
  • 效能計數器 - 系統負載、物件與執行緒數、記憶體使用、CPU 使用、磁碟與網路 IO 等。這些指標也是系統監控的重要引數。

1.2. 效能測試方法

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

1.3. 效能測試報告

效能測試報告示例:

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

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. 分散式快取

網站效能優化第一定律:優先考慮使用快取優化效能。

快取原理

快取指將資料儲存在相對較高訪問速度的儲存介質中,以供系統處理。一方面快取訪問速度快,可以減少資料訪問的時間,另一方面如果快取的資料是經過計算處理得到的,那麼被快取的資料無需重複計算即可直接使用,因此快取還起到減少計算時間的作用。

快取的本質是一個記憶體 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 支援。

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

相關文章