1. 程式人生 > >22.Mysql磁盤I/O

22.Mysql磁盤I/O

基礎上 The 現象 -m 檢查 led 數據倉庫 等待時間 -h

22.磁盤I/O問題
磁盤IO是數據庫性能瓶頸,一般優化是通過減少或延緩磁盤讀寫來減輕磁盤IO的壓力及其對性能的影響。
增強磁盤讀寫性能和吞吐量也是重要的優化手段。

22.1 使用磁盤陣列
RAID(Redundant Array of Inexpensive Disk)是指廉價磁盤冗余陣列,即磁盤陣列。
RAID按照一定的策略將數據分布到若幹物理磁盤上,增加數據存儲的可靠性,提高數據的讀寫整體性能,實現了數據的並行讀寫。
22.1.1 常見RAID級別及其特性
根據數據分布和冗余方式,RAID分為不同的級別。
RAID 0:條帶化,按照一定的條帶大小將數據依次分布到各個磁盤,沒有數據冗余。優點:數據並發讀寫速度快,無額外磁盤開銷。缺點:數據無冗余,可靠性差。

RAID 1:磁盤鏡像,兩個磁盤一組,所有數據都同時寫入兩個磁盤,可以從任一磁盤讀取。優點:數據完全冗余,提高並發讀操作。缺點:磁盤有效容量只有總容量的一半。
RAID 10:RAID 0+RAID 1,先做磁盤鏡像再做條帶化,兼具RAID 1的可靠性和RAID 0的並發讀寫性能。優點:可靠性,並發讀寫性能優良。缺點:磁盤有效容量只有總容量的一半。
RAID 4:RAID 0+校驗糾錯,先做條帶化,額外增加一個磁盤做各個條帶的校驗糾錯數據。優點:一個磁盤損壞可以通過校驗糾錯數據計算出來,有一定的容錯能力,讀速度快。缺點:寫性能受影響。
RAID 5:改進RAID 4,將各個條帶的校驗糾錯數據也分別寫到各個磁盤中。優點:比RAID 4有更好的寫性能和數據保護能力。缺點:寫性能不及RAID 0、RAID 1、RAID 10,容錯能力不及RAID 1,出現壞盤時讀性能下降。
22.1.2 如何選擇RAID級別
數據庫 讀寫都很頻繁,可靠性要求高,選擇RAID 10;
數據倉庫 讀很頻繁,寫相對較少,可靠性有一定要求,選擇很RAID 5;
網站類 讀寫都很頻繁,可靠性要求不高,選擇RAID 0。

22.2 虛擬文件卷或軟RAID
Linux的虛擬文件卷或軟RIAD軟件支持模擬實現RAID,雖然性能上不如硬件RAID,但是比單個磁盤的性能和可靠性高。

22.3 使用Symbolic Links分布I/O
針對MyIASM存儲引擎可以將表、索引的數據分不到不同的磁盤,其它存儲引擎不支持。
先在目標磁盤上創建目錄
#mkdir /otherdisk/databases/test

再創建從Mysql數據目錄到目標目錄的軟連接
#ln -s /otherdisk/databases/test /path/to/datadir
將MyIASM存儲引擎的數據文件(.MYD)和索引文件(.MYI)指向其它的物理磁盤,表定義文件(.frm)不能指向其它磁盤。
>create table test(
id int primary key,
name varchar(20))
engine=myisam
data directory=‘/disk2/data‘
index directory=‘/disk3/index‘;

22.4 禁止操作系統更新文件的atime屬性
atime是一個文件屬性,讀文件時,操作系統會將當前時間更新到atime屬性上。
可以修改文件系統配置文件/etc/fstab來禁止更新文件的atime屬性,以減輕磁盤IO負擔。
LABLE=/home /home ext3 noatime 1 2
重新mount文件系統,即/home下的文件不會修改文件的atime屬性
#mount -oremount /home

22.5 用裸設備(Raw Device)存放InnoDB的共享表空間
InnoDB使用緩存機制存儲表和索引的數據,操作系統IO緩存對其性能沒有幫助,可以使用Raw Device存放InnoDB的共享表空間。
修改my.cnf,在innodb_data_file_path參數中增加裸設備文件名並指定neweaw屬性:
[mysqld]
innodb_data_file_path=/dev/hdd1:3Gnewraw;/dev/hdd2:2Gnewraw
啟動Mysql,使其完成初始化工作,然後關閉Mysql;
將innodb_data_file_path參數中的neweaw該成raw:
[mysqld]
innodb_data_file_path=/dev/hdd1:3Graw;/dev/hdd2:2Graw
重新啟動Mysql,即可開始使用。

