IO Optimization

磁盤 I/O 優化:css

性能檢測前端

而磁盤 I/O 一般都很耗時,咱們要判斷 I/O 是不是一個瓶頸,咱們有一些參數指標能夠參考:ios

如咱們能夠壓力測試應用程序看系統的 I/O wait 指標是否正常,例如測試機器有 4 個 CPU,那麼理想的 I/O wait 參數不該該超過 25%,若是超過 25% 的話,I/O 極可能成爲應用程序的性能瓶頸。Linux 操做系統下能夠經過 iostat 命令查看。一般咱們在判斷 I/O 性能時還會看另一個參數就是 IOPS,咱們應用程序須要最低的 IOPS 是多少,而咱們的磁盤的 IOPS 能不能達到咱們的要求。每一個磁盤的 IOPS 一般是在一個範圍內,這和存儲在磁盤的數據塊的大小和訪問方式也有關。可是主要是由磁盤的轉速決定的,磁盤的轉速越高磁盤的 IOPS 也越高。數據庫

如今爲了提升磁盤 I/O 的性能,一般採用一種叫 RAID 的技術,就是將不一樣的磁盤組合起來來提升 I/O 性能,目前有多種 RAID 技術,每種 RAID 技術對 I/O 性能提高會有不一樣,能夠用一個 RAID 因子來表明,磁盤的讀寫吞吐量能夠經過 iostat 命令來獲取,因而咱們能夠計算出一個理論的 IOPS 值,計算公式以下因此:( 磁盤數 * 每塊磁盤的 IOPS)/( 磁盤讀的吞吐量 +RAID 因子 * 磁盤寫的吞吐量 )=IOPS後端

提高 I/O 性能瀏覽器

  1. 增長緩存,減小磁盤訪問次數
  2. 優化磁盤的管理系統,設計最優的磁盤訪問策略,以及磁盤的尋址策略,這裏是在底層操做系統層面考慮的。
  3. 設計合理的磁盤存儲數據塊,以及訪問這些數據塊的策略,這裏是在應用層面考慮的。如咱們能夠給存放的數據設計索引,經過尋址索引來加快和減小磁盤的訪問,還有能夠採用異步和非阻塞的方式加快磁盤的訪問效率。
  4. 應用合理的 RAID 策略提高磁盤 IO,每種 RAID 的區別咱們能夠用下表所示:

 

磁盤陣列 說明 
RAID 0   數據被平均寫到多個磁盤陣列中,寫數據和讀數據都是並行的,因此磁盤的 IOPS 能夠提升一倍。
RAID 1  RAID 1 的主要做用是可以提升數據的安全性,它將一份數據分別複製到多個磁盤陣列中。並不能提高 IOPS 可是相同的數據有多個備份。一般用於對數據安全性較高的場合中。
RAID 5  這中設計方式是前兩種的折中方式,它將數據平均寫到全部磁盤陣列總數減一的磁盤中,往另一個磁盤中寫入這份數據的奇偶校驗信息。若是其中一個磁盤損壞,能夠經過其它磁盤的數據和這個數據的奇偶校驗信息來恢復這份數據。
RAID 0+1  如名字同樣,就是根據數據的備份狀況進行分組,一份數據同時寫到多個備份磁盤分組中,同時多個分組也會並行讀寫。

 

網絡 I/O 優化:緩存

  1. 一個是減小網絡交互的次數:要減小網絡交互的次數一般咱們在須要網絡交互的兩端會設置緩存,好比 Oracle 的 JDBC 驅動程序,就提供了對查詢的 SQL 結果的緩存,在客戶端和數據庫端都有,能夠有效的減小對數據庫的訪問。關於 Oracle JDBC 的內存管理能夠參考《 Oracle JDBC 內存管理》。除了設置緩存還有一個辦法是,合併訪問請求:如在查詢數據庫時,咱們要查 10 個 id,我能夠每次查一個 id,也能夠一次查 10 個 id。再好比在訪問一個頁面時經過會有多個 js 或 css 的文件,咱們能夠將多個 js 文件合併在一個 HTTP 連接中,每一個文件用逗號隔開,而後發送到後端 Web 服務器根據這個 URL 連接,再拆分出各個文件,而後打包再一併發回給前端瀏覽器。這些都是經常使用的減小網絡 I/O 的辦法。
  2. 減小網絡傳輸數據量的大小:減小網絡數據量的辦法一般是將數據壓縮後再傳輸,如 HTTP 請求中,一般 Web 服務器將請求的 Web 頁面 gzip 壓縮後在傳輸給瀏覽器。還有就是經過設計簡單的協議,儘可能經過讀取協議頭來獲取有用的價值信息。好比在代理程序設計時,有 4 層代理和 7 層代理都是來儘可能避免要讀取整個通訊數據來取得須要的信息。
  3. 儘可能減小編碼:一般在網絡 I/O 中數據傳輸都是以字節形式的,也就是一般要序列化。可是咱們發送要傳輸的數據都是字符形式的,從字符到字節必須編碼。可是這個編碼過程是比較耗時的,因此在要通過網絡 I/O 傳輸時,儘可能直接以字節形式發送。也就是儘可能提早將字符轉化爲字節,或者減小字符到字節的轉化過程。
  4. 根據應用場景設計合適的交互方式:所謂的交互場景主要包括同步與異步阻塞與非阻塞方式,下面將詳細介紹。

