最近遇到一個奇怪的問題
收到短信報警說磁盤IO很高 復制延遲
iostat -x 1 10 信息如下:
QPS 如下:
負載很低 壓力很低 這就很無解了。 只有一個MYSQL
其實這是個硬件問題 ,就是
MegaSAS RAID卡 BBU Learn Cycle周期
背景
最近遇到有些帶MegaSAS RAID卡的服務器,在業務高峰時突然IO負載飈升得很高,IO性能急劇下降,查了日志及各種設置最后才發現是RAID卡的Cache寫策略由WriteBack變成WriteThrough了。更深入的原因是BBU進入了Learn Cycle周期,自動把Cache策略改為WriteThrough.
WriteBack和WriteThrough
在開始之前,我需要提到兩個詞: WriteBack, WriteThrough
- WriteBack:進行寫操作時,將數據寫入RAID卡緩存,並直接返回,RAID卡控制器將在系統負載低或者Cache滿了的情況下把數據寫入硬盤。該設置會大大提升RAID卡寫性能,絕大多數的情況下會降低系統IO負載。 數據的可靠性由RAID卡的BBU(Battery Backup Unit)進行保證。
- WriteThrough: 數據寫操作不使用緩存,數據直接寫入磁盤。RAID卡寫性能下降,在大多數情況下該設置會造成系統IO負載上升。
MegaSAS RAID卡的Cache策略
對於LSI的MegaSAS RAID卡, 默認的Cache策略是: WriteBack, ReadAheadNone, Direct, No Write Cache if Bad BBU
如何查看RAID卡Cache策略
root@hostname:~ # ./MegaCli -LDInfo -Lall -aALL
Adapter 0 -- Virtual Drive Information:
Virtual Drive: 0 (Target Id: 0) Name : RAID Level : Primary-1, Secondary-0, RAID Level Qualifier-0 Size : 557.861 GB Mirror Data : 557.861 GB State : Optimal Strip Size : 128 KB Number Of Drives : 2 Span Depth : 1 Default Cache Policy: WriteBack, ReadAheadNone, Direct, No Write Cache if Bad BBU Current Cache Policy: WriteBack, ReadAheadNone, Direct, No Write Cache if Bad BBU Default Access Policy: Read/Write Current Access Policy: Read/Write Disk Cache Policy : Disabled Encryption Type : None Is VD Cached: No Exit Code: 0x00
- Default Cache Policy: 默認的緩存策略,針對每個RAID可以有不同的設置.
- Current Cache Policy: 當前生效的緩存策略.
策略說明
- 第一段: WriteBack, WriteThrough
-
第二段: ReadAheadNone, ReadAdaptive, ReadAhead.
- ReadAheadNone: 不開啟預讀。這是默認的設置
- ReadAhead: 在讀操作時,預先把后面順序的數據加載入Cache,在順序讀取時,能提高性能,相反會降低隨機讀的性能。
- ReadAdaptive: 自適應預讀,當Cache memory和IO空閑時,采取順序預讀,平衡了連續讀性能及隨機讀的性能,需要消耗一定的計算能力。
-
第三段: Direct, Cached.
- Direct: Direct IO模式,讀操作不緩存到cache memory中,數據將同時傳輸到cache中和應用,如果接下來要讀取相同的數據塊,則直接從Cache memory中獲取. 這是默認的設置
- Cached: Cached IO模式,所有讀操作都會緩存到cache memory中。
-
第四段: Write Cache OK if Bad BBU, No Write Cache if Bad BBU
- Write Cache OK if Bad BBU: 在BBU有問題時(如電池失效), 依舊使用Write Cache, 有一定的數據丟失風險.
- No Write Cache if Bad BBU: 在BBU有問題時, 不使用Write Cache
策略自動切換的問題
由於MegaSAS RAID卡默認采用No Write Cache if Bad BBU的設置,將可能發生Write Cache策略變更的情況(由WriteBack變成WriteThrough),導致寫性能下降,如果該自動變更發生在業務高峰且系統Io負載高的時候,可能會引發不可預測的問題,如卡機。以下原因將造成Write Cache策略的變更.
- RAID卡進入BBU Learn Cycle: 詳細介紹見下面
- 檢測到某些電池故障,如電池容量過低等,一般是電池老化帶來的影響,IBM建議一年更換一次RAID卡電池
- 沒有安裝電池, 部分服務器購買時不帶電池,導致被自動設置為WriteThrough
在BBU出問題時,如何臨時強制啟用Write Cache?
./MegaCli -LDSetProp CachedBadBBU -Lall -aALL
./MegaCli -LDSetProp WB -Lall -aALL
#以下命令可以把設置修改回去
./MegaCli -LDSetProp NOCachedBadBBU -Lall -aALL
BBU Learn Cycle
BBU由鋰離子電池和電子控制電路組成。 鋰離子電池的壽命取決於其老化程度,從出廠之后,無論它是否被充電及它的充放電次數多與少,鋰離子電池的容量將慢慢的減少。這意味着一個老電池無法像新電池那么持久。 也就決定了BBU的相對充電狀態(Relative State of Charge)不會等於絕對充電狀態(Absolute State of Charge)。
為了記錄電池的放電曲線,以便控制器了解電池的狀態,例如最大和最小電壓等,同時為了延長電池的壽命,默認會啟用自動校准模式(AutoLearn Mode). 在learn cycle期間, raid卡控制器不會啟用BBU直到它完成校准。整個過程可能需要高達12小時。這個過程中,會禁用WriteBack模式,以保證數據完整性,同時會造成性能的降低. 整個Learn Cycle分為三個步驟:
- 控制器把BBU電池充滿電(該步驟可能是放電后充電或直接充電,如果電池剛好滿電,則直接進入第二階段)
- 開始校准, 對BBU電池執行放電
- 放電完成后,完成校准,並重新開始充電, 直接達到最大電量, 整個Learn Cycle才算完成 注意: 如果第二或第三階段被中斷,重新校准的任務會停止,而不會重新執行
IBM的服務器默認設置是30天執行一次Learn Cycle, 而DELL是90天。不推薦關閉Auto Learn模式,通過這個校准,能延長電池壽命,不作電池校准的Raid卡,電池壽命將從正常的2年降為8個月
查看當前的BBU Learn設置
root@hostname:~ # ./MegaCli -AdpBbuCmd -GetBbuProperties -aALL
BBU Properties for Adapter: 0 Auto Learn Period: 2592000 Sec Next Learn time: 394618008 Sec Learn Delay Interval:0 Hours Auto-Learn Mode: Enabled
- Auto Learn Period: 自動校准間隔, 單位秒,IBM的服務器默認設置是30天執行一次Learn Cycle, 而DELL是90天。 該設置無法修改。
- Next Learn time: 下一次自動校准的時間,從2000年1月1日算起的秒數,這個設置無法修改,根據上一次自動校准的完成時間加上自動校准間隔計算得來。該時間轉化為實際時間時,需要加上RAID卡時間的誤差,部分RAID卡時間轉成GMT時間后,依然是錯誤的。
實際時間計算方法,偽代碼如下
RealTime = Next Learn time + ( 系統時間的Unixtime - RAID卡時間的Unixtime ) date -d 'UTC 2000-01-01 + $RealTime secs'
- Learn Delay Interval: 自動校准啟動后的延遲時間,單位小時,最大設置為7天。該設置只針對下次Learn Cycle,下次Learn Cycle完成后,該值將自動歸零。
- Auto-Learn Mode: 是否打開自動校准模式
查看當前BBU的狀態
root@hostname:~ # MegaCli -AdpBbuCmd -GetBbuStatus -aALL
BBU status for Adapter: 0 BatteryType: iBBU Voltage: 3837 mV Current: -152 mA Temperature: 23 C Battery State : Operational BBU Firmware Status: Charging Status : Discharging Voltage : OK Temperature : OK Learn Cycle Requested : Yes Learn Cycle Active : Yes Learn Cycle Status : OK Learn Cycle Timeout : No I2c Errors Detected : No Battery Pack Missing : No Battery Replacement required : No Remaining Capacity Low : No Periodic Learn Required : No Transparent Learn : No No space to cache offload : No Pack is about to fail & should be replaced : No Cache Offload premium feature required : No Module microcode update required : No ...下略...
- Charging Status: 當前電池處於什么狀態,有Charging, Discharging, None等值,分別代表電池充電,放電,及沒有充放電操作的狀態
- Learn Cycle Requested: Learn Cycle請求,當為Yes時,並且下面的Learn Cycle Active為No, 說明已經開始了Learn Cycle的第一階段, 此時策略開始變為WriteThrough, 電池將經歷一個放電后充電或者充電的過程
- Learn Cycle Active: 是否處於Learn Cycle的校准階段,如果為Yes, 則進入了Learn Cycle的第二階段,控制器開始校准電池.
- Battery Replacement required: 電池是否需要維修,如果為Yes, 請盡快更換電池5. Remaining Capacity Low: 剩余電容量低, 如果為Yes, 需要更換電池
如何強制啟動Learn Cycle操作
強制執行自動校准的命令, 執行該命令后,會延遲幾秒才會生效,策略會自動變為WriteThrough
root@hostname:~ # MegaCli -AdpBbuCmd -BbuLearn -aALL
通過該命令可以粗略的調整自動校准的下次執行時間,但無法100%准確:
- 本次Learn Cycle的完成時間無法精確計算,這取決於電池的放電及充電速度.* 下次Battery的relearn任務可能會因為某些原因而推遲執行,例如當時電池正在充電,整個Relearn操作將推遲到充電完后之后。
如何查看當前的Cache策略是否發生變動
對比Default Cache Policy和Current Cache Policy是否不同,不同則是策略發生變動
root@hostname:~ # MegaCli -LDInfo -Lall -aALL
如何把Learn模式改為手動?
echo 'autoLearnMode=1' >/tmp/megaraid.conf MegaCli -AdpBbuCmd -SetBbuProperties -f /tmp/megaraid.conf -aAll #1為Disable, 0為Enable, 從Disable切換到Enable時,Relearn操作會立刻執行 #確認是否生效 MegaCli -AdpBbuCmd -GetBbuProperties -aALL
建議
推薦的Cache策略: 使用No Write Cache if Bad BBU,在BBU出問題的情況下,犧牲性能來確保數據的安全性。
WriteBack, ReadAheadNone, Direct, No Write Cache if Bad BBU
以下有幾種可選的方法
- 在非業務高峰對BBU強制啟動Learn Cycle,但下次自動的Learn Cycle會向后延遲5-6小時(視整個Learn Cycle所需時間而定)。每一次Learn Cycle執行完,下次Learn Cycle的執行時間會發生向后偏移的情況,推移時間由上一次整個Learn Cycle的耗時決定,一般下一次執行時間都會向后推移大約5小時(一次Learn Cycle的時間)。建議可以根據實際推遲效果定期在非業務高峰做一次手動Learn Cycle(一般是02:00~05:00)
- 切換為手動模式,由crontab或者其他手動定期觸發Learn Cycle,采用該方式需要根據不同硬件來決定Learn Cycle的間隔,采取錯誤的間隔將損耗電池的壽命。IBM的30天, DELL的機器為90天。
- 檢測下次Learn Cycle的時間,在即將進入Learn Cycle前,設置為Write Cached OK if Bad BBU, 使得Write Cache策略在Learn Cycle期間不發生變動,Learn Cycle過后,切換會原配置,這種方式在Learn Cycle期間(大約5小時左右)數據將不保險,如果遇到斷電的情況,將發生數據丟失。* 檢測下次Learn Cycle的時間,提前1~2天,在非業務高峰期提前觸發learn cycle. 這種方法效果最好,也最方便,需要專門的腳本進行下次Learn Cycle時間的計算
推薦做法: 在保留Auto Learn模式的同時,定期通過Crontab對Raid卡執行強制Relearn的操作,檢測下次Learn Cycle的時間,提前1~2天,在非業務高峰期提前觸發learn cycle(一般是02:00~05:00)。
參考資料