22.6 調整I/O調度算法
磁盤讀取數據的3個步驟:
將磁頭移動到磁盤表面的的正確位置,所花費的時間稱為尋道時間;
等待磁盤旋轉,需要的數據會移動到磁頭下面,所花費的時間稱為旋轉時間(與磁盤轉速有關);
繼續旋轉,所需要的數據都經過磁頭讀取,所花費的時間稱為傳輸時間。
尋道時間取值範圍[5ms-10ms],旋轉時間取值範圍[2ms-5ms],傳輸時間與數據量有關取值範圍[0ms-1ms]。
所以降低尋道次數,從而能夠優化磁盤IO。
操作系統將IO請求放入隊列,對請求進行合並和排序,即將相同或相鄰扇區的請求進行合並,並按請求數據所在磁道由內向外的順序對請求排序,已達到一次尋道處理IO請求,減少尋道次數。
Linux的4種IO調度算法:
NOOP算法(No Operation):只對IO請求合並而不進行排序,使用先進先出FIFO隊列順序提交IO請求。
最後期限算法(Deadline):IO請求在隊列內進行合並、排序,並維護帶有超時的寫請求對列和讀請求隊列。新請求被插入普通隊列和讀寫隊列,一般按照普通對象的順序處理請求,當讀寫隊列某個請求快要超時時將被優先處理。
預期算法(Anticipatory):基於預測的IO算法,在最後期限算法(Deadline)的基礎上增加等待時間(6ms),等待時間內有相同扇區的新請求到達時優先處理新請求,否則按照普通隊列順序處理。
完全公平隊列(Complete Fair Queuing/CFQ):把IO請求按照進程分別放入每個進程的隊列中,以時間片算法輪轉處理每個隊列的請求。
Mysql建議使用最後期限算法(Deadline),如果是SSD建議使用NOOP算法(No Operation)。
查看當前系統支持的IO調度算法:
#dmseg | grep -i scheduler
查看當前設備使用的IO調度算法:
#more /sys/block/sda/queue/scheduler
修改當前塊設備的IO調度算法,修改後直接生效:
#echo "deadline" > /sys/block/sda/queue/scheduler
永久修改IO調度算法,通過修改內核引導參數,增加elevator=調度程序名
#vi /boot/grub/menu.lst
kernel /boot/vmlinuz-2.6.18-308.e15 ro root=LABLE=/ elevator=deadline

22.7 RAID卡電池充放電問題
22.7.1 什麽是RAID卡電池充放電
RAID卡寫緩存(Battery Backed Write Cache)有助於IO性能提升。
RAID卡寫緩存有電池,用於斷電後將寫緩存中的數據寫入磁盤,防止斷電導致的寫緩存中的數據丟失。
RAID卡電池會定期充、放電,定期充、放電的操作稱為電池校準。
電池校準的3個階段:首先RAID控制器會將電池充滿,然後開始放電,再重新充滿。
查看RAID卡電池狀態:
#MegaCli64 -AdpBbuCmd -GetBbuStatus -aAll

22.7.2 RAID卡緩存策略
查看RAID卡緩存策略:
#MegaCli64 -LDInfo -Lall -aAll
寫緩存策略,取值包括:WriteBack、WriteThrough。
WriteBack:將數據寫入RAID卡緩存後直接返回,由RAID卡控制器負責將緩存中的數據寫入磁盤。
WriteThrough:將數據直接寫入磁盤,不使用RAID卡緩存。
是否開啟預讀,取值包括:ReadAheadNone、ReadAhead、ReadAdaptive。
ReadAheadNone:不開啟預讀
ReadAhead:開啟預讀,預先把後面順序的數據加載入緩存,提升順序讀的性能,降低了隨機讀的性能。
ReadAdaptive:自適應預讀,在緩存和IO空閑時進行順序預讀,否則不進行預讀。默認設置。
讀操作是否緩存到RAID卡中,取值包括:Direct、Cached。
Direct:讀操作不緩存到RAID卡中
Cached:讀操作緩存到RAID卡中
電池問題時是否啟用Write Cache,取值包括:Write Cache Ok if Bad BBU、No Write Cache if Bad BBU。
No Write Cache if Bad BBU:電池問題時不啟用Write Cache,直接寫入磁盤。
Write Cache Ok if Bad BBU:電池問題時仍啟用Write Cache。
修改RAID卡緩存策略:
#MegaCli64 -LDSetProp -WB -Lall -aAll -- 寫緩存策略修改為WriteBack
#MegaCli64 -LDSetProp -WT -Lall -aAll -- 寫緩存策略修改為WriteThrough
#MegaCli64 -LDSetProp -CachedBadBBU -Lall -aAll -- 電池問題時啟用Write Cache策略Write Cache Ok if Bad BBU
#MegaCli64 -LDSetProp -NoCachedBadBBU -Lall -aAll -- 電池問題時不啟用Write Cache策略No Write Cache if Bad BBU
再RAID卡電池校準期間或電池故障期間,默認RAID卡寫緩存策略會從WriteBack變為WriteThrough,會造成系統寫入性能下降。
可以通過修改RAID卡緩存策略調整,無需重啟。#MegaCli64 -LDSetProp -CachedBadBBU -Lall -aAll
等業務高峰期過後應即時修改為#MegaCli64 -LDSetProp -NoCachedBadBBU -Lall -aAll 避免斷電RAID卡寫緩存數據丟失。

