Multipath多路徑冗余全解析


一、什么是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

device-mapper-1.02.32-1.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]

\_ round-robin 0 [prio=1][enabled]

\_ 5:0:0:7 sdbk 67:224 [active][ready]

\_ round-robin 0 [prio=1][enabled]

\_ 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

# multipath -v0

# 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 -F

# 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) =====

bus = 1

dev_t = 65:240

size = 671088640

vendor = HITACHI

product = DF600F

rev = 0000

h:b:t:l = 3:0:0:6

tgt_node_name = 0x50060e8010463ef1

path checker = readsector0 (internal default)

state = 2

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 的結果為可用設備。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM