磁盤相關知識點入門

Ⅰ、磁盤的訪問模式

磁盤性能和磁盤的訪問模式有關linux

  • Sequential access
    算法

  • Random access
    數據庫

上面說的順序和隨機是邏輯上的,大多時候作不到徹底順序api

數據庫不是連續塊的申請空間,是一次申請固定塊大小的空間,在這一個塊裏面的數據是連續的緩存

Ⅱ、HDD VS SSD

隨機訪問的性能叫IOPS,順序訪問的性能叫吞吐率安全

2.1 簡單瞭解HDD

  • 機械磁盤,經過磁頭旋轉定位,單塊盤通常100IOPS
  • 數據庫的優化都是根據機械磁盤特性,隨機轉順序,經過磁頭旋轉進行數據定位
  • 常見轉速,筆記本5400r/min,臺式機7200r/min,服務器硬盤1w/min,1.5w/min
  • 順序訪問性能較好,100M/s/~200M/s,這叫磁盤吞吐率,也叫帶寬,能夠經過作raid來提高磁盤帶寬,能夠作到一兩個G
  • 隨機訪問性能較差,須要磁頭旋轉定位,IOPS較低

爲何數據庫比較多的是隨機訪問?
B+ tree索引定位數據是比較隨機的,因此數據庫最看重的就是隨機IO,也就是IOPS,順序的話一般就是掃描了,兩張表作join的話比的就是順序的性能,MySQL一般用在大併發,小事務的OLTP場景服務器

知道轉速,對應的IOPS也出來了
IOPS=轉速/60併發

帶寬怎麼轉換爲IOPS
每作一次io操做,io的大小是不必定的,好比4k的操做,一般廠商都給的數據都是4k大小的io,注意,MySQL中每一個IO的大小是16k,即每一個頁的大小,因此和廠商給的性能數據相比會有所降低dom

48M的寬帶算IOPS就是,1M/4k*48=12288函數

如何提高HDD的IOPS性能

  • 作raid
    • 功耗很是高
  • 經過購買共享存儲
    • 價格昂貴
    • 共享存儲,作高可用很方便,可是單點故障太坑爹,就像坐飛機,通常沒問題,出了問題基本上就是死

然而提高都是很是有限的

tips:
一般來講數據庫作raid10,性能和可靠性都要有保障

2.2 SSD

  • 固態硬盤,無磁頭,純電設備,控制器和閃存組成。單塊盤7~8wIOPS
  • 讀寫速度非對稱,通常來講寫比讀慢一半,高端ssd是對稱的,機械盤也是對稱的
  • 性能降低,之前的ssd用一段時間性能會急劇降低,如今基本解決了,強烈推薦英特爾的盤
  • 設備短命,性能抖動的問題如今也不用擔憂
  • 用MySQL必定要用SSD

SSD與數據庫優化
一、磁盤調度算法設置爲deadline或者noop,在ssd上,這個調整性能至少提高百分之七十,甚至多倍,如今CentOS7默認磁盤調度算法已是deadline了而不是cfq

cat /sys/block/vda/queue/scheduler
echo deadline > /sys/block/vda/queue/scheduler

上面這個能夠做一個模板,規定,HDD也因該這麼設置,只是性能提高沒這麼大

二、InnoDB參數調整

InnoDB存儲引擎參數設置
innodb_flush_neighbors = 0  -- 默認1,平緩刷新的,默認只刷髒頁,不會將髒頁所在的整個區刷新,把這個設爲0,重作日誌大小足夠大,數據庫測試時性能比較平穩,還有必定的提高
innodb_log_file_size = 4G   -- 默認128M,高端設備設置8G和16G都不爲過,MySQL5.5最大隻能設1.9G,無限接近於2G
innodb_io_capacity 設置爲存儲性能的一半

修改以後重啓,等待時間比較長,是數據庫在作擴展

上面兩個配置不對性能抖動比較厲害,設置後性能平穩且提高百分之15

三、SSD的選擇——PCIE or SATA/SAS?
SATA/SAS與PCIE的性能差距逐漸減少,PCIE快很是多,甚至達到50w,100wIOPS,沒什麼上限

PCIE的性能不多有應用能夠徹底使用,優先選擇SATA/SAS接口的SSD

數據庫的瓶頸已經不在磁盤上了

SSD品牌推薦:Intel、FusinIO、寶存

Ⅲ、磁盤調度算法介紹

3.1 CFQ

  • CFQ把I/O請求按照進程分別放入進程對應的隊列中,因此A進程和B進程發出的I/O請求會在兩個隊列中。而各個隊列內部仍然採用 合併和排序 的方法,區別僅在於,每個提交I/O請求的進程都有本身的I/O隊列
  • CFQ的「公平」是針對進程而言的,它以時間片算法爲前提,輪轉調度隊列,默認從當前隊列中取4個請求處理,而後處理下一個隊列的4個請求。這樣就能夠確保每一個進程享有的I/O資源是均衡的
  • CFQ的缺點是先來的IO請求不必定能被及時知足,可能出現飢餓的狀況

3.2 Deadline

  • 同CFQ同樣,除了維護一個擁有合併和排序功能的請求隊列之外,還額外維護了兩個隊列,分別是讀請求隊列和寫請求隊列 ,它們都是帶有超時的FIFO隊列,當新來一個I/O請求時,會被同時插入普通隊列和讀/寫隊列,而後處理普通隊列中的請求,當調度器發現讀/寫請求隊列中的請求超時的時候,會優先處理這些請求,保證儘量不產生請求飢餓
  • 在DeadLine算法中,每一個I/O請求都有一個超時時間,默認讀請求是500ms,寫請求是5s