22.7.3 如何應對RAID卡電池充放電帶來的I/O性能波動
定期在業務量低的時候對RAID卡電池充放電,避免在高峰期發生寫緩存策略切換(從WriteBack到WriteThrough)。
DELL服務器RAID卡電池充放電周期為90天;IBM服務器RAID卡電池充放電周期為30天。
從日誌查看RAID卡電池下次充電時間:
#MegaCli64 -fwtermlog -dsply -a0 -nolog
從命令查看RAID卡電池下次充電時間:
#MegaCli -AdpBbuCmd -GetBbuProperties -aall
手動觸發電池校準操作:
#MegaCli64 -AdpBbuCmd -BbuLearn -aALL
在有UPS電源的情況下可以強制設置寫緩存策略為WriteBack,避免寫入性能波動。

22.8 NUMA架構優化
商用服務器分類:SMP對稱多處理器結構(Symmetric Multi-Process)、NUMA非一致存儲訪問結構(Non-Uniform Memory Access)、MPP海量並行處理結構(Massive Parallel Processing)。
22.8.1 SMP架構
SMP架構一組CPU共享內存和總線,系統將任務隊列對稱地分布在多個CPU上,各CPU平等的訪問內存、IO、外設,又稱為一致存儲訪問結構UMA。
SMP擴展方式有:增加內存、增加CPU、更換更高頻的CPU、擴充IO、增加磁盤。
SMP特征是共享,缺點是通過同一套總線機制訪問,存在資源爭用而產生鎖等待。
22.8.2 NUMA架構
NUMA架構是將物理機分為多個節點,每個節點有一組CPU和內存,節點之間通過互聯模塊進行連接和通信。
每個CPU可以訪問物理機的整個內存,但是訪問本節點內存要快於訪問其它節點的內存。
顯示當前NUMA的節點情況:# numactl --hardware
空閑內存(單位MB):#:free -m
節點距離(Node Distances)是指CPU訪問本節點內存和其它節點內存的資源消耗度量。
默認CPU訪問本節點內存節點距離為10,訪問其它節點內存節點距離為21。
NUMA的內存分配策略有4種:
缺省default:總是在本節點內分配;
綁定bind:在指定節點上分配;
交叉interleave:在所有節點或指定的多個節點上交叉分配;
優先preferred:優先在指定節點上分配,失敗則在其它節點上分配。
顯示當前系統的NUMA內存分配策略:# numactl --show
NUMA內存分配默認策略會導致各節點之間內存分配不均衡,某個節點產生Swap也不會從其它節點分配內存,這種現象稱為Swap Insanity。
Mysql是單進程多線程架構的數據庫,一個Mysql實例只能在一個NUMA節點上運行,使用本節點Swap也不會使用其它節點的內存的現象也會產生。
解決方法:
1.將NUMA的內存分配策略由default修改為interleave。
修改mysql啟動腳本mysqld_safe,添加一行cmd="/usr/bin/numactl --interleave all $cmd",含義:在Mysql啟動時指定內存分配策略為interleave。
# vi $MYSQL_HOME/bin/mysqld_safe
cmd="/usr/bin/numactl --interleave all $cmd"
for i in "$ledir/$MYSQLD" "$defaults" "--basedir=$MY_BASEDIR_VERSION" \
"--datadir=$DATADIR" "--plugin-dir=$plugin-dir" "$USER_OPTION"
do
cmd="$cmd "`shell_quote_string "i"`
done
保存後重啟Mysql。
2.在OS內核關閉NUMA特性
修改/etc/grub.conf文件,在kernel那行追加numa=off
# vi /etc/grub.conf
...
kernel /boot/...quiet 追加numa=off
保存後重啟服務器,再次檢查numa節點:
# numactl --hardware 只剩一個節點了。
如果有多個Mysql實例,則可以指定到不同的節點上,采用綁定bind內存分配策略,Mysql緩沖區參數設置不能大於本節點的內存。
NUMA架構缺點在於跨節點的內存訪問存在延時,性能不是隨著CPU的數量線性增長的。
22.8.3 MPP架構
MPP架構由多個SMP服務器通過一定的節點互聯網絡進行連接,每個節點只訪問本地資源,不訪問其它節點資源,這種Share Nothing架構理論上支持無限擴展。
節點之間的信息交互通過節點互聯網絡實現,稱為DATA Redistribution。
MPP服務器有機制來調度和平衡各個節點的負載和並行處理。

22.9 小結

22.Mysql磁盤I/O