做技術的朋友可能有過類似這樣的感覺——每天都會遇到新的問題,或者學到新的知識。然而一個人的時間和精力畢竟有限,不是所有的崗位都能做到總是親力親為,每人最擅長的領域也各不相同。為了使工程師自己踩過的坑、那些實用的心得體會也能給大家帶來幫助,把經驗記錄和分享出來就顯得尤為可貴,這就是我們開設《工程師筆記》專欄的目的。
小議Linux下磁盤亂序問題
最近碰到客戶問有關Linux系統下磁盤亂序的問題,整理了一下供各位參考。個人觀點,紕漏之處,還請不吝指正~
在戴爾PowerEdge 11G和12G服務器上,由于LSI(如今的Avago)當時的控制器微碼、驅動以及對應Linux kernel 的版本支持問題,確實出現過這種狀況(具體涉及到兩種SAS HBA/RAID卡: PERC H200(LSI 9211-8i)和 LSI 9207)。此問題在使用了LSI 對應直通SAS控制器芯片的服務器上均會出現,與服務器廠商并無直接關系。結論是客戶提到的“磁盤亂序”情況確實是存在過的。
盡管當時的影響不小,圈中也小有轟動,但LSI很快通過Firmware和kernel驅動解決掉了。
當前戴爾全線服務器(13G/12G等),PERC H330(LSI 3008 芯片)、H730/P(LSI 3108 芯片)或是外部端口的12Gbps SAS Ext. HBA等,均不存在磁盤亂序的問題。
所以,在不存在Firmware或驅動bug的情況下,系統識別磁盤設備順序會按照總線及驅動加載順序進行。從前向后,或從后向前,總之是規則有序的,不能稱為“亂”序。
Linux kernel指派sdx為設備名對應磁盤的方式其實很早就已經不推薦了。大約在2.6.13 Kernel版本以后,為保證persistent naming(持久的命名),udev默認會在/dev目錄下創建by-lable、by-uuid 等目錄,通過磁盤唯一的標識方式創建symbolic link(符號連接)來指向實際的設備節點。
結合服務器上的RAID控制器,當用戶既要配置JBOD又要配置RAID時,JBOD的每塊磁盤其實是最先被系統識別到的,優先級最高;然后按照磁盤slot ID 依次排序。如果同時配置了Raid VD,均會被靠后識別,排至JBOD最后一塊磁盤的后面。
舉個實際的例子如下:
戴爾一款16個硬盤槽位的服務器機型,當slot 0,1上的硬盤做RAID 1為第一個VD0,slot 12-slot 15 硬盤做RAID 6 為第二個VD1;其余槽位硬盤slot 2-slot 11 均做JBOD。這樣,做JBOD 的第一塊盤即slot2 槽位的磁盤將會是dev/sda,以此類推直到JBOD 全部磁盤按順序分配,之后才開始為RAID 第一組VD 進行分配。即VD0 會是dev/sdk,VD1 為/dev/sdl。
如果客戶仍然希望用 sdX 的方式來對應磁盤物理順序,有一個變通的辦法,就是需要通過手工改動/etc/udev/rules.d 文件的方式來實現。
具體可參考如下:
KERNEL=="sda*" NAME="sdb%n"
KERNEL=="sdb*" NAME="sdc%n"
KERNEL=="sdc*" NAME="sdd%n"
KERNEL=="sdd*" NAME="sde%n"
KERNEL=="sde*" NAME="sdf%n"
KERNEL=="sdf*" NAME="sdg%n"
KERNEL=="sdg*" NAME="sdh%n"
KERNEL=="sdh*" NAME="sdi%n"
KERNEL=="sdi*" NAME="sdj%n"
KERNEL=="sdj*" NAME="sdk%n"
KERNEL=="sdk*" NAME="sda%n"
但是要注意,這種方式有很大的局限性。一旦RAID配置改變,增減VD或者JBOD磁盤的增減都會造成人為亂序的情況。
綜上所述,我們仍然建議引導客戶接受采用By uuid(綁定)或By lable的方式來管理。
具體可參見:《Persistent block device naming》https://wiki.archlinux.org/index.php/Persistent_block_device_naming#Persistent_naming_methods