3.3 Noop

  • Noop作的事情很是簡單,它不會對I/O請求排序也不會進行任何其它優化(除了合併),Noop除了對請求合併之外,再也不進行任何處理,直接以相似FIFO的順序提交I/O請求
  • Noop面向的不是普通的塊設備,而是隨機訪問設備(例如SSD),對於這種設備,不存在傳統的尋道時間,那麼就沒有必要去作那些多餘的爲了減小尋道時間而採起的事情了

Ⅳ、存儲結構對應關係

+-------------+-------------+-------------+
 Database  |     16K     |      16K    |     16K     |
           +------+------+-------------+-------------+
                  |
+------------------------------------------------------------------------+
                  |
                  +------+
                         |
           +------+------v------+------+
Filesystem |  4K  |  4K  |  4K  |  4K  |
           +---+--+------+------+------+
               |
+------------------------------------------------------------------------+
               |
            +--+
            |
            v
      +------+------+         +------+
 Disk | 512B | 512B | ... ... | 512B |
      +------+------+         +------+

SSD扇區的大小通常爲4K或者8K,可是爲了兼容HDD,SSD經過Flash Translation Layer(FTL)的方式轉換成512B

4.1 一個參數——innodb_flush_method

  • fwrite:把數據寫入文件系統層(Filesystem)(可能有cache),並不能保證寫入Disk
  • fsync:保證把數據寫入到Disk(數據落盤)
  • O_DIRECT:系統直接將數據寫入磁盤,跳過文件系統的緩存,等同於使用裸設備的效果
+-------------------+               +-------------------+              +-------------------+
|                   |    fwrite     |                   | fsync        |                   |
|     Buffer Pool   +---------------> Filesystem Cache  +-------------->         Disk      |
|                   |               |                   |              |                   |
+--------+----------+               +-------------------+              +---------+---------+
         |                                                                       ^
         |                                                                       |
         |                                        innodb_flush_method = O_DIRECT |
         +-----------------------------------------------------------------------+

只經過fwrite寫入數據特別快(由於有緩存),但隨後調用fsync就會很慢,這個速度取決於磁盤的 IOPS

若是不手工執行fysnc,當Filesystem的cache小於10%時,操做系統纔會將數據刷入磁盤,因此可能存在數據丟失的風險,好比掉電

4.2 寫數據的過程

OS              pagecache(操做系統層的)
filesystem      一個塊一個塊,每一個塊大小4k
DISK            一個4k由8個扇區(sector)組成,一個sector大小512字節

fwrite/fread,最底層的system core中用fopen打開文件:f=fopen('ibdata',wb)

打開以後對應一個文件句柄f,對文件句柄f操做:fwrite(f,offset,data,len)

offset就是偏移量,data是寫入的數據,len是字節數

數據庫都是16k一個塊,對於數據庫來講,它的offset=16k*N
fwrite(f,0,xxx,16384);
fwrite(f,16384,xxx,16384);

寫就是覆蓋操做,若是追加在最後就是佔用空間,不會有碎片,數據庫裏會先申請空間所有填0,對於數據庫來講,offset大小確定和塊大小對齊,offset必然是塊大小的倍數

僅僅調用fwrite函數,表示數據只寫入到了pagecache(操做系統緩存中),並沒落地到磁盤,這時候服務器掛了,就有問題了,因此還要調用一個fsync函數刷新句柄,fsync表示直接刷新到磁盤

只經過fwrite寫入數據特別快(由於有緩存),但隨後調用fsync就會很慢,這個速度取決於磁盤的IOPS,若是不手工執行fysnc,當Filesystem的cache小於10%時,操做系統纔會將數據刷入磁盤,因此可能存在數據丟失的風險,好比掉電

4.3 寫的比較亂,作個小結

首先明確一點,無論走不走os緩存,對於數據庫來講fsync確定是要一直刷的

fsync非1的話,性能是會好一些,可是性能會有抖動(隔段時間刷新,或者設爲0的時候不主動fsync,os會控制這個刷新頻率),反正是不用嘛

linux內核2.4版本開始,api函數提供了一個叫o_direct函數,讓fwrite直接寫到磁盤而不通過pagecache,就是fopen的時候用o_direct參數

這種狀況比走os緩存性能稍微要有點差異,可是爲了保證數據庫的安全咱們確定仍是選擇直接刷到盤上,並且這個走os緩存性能好的一個緣由是用了額外的內存,咱們能夠把這部份內存分配給buffer pool

其實,若是不直接刷盤,對於數據庫來講多作了一次額外的緩存,bp+pagecahe,徹底不必

綜上所述:

innodb_flush_method = O_DIRECT

若是沒這個參數,一開始MySQL跑出來性能很是好,可是這確定是不對的

tips:
哪些寫入是o_direct,哪些是pagecache

  • 數據文件----o_direct
  • 日誌文件----pagecache,fsync,一個日誌文件可能很大,只有一個事務徹底提交才fsync一次,不用每次寫都fsync

4.4 另外一個參數——innodb_io_capacity

數據庫每秒寫入能用到的IOPS是多少

調整這個值,先觀察線上業務數據庫IOPS比例,而後測試用--file-rw-ratio 測出這個IOPS,一般來講設置爲整個IOPS的一半

有人說互聯網業務數據庫讀寫比是10:1,因此這個參數設置爲IOPS的十分之一,然而並非,咱們說的數據庫的讀寫比例,是指數據庫內部是10:1,不少操做被cache起來了,真實的發生在磁盤上的大多數讀寫比例是1:1,甚至不少場景寫比讀還多

如今寫設2w,讀用2w,單塊ssd就能達到了,設置很差就是花錢買冤枉

相關文章
相關標籤/搜索