一、什麼是multipath
普通的電腦主機都是一個硬碟挂接到一個總線上,這裡是一對一的關系。而到了有光纖組成的SAN環境,由于主機和存儲通過了光纖交換機連接配接,這樣的話,就構成了多對多的關系。也就是說,主機到存儲可以有多條路徑可以選擇。主機到存儲之間的IO由多條路徑可以選擇。
既然,每個主機到所對應的存儲可以經過幾條不同的路徑,如果是同時使用的話,I/O流量如何配置設定?其中一條路徑壞掉了,如何處理?還有在作業系統的角度來看,每條路徑,作業系統會認為是一個實際存在的實體盤,但實際上隻是通向同一個實體盤的不同路徑而已,這樣是在使用的時候,就給使用者帶來了困惑。多路徑軟體就是為了解決上面的問題應運而生的。多路徑的主要功能就是和儲存設備一起配合實作如下功能:
1. 故障的切換和恢複
2. IO流量的負載均衡
3. 磁盤的虛拟化
二、為什麼使用multipath
由于多路徑軟體是需要和存儲在一起配合使用的,不同的廠商基于不同的作業系統,都提供了不同的版本。并且有的廠商,軟體和硬體也不是一起賣的,如果要使用多路徑軟體的話,可能還需要向廠商購買license才行。比如EMC公司基于linux下的多路徑軟體,就需要單獨的購買license。
其中,EMC提供的就是PowerPath,HDS提供的就是HDLM,更多的存儲廠商提供的軟體,可參考這裡。
當然,使用系統自帶的免費多路徑軟體包,同時也是一個比較通用的包,可以支援大多數存儲廠商的裝置,即使是一些不是出名的廠商,通過對配置檔案進行稍作修改,也是可以支援并運作的很好的。
※ 請與IBM的RDAC、Qlogic的failover驅動區分開,它們都僅提供了Failover的功能,不支援Load Balance方式。但multipath根據選擇的政策不同,可支援多種方式,如:Failover、Multipath等。
三、multipath的組成
我這裡以紅帽x86_64為例,雖然版本比較老,但下面的配置方式基本适用後面的所有版本。
# cat /etc/redflag-release
Red Flag DC Server release 5.0 (Trinity SP2)
# uname -a
Linux localhost.localdomain 2.6.18-164.el5 #1 SMP Tue Aug 18 15:51:48 EDT 2009 x86_64 x86_64 x86_64 GNU/Linux
# rpm -qa|grep device
device-mapper-event-1.02.32-1.el5
device-mapper-1.02.32-1.el5
device-mapper-multipath-0.4.7-30.el5
可見,一套完整的multipath由下面幾部分組成:
1. device-mapper-multipath
提供multipathd和multipath等工具和multipath.conf等配置檔案。這些工具通過device mapper的ioctr的接口建立和配置multipath裝置(調用device-mapper的使用者空間庫。建立的多路徑裝置會在/dev/mapper中);
2. device-mapper
device-mapper包括兩大部分:核心部分和使用者部分。
核心部分由device-mapper核心(multipath.ko)和一些target driver(dm-multipath.ko)構成。dm-mod.ko是實作multipath的基礎,dm-multipath其實是dm的一個target驅動。核心完成裝置的映射,而target根據映射關系和自身特點具體處理從mappered device 下來的i/o。同時,在核心部分,提供了一個接口,使用者通過ioctr可和核心部分通信,以指導核心驅動的行為,比如如何建立mappered device,這些device的屬性等。
使用者空間部分包括device-mapper這個包。其中包括dmsetup工具和一些幫助建立和配置mappered device的庫。這些庫主要抽象,封裝了與ioctr通信的接口,以便友善建立和配置mappered device。device-mapper-multipath的程式中就需要調用這些庫;
3. scsi_id
其包含在udev程式包中,可以在multipath.conf中配置該程式來擷取scsi裝置的序号。通過序号,便可以判斷多個路徑對應了同一裝置。這個是多路徑實作的關鍵。scsi_id是通過sg驅動,向裝置發送EVPD page80或page83 的inquery指令來查詢scsi裝置的辨別。但一些裝置并不支援EVPD 的inquery指令,是以他們無法被用來生成multipath裝置。但可以改寫scsi_id,為不能提供scsi裝置辨別的裝置虛拟一個辨別符,并輸出到标準輸出。
multipath程式在建立multipath裝置時,會調用scsi_id,從其标準輸出中獲得該裝置的scsi id。在改寫時,需要修改scsi_id程式的傳回值為0。因為在multipath程式中,會檢查該直來确定scsi id是否已經成功得到。
四、配置multipath
原理看了一堆,實際配置還是比較簡單的。配置檔案隻有一個:/etc/multipath.conf 。配置前,請用fdisk -l 确認已可正确識别盤櫃的所有LUN,HDS支援多鍊路負載均衡,是以每條鍊路都是正常的;而如果是類似EMC CX300這樣僅支援負載均衡的裝置,則備援的鍊路會出現I/O Error的錯誤。
multipath.conf的配置參數、預設值,可參考:
1、編輯黑名單
預設情況下,multipath會把所有裝置都加入到黑名單(devnode "*"),也就是禁止使用。是以,我們首先需要取消該設定,把配置檔案修改為類似下面的内容:
devnode_blacklist {
#devnode "*"
devnode "hda"
wwid 3600508e000000000dc7200032e08af0b
}
這裡禁止使用hda,也就是光驅。另外,還限制使用本地的sda裝置,這個wwid,可通過下面的指令獲得:
# scsi_id -g -u -s /block/sda
3600508e000000000dc7200032e08af0b
2、編輯預設規則
不同的device-mapper-multipath或作業系統發行版,其預設的規則都有點不同,以RedHat x86_64為例,其path_grouping_policy預設為failover,也就是主備的方式。這明顯不符合我們的要求。(HDS支援多路徑負載均衡,EMC CX300等隻支援Failover)。
是以,我們需要修改預設的規則:
defaults {
udev_dir /dev
path_grouping_policy multibus
failback immediate
no_path_retry fail
user_friendly_name yes
關鍵是path_grouping_policy一項,其他選項可參考說明文檔。
3、啟動服務及生成映射
# modprobe dm-multipath
# service multipathd start
# multipath -v0
4、檢視複合後的裝置
# multipath -ll
會看到類似下面的資訊:
mpath0 (360060e80058e980000008e9800000007)
[size=20 GB][features="0"][hwhandler="0"]
\_ round-robin 0 [prio=1][active]
\_ 3:0:0:7 sdaa 65:160 [active][ready]
\_ round-robin 0 [prio=1][enabled]
\_ 4:0:0:7 sdas 66:192 [active][ready]
\_ 5:0:0:7 sdbk 67:224 [active][ready]
\_ 2:0:0:7 sdi 8:128 [active][ready]
這說明,已由四條鍊路sdaa/sdas/sdbk/sdi複合成一條鍊路,裝置名為mpath0。
狀态正常的話,把multipathd設定為自啟動:
# chkconfig multipathd on
5、使用mpath裝置
用multipath生成映射後,會在/dev目錄下産生多個指向同一條鍊路的裝置:
/dev/mapper/mpathn
/dev/mpath/mpathn
/dev/dm-n
但它們的來源是完全不同的:
/dev/mapper/mpathn 是multipath虛拟出來的多路徑裝置,我們應該使用這個裝置;
/dev/mpath/mpathn 是udev裝置管理器建立的,實際上就是指向下面的dm-n裝置,僅為了友善,不能用來挂載;
/dev/dm-n 是軟體内部自身使用的,不能被軟體以外使用,不可挂載。
簡單來說,就是我們應該使用/dev/mapper/下的裝置符。對該裝置即可用fdisk進行分區,或建立為pv。
6、分區或建立lvm
以前,我考慮到從系統iostat看到的都是dm-n的裝置,是以一直都是直接對dm-n操作。但這會産生一個問題,就是沒法分區。而對/dev/mapper/mpathn裝置操作就沒有這問題。隻要要注意,用fdisk分區并儲存後,必須重新整理multipath的映射表,以便其建立分區對應的裝置符,例如:
# fdisk -l /dev/mapper/mpath0
Disk /dev/mapper/mpath0: 214.7 GB, 214748364800 bytes
255 heads, 63 sectors/track, 26108 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Device Boot Start End Blocks Id System
/dev/mapper/mpath0p1 1 26108 209712478+ 83 Linux
# multipath -F
# ll /dev/mapper/mpath0p1
brw-rw---- 1 root disk 253, 2 5月 7 07:40 /dev/mapper/mpath0p1
同樣的,mpathn或其分區都可用來做pv使用:
# pvcreate /dev/mapper/mpath0p1
# vgcreate test /dev/mapper/mpath0p1
# lvcreate -L 1g -n lv1 test
# lvdisplay
# mkfs.ext3 /dev/test/lv1
※ 注意:
根據網上的資料,有部分multipath版本存在與lvm相容的問題。具體表現是,使用device-mapper裝置建立lvm完成,重新開機後,雖然lvm仍存在,但/dev/mapper下的裝置丢失。為了防止可能的意外,建議還是修改一下lvm的配置檔案/etc/lvm/lvm.conf,加入:
types=["device-mapper", 1]
7、其他
最簡單的測試方法,是用dd往磁盤讀寫資料,然後用iostat觀察各通道的流量和狀态,以判斷Failover或負載均衡方式是否正常:
# dd if=/dev/zero of=/dev/mapper/mpath0
# iostat -k 2
另外,如果是在由多台伺服器建構叢集環境中,為了讓每台伺服器識别的mpathn裝置順序一直,需進行wwid的綁定工作,請參考後面“自定義裝置名稱”中的内容。
五、答疑
1、為什麼黑名單中不直接使用devnode "sda" 呢?
因為按Linux對裝置的編号,當裝置從sda到sdz時,後一個裝置應該是sdaa。而multipath對黑名單的設定是以比對的方式進行的,也就是說,如果你設定為devnode "sda",那麼除了sda為,sdaa、sdab等的裝置(通道)都會被加入到黑名單中,而禁止使用。當然,你也可以參考配置檔案中的樣式,以正規表達式的形式進行描述:devnode "^sda$"。
但考慮到每次重新開機後,udev配置設定的盤符可能都不同(沒有做udev綁定的情況),是以,我覺得以wwid的方式處理更可靠。
2、為存儲定制特定的政策
在前面的配置中,我們已經在/etc/mulitpah.conf中配置了多路徑的預設path_grouping_policy為multibus。但有時候,同一台機器上如果連接配接了一個以上的存儲時,可能預設規則并不完全适用。這時,我們可以給特定的存儲定制多路徑符合的政策。
a、mulipath指令
該指令提供了一個-p的參數,可以修改預設政策,參數有:
-p policy force all maps to specified policy :
failover 1 path per priority group
multibus all paths in 1 priority group
group_by_serial 1 priority group per serial
group_by_prio 1 priority group per priority lvl
group_by_node_name 1 priority group per target node
例如,執行:
# multipath -p failover -v0
有如下結果:
mpath18 (360060e8010463ef004f2b79f00000006)
[size=320 GB][features="0"][hwhandler="0"]
\_ round-robin 0 [prio=2][active]
\_ 5:0:0:6 sdaf 65:240 [active][ready]
\_ 4:0:0:6 sdv 65:80 [active][ready]
\_ round-robin 0 [enabled]
\_ 2:0:0:6 sdb 8:16 [active][ready]
\_ 3:0:0:6 sdl 8:176 [active][ready]
這說明,當你對mpath18裝置讀寫時,sdaf、sdv 會處于active狀态,都有資料流,但sdb、sdl 組成的鍊路是enabled,作為ready情況。這為Failover(主備)情況,僅當sdaf、sdv組成的鍊路出現問題時,才會切換到sdb、sdl 的鍊路上。
b、修改配置檔案
可以在配置檔案中為指定的存儲定義政策。首先,可以用multipath -v3 -ll 看看存儲的資訊,例如,我這裡的機器就同時連接配接了兩個不同的存儲:
===== path info sdaa (mask 0x5) =====
bus = 1
dev_t = 65:160
size = 10487040
vendor = HITACHI
product = OPEN-V
rev = 6006
h:b:t:l = 2:0:1:24
tgt_node_name = 0x50060e80058e9800
path checker = readsector0 (internal default)
state = 2
uid = 360060e80058e980000008e9800000058 (cache)
===== path info sdaf (mask 0x5) =====
dev_t = 65:240
size = 671088640
product = DF600F
rev = 0000
h:b:t:l = 3:0:0:6
tgt_node_name = 0x50060e8010463ef1
uid = 360060e8010463ef004f2b79f00000006 (cache)
預設情況下,multipath已經支援大部分常見的存儲型号(可見multipath.conf.defaults),但不同的multipath版本可能都有些不同。這時,建議參考存儲的官方文檔:
devices {
device {
vendor "HITACHI" //廠商名稱
product "OPEN-V" //産品型号
path_grouping_policy group_by_prio //預設的路徑組政策
getuid_callout "/sbin/scsi_id -p 0x80 -g -u -s /block/%n" //獲得唯一裝置号使用的預設程式
path_checker readsector0 //決定路徑狀态的方法
path_selector "round-robin 0" //選擇那條路徑進行下一個IO操作的方法
prio_callout "/sbin/mpath_prio_alua /dev/%n" //擷取有限級數值使用的預設程式
failback immediate //故障恢複的模式
hardware_handler "0" //确認用來在路徑切換和IO錯誤時,執行特定的操作的子產品。
no_path_retry queue //在disable queue之前系統嘗試使用失效路徑的次數的數值
rr_min_io 100 //在目前的使用者組中,在切換到另外一條路徑之前的IO請求的數目
※ 千萬不要寫錯path_checker(可能值有:readsector0, tur, emc_clariion, hp_sw, directio)。 不清楚的,可從存儲的官方資料獲得。
3、自定義裝置名稱
預設情況下,multipath會根據multipath.conf.defaults中的定義,生成mpathn的裝置名。當然,我們也可以自行定義。不過,更主要的原因是:當我們有多台伺服器以相同的方式連接配接到存儲時,每台伺服器識别出來的mpathn順序可能不同。為了組成叢集,我們需要固定每台機器識别的裝置名順序是一緻的(綁定wwid)。
修改配置檔案,加入:
multipaths {
multipath {
wwid 360060e80058e980000008e9800000007
alias mpath0
重新重新整理multipath映射表後,mpath0就與該wwid裝置一一對應起來。除了别名alias外,還可以為該裝置定義其他屬性,請參考multipath.conf上的樣式。把該配置指派到其他同一叢集的機器上,則每台機器識别的mpathn裝置順序将是一緻的。
※ 注意:1、綁定後,需重新生成路徑的映射表;2、當加入該wwid綁定後,沒有綁定的裝置将不能使用,用-ll 也無法看到這些裝置,但/var/lib/multipath/bindings 中可見。
4、如何排錯
# multipath -v3 -ll
# dmsetup ls
# multipathd -k
> > show config
> >reconfigure
> >show paths
> > CTRL-D
/var/lib/multipath/bindings
/dev/mapper/
# cat /sys/block/sda/device/vendor
# cat /sys/block/sda/device/model
/var/lib/multipath/bindings顯示的内容包括黑名單中的wwid,其mpathn順序與multipath -ll 的結果可能不同。實際以multipath -ll 的結果為可用裝置。
本文轉自yzy121403725 51CTO部落格,原文連結:http://blog.51cto.com/lookingdream/1793606,如需轉載請自行聯系原作者