同步與異步安全

所謂同步就是一個任務的完成須要依賴另一個任務時,只有等待被依賴的任務完成後,依賴的任務才能算完成,這是一種可靠的任務序列。要麼成功都成功,失敗都失敗,兩個任務的狀態能夠保持一致。而異步是不須要等待被依賴的任務完成,只是通知被依賴的任務要完成什麼工做,依賴的任務也當即執行,只要本身完成了整個任務就算完成了。至於被依賴的任務最終是否真正完成,依賴它的任務沒法肯定,因此它是不可靠的任務序列。咱們能夠用打電話和發短信來很好的比喻同步與異步操做。服務器

在設計到 IO 處理時一般都會遇到一個是同步仍是異步的處理方式的選擇問題。由於同步與異步的 I/O 處理方式對調用者的影響很大,在數據庫產品中都會遇到這個問題。由於 I/O 操做一般是一個很是耗時的操做,在一個任務序列中 I/O 一般都是性能瓶頸。可是同步與異步的處理方式對程序的可靠性影響很是大,同步可以保證程序的可靠性,而異步能夠提高程序的性能,必須在可靠性和性能之間作個平衡,沒有完美的解決辦法。網絡

阻塞與非阻塞

阻塞與非阻塞主要是從 CPU 的消耗上來講的,阻塞就是 CPU 停下來等待一個慢的操做完成 CPU 才接着完成其它的事。非阻塞就是在這個慢的操做在執行時 CPU 去幹其它別的事,等這個慢的操做完成時,CPU 再接着完成後續的操做。雖然表面上看非阻塞的方式能夠明顯的提升 CPU 的利用率,可是也帶了另一種後果就是系統的線程切換增長。增長的 CPU 使用時間能不能補償系統的切換成本須要好好評估。

兩種的方式的組合

 

組合方式 性能分析
同步阻塞  最經常使用的一種用法,使用也是最簡單的,可是 I/O 性能通常不好,CPU 大部分在空閒狀態。
同步非阻塞  提高 I/O 性能的經常使用手段,就是將 I/O 的阻塞改爲非阻塞方式,尤爲在網絡 I/O 是長鏈接,同時傳輸數據也不是不少的狀況下,提高性能很是有效。這種方式一般能提高 I/O 性能,可是會增長 CPU 消耗,要考慮增長的 I/O 性能能不能補償 CPU 的消耗,也就是系統的瓶頸是在 I/O 仍是在 CPU 上。
異步阻塞 這種方式在分佈式數據庫中常常用到,例如在往一個分佈式數據庫中寫一條記錄,一般會有一份是同步阻塞的記錄,而還有兩至三份是備份記錄會寫到其它機器上,這些備份記錄一般都是採用異步阻塞的方式寫 I/O。異步阻塞對網絡 I/O 可以提高效率,尤爲像上面這種同時寫多份相同數據的狀況。
異步非阻塞 這種組合方式用起來比較複雜,只有在一些很是複雜的分佈式狀況下使用,像集羣之間的消息同步機制通常用這種 I/O 組合方式。如 Cassandra 的 Gossip 通訊機制就是採用異步非阻塞的方式。它適合同時要傳多份相同的數據到集羣中不一樣的機器,同時數據的傳輸量雖然不大,可是卻很是頻繁。這種網絡 I/O 用這個方式性能能達到最高。

   

雖然異步和非阻塞可以提高 I/O 的性能,可是也會帶來一些額外的性能成本,例如會增長線程數量從而增長  CPU 的消耗,同時也會致使程序 設計的複雜度上升。若是設計的不合理的話反而會致使性能降低。在實際設計時要根據應用場景綜合評估一下。
相關文章
相關標籤/搜索