正如 Gluster和Ceph對比 辨析,GlusterFS是在文件系統之上構建的分布式文件系統,所以 Linux文件系統 的構建會給GlusterFS帶來更多的特性和功能。例如,結合卷管理可以實現快照。本文實踐是快速部署一個簡化版本的GlusterFS集群,在文件系統存儲層采用直接基於磁盤設備創建XFS文件系統。這種簡潔的文件系統雖然靈活性受到限制,但是架構簡潔也使得出現錯誤的可能性降低。
服務器准備¶
-
至少需要3台服務器組建穩定的GlusterFS集群(2台雖然也能構建,但是缺乏quotum容易導致腦裂),在我的這個演示案例中,我采用6個KVM虛擬機(最初我以為奇數服務器可以構建更為穩定,但是參考 GlusterFS腦裂和解決方案 修正了方案),目的是構建分布式多副本集群
-
每個虛擬機使用一個附加的 /dev/vdb 設備(見下文磁盤分區和文件系統構建)
環境准備¶
-
所有服務器節點的時間必須同步,所以,請安裝並運行ntp客戶端,當前主流推薦采用 chrony - CentOS / RHEL 7 : Chrony V/s NTP (Differences Between ntpd and chronyd)
-
所有服務器需要彼此能夠DNS解析,所以建議采用統一的DNS服務器進行維護主機名解析,比較簡化的方法是所有服務器采用一致的
/etc/hosts
提供靜態主機名解析。
磁盤分區¶
-
使用
parted
對磁盤進行分區,分區vdb1占用250G(沒有使用這個vdb是因為我還准備用vdb構建復雜的 Stratis - Linux存儲系統 ):parted -a optimal /dev/vdb mklabel gpt unit GB mkpart primary 0 250 name 1 gluster_brick1 print
如果磁盤之前已經有分區表,但是分區表沒有對齊,你沒有執行 mklabel gpt
就執行 mkpart
就可能會提示磁盤分區從0開始對齊需要接近扇區,這個警告需要通過使用 -a optimal
參數來修正:
Warning: You requested a partition from 0.00GB to 3840GB (sectors 0..7500000000).
The closest location we can manage is 0.00GB to 0.00GB (sectors 34..2047).
Is this still acceptable to you?
Yes/No?
對於原先有分區的磁盤,覆蓋原先的分區表,默認是會提示WARNING的,對於腳本執行命令,需要關閉提示,則使用參數 -s
表示 --script
就不會有提示了。舉例:
parted -s -a optimal /dev/vdb mklabel gpt parted -s -a optimal /dev/vdb mkpart primary 0% 100% parted -s -a optimal /dev/vdb name 1 gluster_brick1 mkfs.xfs -f -i size=512 /dev/vdb1
此時顯示分區信息:
Model: Virtio Block Device (virtblk) Disk /dev/vdb: 537GB Sector size (logical/physical): 512B/512B Partition Table: gpt Disk Flags: Number Start End Size File system Name Flags 1 0.00GB 250GB 250GB gluster_brick1
退出parted:
quit
-
使用lsblk檢查磁盤設備:
lsblk
輸出顯示:
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
vda 253:0 0 40G 0 disk
`-vda1 253:1 0 40G 0 part /
vdb 253:16 0 500G 0 disk
`-vdb1 253:17 0 232.9G 0 part
XFS文件系統¶
注解
GlusterFS底層的XFS’文件系統根據不同的硬件(RAID條帶化)或者存儲的內容不同,可以采用不同的優化策略。我准備在 XFS性能 做詳細的測試和對比。這里僅做簡化的配置,采用比較通用的參數。
GlusterFS可以使用任何支持擴展屬性的文件系統,例如XFS或者Ext4。
-
格式化bricks並掛載:
mkfs.xfs -i size=512 /dev/vdb1 mkdir -p /data/brick1 echo '/dev/vdb1 /data/brick1 xfs defaults 1 2' >> /etc/fstab mount -a && mount
注解
掛載XFS的參數建議: rw,inode64,noatime,nouuid
所以上述命令可以修改:
echo '/dev/vdb1 /data/brick1 xfs rw,inode64,noatime,nouuid 1 2' >> /etc/fstab
我對比了默認的 defaults
參數,實際上就是 rw,relatime,attr2,inode64,noquota
,則上述 rw,inode64,noatime,nouuid
實際效果僅僅是將默認的 relatime
修改成了 noatime
此時可以看到 vdb1 掛載到 /data/brick1
/dev/vdb1 on /data/brick1 type xfs (rw,relatime,attr2,inode64,noquota)
批量創建文件系統腳本¶
服務器有多塊nvme磁盤,從 /dev/nvme0n1
到 /dev/nvme11n1
共計12塊磁盤,則采用如下腳本快速完成格式化掛載:
for i in {0..11};do
if [ ! -d /data/brick${i} ];then mkdir -p /data/brick${i};fi
parted -s -a optimal /dev/nvme${i}n1 mklabel gpt
parted -s -a optimal /dev/nvme${i}n1 mkpart primary xfs 0% 100%
parted -s -a optimal /dev/nvme${i}n1 name 1 gluster_brick${i}
sleep 1
mkfs.xfs -f -i size=512 /dev/nvme${i}n1p1
fstab_line=`grep "/dev/nvme${i}n1p1" /etc/fstab`
if [ ! -n "$fstab_line" ];then echo "/dev/nvme${i}n1p1 /data/brick${i} xfs rw,inode64,noatime,nouuid 1 2" >> /etc/fstab;fi
mount /data/brick${i}
done
完成后磁盤掛載如下:
/dev/nvme0n1p1 3.5T 33M 3.5T 1% /data/brick0 /dev/nvme1n1p1 3.5T 33M 3.5T 1% /data/brick1 /dev/nvme2n1p1 3.5T 33M 3.5T 1% /data/brick2 /dev/nvme3n1p1 3.5T 33M 3.5T 1% /data/brick3 /dev/nvme4n1p1 3.5T 33M 3.5T 1% /data/brick4 /dev/nvme5n1p1 3.5T 33M 3.5T 1% /data/brick5 /dev/nvme6n1p1 3.5T 33M 3.5T 1% /data/brick6 /dev/nvme7n1p1 3.5T 33M 3.5T 1% /data/brick7 /dev/nvme8n1p1 3.5T 33M 3.5T 1% /data/brick8 /dev/nvme9n1p1 3.5T 33M 3.5T 1% /data/brick9 /dev/nvme10n1p1 3.5T 33M 3.5T 1% /data/brick10 /dev/nvme11n1p1 3.5T 33M 3.5T 1% /data/brick11
安裝GlusterFS¶
注解
以前安裝GlusterFS的方法是先下載repo倉庫配置文件,例如 glusterfs-rhel8.repo
wget -P /etc/yum.repos.d https://download.gluster.org/pub/gluster/glusterfs/LATEST/CentOS/glusterfs-rhel8.repo
也可以通過dnf命令管理:
dnf config-manager --add-repo https://download.gluster.org/pub/gluster/glusterfs/LATEST/CentOS/glusterfs-rhel8.repo
-
現在CentOS已經把開源的多個存儲項目集中到一個統一的 CentOS Storage Special Interest Group (SIG) ,所以安裝對應存儲軟件的軟件倉庫非常簡單:
yum install centos-release-gluster
-
激活PowerTools repo - 必須激活PowerTools軟件倉庫,否則安裝
glusterfs-server
會提示報錯python3-pyxattr is needed by glusterfs-srver which is provded by powertools repo from centOS 8 so this also needs to be enabled
dnf config-manager --set-enabled PowerTools
注解
可以通過 dnf repolist all
檢查可用的repo,並且通過上述命令激活需要的倉庫。
在CentOS 7上安裝舊版本 GlusterFS 6.10 則不需要激活PowerTools
-
安裝GlusterFS:
dnf install glusterfs-server
-
啟動GlusterFS管理服務:
systemctl start glusterd
-
檢查服務狀態:
systemctl status glusterd
在CentOS 7上安裝GlusterFS¶
如果在標准的CentOS 7上,當前也是可以直接使用 SIG Yum Repos進行安裝的:
yum install centos-release-gluster
然后安裝方式同上。
不過,如果你的CentOS安裝沒有升級到最新版本,或者是采用了CentOS的自制版本,則需要獨立分發倉庫配置文件 /etc/yum.repos.d/CentOS-Gluster-7.repo
和軟件包簽名證書文件 /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-Storage
,這兩個文件分別是通過如下rpm包可以通過CentOS的發行版extras倉庫獲得:
yum install http://mirrors.163.com/centos/7.8.2003/extras/x86_64/Packages/centos-release-gluster7-1.0-2.el7.centos.noarch.rpm yum install http://mirrors.163.com/centos/7.8.2003/extras/x86_64/Packages/centos-release-storage-common-2-2.el7.centos.noarch.rpm
注解
centos-release-gluster7-1.0-2.el7.centos.noarch 要求 centos-release >= 7-5.1804.el7.centos.2
如果由於業務原因,無法升級操作系統,則可以考慮安裝較低版本的GlusterFS,通過以下命令搜索可能的GlusterFS版本:
yum search centos-release-gluster
提示可選版本如下:
===================== N/S Matched: centos-release-gluster ====================== centos-release-gluster-legacy.noarch : Disable unmaintained Gluster repositories : from the CentOS Storage SIG centos-release-gluster312.noarch : Gluster 3.12 (Long Term Stable) packages from : the CentOS Storage SIG repository centos-release-gluster41.x86_64 : Gluster 4.1 (Long Term Stable) packages from : the CentOS Storage SIG repository centos-release-gluster5.noarch : Gluster 5 packages from the CentOS Storage SIG : repository centos-release-gluster6.noarch : Gluster 6 packages from the CentOS Storage SIG : repository centos-release-gluster7.noarch : Gluster 7 packages from the CentOS Storage SIG : repository
舊版本CentOS 7.x可以安裝GlusterFS 6系列,對操作系統版本要求較低。在一台服務器上安裝過 centos-release-gluster6
之后,只需要將這台服務器上的以下文件直接復制到其他需要安裝的服務器(可能不適合直接安裝發行版軟件包)就可以在服務器上安裝GlusterFS:
-
/etc/yum.repo.d/CentOS-Gluster-6.repo
-
/etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-Storage
然后在需要安裝服務器上執行:
yum install glusterfs-server
在CentOS 6上安裝GlusterFS¶
生產環境也有非常古老的CentOS 6系統,安裝GlusterFS舊版本客戶端,測試和GlusterFS 7的兼容性。首先通過 yum search centos-release-gluster
檢查可用版本,然后安裝對應的GlusterFS。
配置GlusterFS¶
-
確保服務器打開正確通訊端口:
# firewall-cmd --zone=public --add-port=24007-24008/tcp --permanent success # firewall-cmd --reload success
注解
CentOS 7 默認啟用了防火牆,上述步驟請無比確認執行成功。否則后續添加 peer
節點會顯示 Disconected
狀態,無法正常工作。
-
在第一台服務器上執行以下命令配置信任存儲池,將7台服務器組成一個信任存儲池:
gluster peer probe worker2 gluster peer probe worker3 ... gluster peer probe worker7 #這里多加了一台服務器,實際應該剔除
-
然后檢查peer status:
gluster peer status
輸出顯示類似:
Number of Peers: 6 Hostname: worker2 Uuid: 48350a85-3c2c-43f3-aca7-b99c7043d7af State: Peer in Cluster (Connected) Hostname: worker3 Uuid: 96a821b3-6232-4b8b-99a6-830b4fd17110 State: Peer in Cluster (Connected) ... Hostname: worker7 Uuid: c9262857-7f56-4500-a2d4-5c81767a27cf State: Peer in Cluster (Connected)
設置GlusterFS卷¶
-
在 所有服務器 上執行以下命令創建一個GlusterFS卷:
mkdir -p /data/brick1/gv0
-
然后在 任意一台服務器 上執行創建卷命令:
gluster volume create gv0 replica 3 \ worker1:/data/brick1/gv0 \ worker2:/data/brick1/gv0 \ worker3:/data/brick1/gv0 \ worker4:/data/brick1/gv0 \ worker5:/data/brick1/gv0 \ worker6:/data/brick1/gv0 \ worker7:/data/brick1/gv0
這里報錯:
number of bricks is not a multiple of replica count Usage: volume create <NEW-VOLNAME> [stripe <COUNT>] [[replica <COUNT> [arbiter <COUNT>]]|[replica 2 thin-arbiter 1]] [disperse [<COUNT>]] [disperse-data <COUNT>] [redundancy <COUNT>] [transport <tcp|rdma|tcp,rdma>] <NEW-BRICK> <TA-BRICK>... [force]
也就是說,要求bricks數量必須是replica數量的整數倍。
注解
請參考 GlusterFS腦裂和解決方案 的實現原理:對於穩定的分布式文件系統,需要采用3副本(3 replicas)或者2副本+1個仲裁卷來確保客戶端寫入時能夠根據quorum來判斷集群的可用性,避免腦裂。
不管怎樣,每個文件的存儲都需要3個卷來負責,所以構建brick的數量必須是3的倍數。
如果你的資金有限(需要節約存儲空間),則可以采用2個數據卷+1個仲裁卷(仲裁卷可以大幅節約存儲空間);但是對於數據安全性要求較高的場景,依然建議采用3副本數據卷方案。
但是,需要注意需要把一個文件的多個副本存放到不同服務器上,就需要特別注意 brick的順序 。正確的方式是首先依次列出所有服務器的第一個brick,然后再列出所有服務器的第二個brick,依次類推。這樣GlusterFS才能正確把文件的副本存放到不同的服務器上。
注解
如果你使用的是非常高端的多存儲設備服務器,尤其需要在構建glusterfs時采用正確的gluster brick順序,避免多副本數據都集中到少數服務器上導致無法容災。
由於這里采用了錯誤的bricks數量(必須是3的整數倍),所以我這里修訂,剔除掉 worker7
節點:
gluster peer detach worker7
此時提示:
All clients mounted through the peer which is getting detached need to be remounted using one of the other active peers in the trusted storage pool to ensure client gets notification on any changes done on the gluster configuration and if the same has been done do you want to proceed? (y/n)
輸入 y
剔除掉節點 worker7
,這樣集群中只保留6個服務器節點,每個節點有一個 brick1
。
-
然后重新構建存儲卷:
gluster volume create gv0 replica 3 \ worker1:/data/brick1/gv0 \ worker2:/data/brick1/gv0 \ worker3:/data/brick1/gv0 \ worker4:/data/brick1/gv0 \ worker5:/data/brick1/gv0 \ worker6:/data/brick1/gv0
此時提示數據卷建立:
volume create: gv0: success: please start the volume to access data
-
啟動存儲卷:
gluster volume start gv0
提示信息:
volume start: gv0: success
-
現在可以檢查卷狀態:
gluster volume info
輸出信息:
Volume Name: gv0 Type: Distributed-Replicate Volume ID: 5842afec-f6c9-4530-bc90-7f92705d3bdd Status: Started Snapshot Count: 0 Number of Bricks: 2 x 3 = 6 Transport-type: tcp Bricks: Brick1: worker1:/data/brick1/gv0 Brick2: worker2:/data/brick1/gv0 Brick3: worker3:/data/brick1/gv0 Brick4: worker4:/data/brick1/gv0 Brick5: worker5:/data/brick1/gv0 Brick6: worker6:/data/brick1/gv0 Options Reconfigured: transport.address-family: inet storage.fips-mode-rchecksum: on nfs.disable: on performance.client-io-threads: off
注意上述卷信息中需要顯示狀態 Status: Started
,如果狀態不是啟動狀態,則需要檢查 /var/log/glusterfs/glusterd.log
排查。
-
啟動存儲卷:
gluster volume start gv0
提示信息:
volume start: gv0: success
-
現在可以檢查卷狀態:
gluster volume info
輸出信息:
Volume Name: gv0 Type: Distributed-Replicate Volume ID: 5842afec-f6c9-4530-bc90-7f92705d3bdd Status: Started Snapshot Count: 0 Number of Bricks: 2 x 3 = 6 Transport-type: tcp Bricks: Brick1: worker1:/data/brick1/gv0 Brick2: worker2:/data/brick1/gv0 Brick3: worker3:/data/brick1/gv0 Brick4: worker4:/data/brick1/gv0 Brick5: worker5:/data/brick1/gv0 Brick6: worker6:/data/brick1/gv0 Options Reconfigured: transport.address-family: inet storage.fips-mode-rchecksum: on nfs.disable: on performance.client-io-threads: off
注意上述卷信息中需要顯示狀態 Status: Started
,如果狀態不是啟動狀態,則需要檢查 /var/log/glusterfs/glusterd.log
排查。
-
啟動存儲卷:
gluster volume start gv0
提示信息:
volume start: gv0: success
-
現在可以檢查卷狀態:
gluster volume info
輸出信息:
Volume Name: gv0 Type: Distributed-Replicate Volume ID: 5842afec-f6c9-4530-bc90-7f92705d3bdd Status: Started Snapshot Count: 0 Number of Bricks: 2 x 3 = 6 Transport-type: tcp Bricks: Brick1: worker1:/data/brick1/gv0 Brick2: worker2:/data/brick1/gv0 Brick3: worker3:/data/brick1/gv0 Brick4: worker4:/data/brick1/gv0 Brick5: worker5:/data/brick1/gv0 Brick6: worker6:/data/brick1/gv0 Options Reconfigured: transport.address-family: inet storage.fips-mode-rchecksum: on nfs.disable: on performance.client-io-threads: off
注意上述卷信息中需要顯示狀態 Status: Started
,如果狀態不是啟動狀態,則需要檢查 /var/log/glusterfs/glusterd.log
排查。
注解
GlusterFS支持多種 GlusterFS卷 ,通常對於生產環境,建議使用數據高可用的 Replicated
卷,或者 Distributed Replicated
卷。
這里的案例指定 replica 3
也就是多副本卷,但是由於同時提供了多個3x數量的brick,所以就自然形成了分布式多副本卷( Distributed Replicated
)。這種場景非常適合大規模的海量存儲。
使用GlusterFS卷¶
通常為了結構清晰和便於維護,GlusterFS客戶端和服務器是采用分離部署的。這里我們把剛才剔除掉的 worker7
作為客戶端來測試剛才構建的數據卷。當然,客戶端和服務器端部署在相同服務器上也是可以的,但是需要確保GlusterFS服務端比客戶端先啟動並就緒,否則可能會導致客戶端異常。
客戶端GlusterFS軟件安裝¶
在客戶端不需要安裝完整的glusterfs軟件包,只需要安裝 gluster-fuse
軟件包:
dnf install glusterfs-fuse
客戶端掛載GlusterFS卷¶
-
在
worker7
上創建掛載目錄:mkdir -p /data/gv0
-
使用
glusterfs
類型掛載存儲卷:mount -t glusterfs worker1:/gv0 /data/gv0
-
檢查掛載:
df -h
可以看到輸出:
Filesystem Size Used Avail Use% Mounted on ... worker1:/gv0 466G 8.0G 458G 2% /data/gv0
-
檢查掛載:
mount | grep gv0
顯示輸出:
worker1:/gv0 on /data/gv0 type fuse.glusterfs (rw,relatime,user_id=0,group_id=0,default_permissions,allow_other,max_read=131072)
注解
在實際生產環境,可以采用DNS輪詢的方式,通過DNS解析到多個服務器節點,這樣掛載時即使有服務器節點故障,依然可以通過正常工作的服務器節點獲得glusterfs的掛載信息配置。實際上 worker1
只是提供客戶端下載GlusterFS卷配置信息的服務器節點,客戶端實際上是和集群的所有服務器進行通訊和讀寫數據。
-
測試文件存儲:
for i in `seq -w 1 100`; do cp -rp /var/log/messages /data/gv0/copy-test-$i;done
我估算了一下,12秒鍾復制了 27MB*100 = 2.7GB 數據,大約寫入速度是 245MB/s (連續大文件寫入)
GlusterFS文件分布¶
上述6個brick,按照順序排列,可以在 worker1
節點 /data/brick1/gv0
目錄下看到文件:
copy-test-001 copy-test-004 copy-test-006 copy-test-008 ...
worker2
對應目錄:
copy-test-001 copy-test-004 copy-test-006 copy-test-008 ...
worker3
對應目錄:
copy-test-001 copy-test-004 copy-test-006 copy-test-008 ...
從 worker4
對應目錄開始分布第二個文件:
copy-test-002 copy-test-003 copy-test-005 copy-test-007 ...
worker5
copy-test-002 copy-test-003 copy-test-005 copy-test-007 ...
worker6
copy-test-002 copy-test-003 copy-test-005 copy-test-007 ...
可以看到文件分布是按照文件名進行hash后存放到對應brick上,每個brick是一個完整的文件,所以如果出現某些異常情況,是可以通過直接復制brick中文件來恢復的。
這種 replica
卷中存儲的文件是每個原始文件的完整副本,所以比較容易恢復。如果是采用 dispersed
卷(糾錯卷)(dispersed英文原意是色散),則基於ErasureCodes(糾錯碼),類似RAID5/6。通過配置Redundancy(冗余)級別提高可靠性,在保證較高的可靠性同時,可以提升物理存儲空間的利用率。