初探GlusterFS-测试卷的类型

2016/10/19

一、、准备工作
1、物理机3台
增加IP映射到hosts文件:
10.0.200.72 node72
10.0.200.73 node73
10.0.200.86 node86

2、分区
如果分区所在设备已经挂载,要先卸载并删掉现有系统。
yum install lvm2 xfsprogs -y   
pvcreate /dev/sdb
vgcreate vg0 /dev/sdb 
lvcreate -l 100%FREE -n lv01 vg0
mkfs.xfs -f -i size=512 /dev/vg0/lv01 
mkdir /data
cat <<_EOF >>/etc/fstab
UUID=$(blkid /dev/vg0/lv01 |cut -d'"' -f2) /data                   xfs     defaults        0 0
_EOF

mount -a
# df -h |grep data
/dev/mapper/vg0-lv01  16T   33M  16T   1% /data

3、调整防火墙
[root@node72 ~]# vim /etc/sysconfig/network
# rpc.statd
-A INPUT -p tcp --dport 111 -j ACCEPT
-A INPUT -p udp --dport 111 -j ACCEPT

# glusterd
-A INPUT -p tcp -m tcp --dport 24007 -j ACCEPT

# portmapper
-A INPUT -p tcp -m tcp --dport 38465 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 38466 -j ACCEPT

# nfs
-A INPUT -p tcp -m tcp --dport 38467 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 2049  -j ACCEPT
-A INPUT -p tcp -m tcp --dport 38469 -j ACCEPT

# nrpe
-A INPUT -p tcp --dport 5666 -j ACCEPT

# status
-A INPUT -p tcp -m tcp --dport 39543 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 55863 -j ACCEPT

# nlockmgr
-A INPUT -p tcp -m tcp --dport 38468 -j ACCEPT
-A INPUT -p udp -m udp --dport 963   -j ACCEPT
-A INPUT -p tcp -m tcp --dport 965   -j ACCEPT

# ctdbd
-A INPUT -p tcp -m tcp --dport 4379  -j ACCEPT

# smbd
-A INPUT -p tcp -m tcp --dport 139   -j ACCEPT
-A INPUT -p tcp -m tcp --dport 445   -j ACCEPT

# Ports for gluster volume bricks (default 100 ports)
-A INPUT -p tcp -m tcp --dport 24009:24108 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 49152:49251 -j ACCEPT



4、服务安装
[root@node72 ~]# yum install glusterfs-server -y
[root@node72 ~]# service glusterd start
[root@node72 ~]# chkconfig glusterd on

5、peer probe
[root@node72 ~]# gluster peer probe node73
peer probe: success
[root@node72 ~]# gluster peer probe node86
peer probe: success


二、配置:2分散,3副本,2条带。
需要的brick大小为:2(分散) x 2(条带) x 3(镜像) = 12
在3个节点上创建多个目录来测试:
# mkdir /data/gv0/brick{1,2,3,4} -p
# cd /data/gv0

在其中1个节点执行:
[root@node72 gv0]# gluster volume create gv0 stripe 2 replica 3 transport tcp \
node72:/data/gv0/brick1 node73:/data/gv0/brick1 node86:/data/gv0/brick1 \
node72:/data/gv0/brick2 node73:/data/gv0/brick2 node86:/data/gv0/brick2 \
node72:/data/gv0/brick3 node73:/data/gv0/brick3 node86:/data/gv0/brick3 \
node72:/data/gv0/brick4 node73:/data/gv0/brick4 node86:/data/gv0/brick4


[root@node72 gv0]# gluster volume start gv0
[root@node72 gv0]# gluster volume info
 
Volume Name: gv0
Type: Distributed-Striped-Replicate
Volume ID: 83f759f9-2dad-433c-ae5d-d608c9d88a46
Status: Started
Number of Bricks: 2 x 2 x 3 = 12
Transport-type: tcp
Bricks:
Brick1: node72:/data/gv0/brick1
Brick2: node73:/data/gv0/brick1
Brick3: node86:/data/gv0/brick1
Brick4: node72:/data/gv0/brick2
Brick5: node73:/data/gv0/brick2
Brick6: node86:/data/gv0/brick2
Brick7: node72:/data/gv0/brick3
Brick8: node73:/data/gv0/brick3
Brick9: node86:/data/gv0/brick3
Brick10: node72:/data/gv0/brick4
Brick11: node73:/data/gv0/brick4
Brick12: node86:/data/gv0/brick4

查看当前brick是怎么分配数据的:
[root@node72 gv0]# cat /var/lib/glusterd/vols/gv0/trusted-gv0-fuse.vol  
(部分输出的信息省略)     
--------------------------------------------
####
# 按照我们create gv0时提供的brick的顺序,分别映射为gv0-client-0 -> gv0-client-11 
#
volume gv0-client-0
    option remote-subvolume /data/gv0/brick1
    option remote-host node72
end-volume

volume gv0-client-1
    option remote-subvolume /data/gv0/brick1
    option remote-host node73
end-volume

volume gv0-client-2
    option remote-subvolume /data/gv0/brick1
    option remote-host node86
end-volume

volume gv0-client-3
    option remote-subvolume /data/gv0/brick2
    option remote-host node72
end-volume

volume gv0-client-4
    option remote-subvolume /data/gv0/brick2
    option remote-host node73
end-volume

volume gv0-client-5
    option remote-subvolume /data/gv0/brick2
    option remote-host node86
end-volume

volume gv0-client-6
    option remote-subvolume /data/gv0/brick3
    option remote-host node72
end-volume

volume gv0-client-7
    option remote-subvolume /data/gv0/brick3
    option remote-host node73
end-volume

volume gv0-client-8
    option remote-subvolume /data/gv0/brick3
    option remote-host node86
end-volume

volume gv0-client-9
    option remote-subvolume /data/gv0/brick4
    option remote-host node72
end-volume

volume gv0-client-10
    option remote-subvolume /data/gv0/brick4
    option remote-host node73
end-volume

volume gv0-client-11
    option remote-subvolume /data/gv0/brick4
    option remote-host node86
end-volume

--------------------------------------------
####
# 我们设置了3个副本,因此相邻的3个gv0-client组成一个镜像(replicate)组,合计4个:gv0-replicate-0 -> gv0-replicate-3
#
volume gv0-replicate-0
    subvolumes gv0-client-0 gv0-client-1 gv0-client-2
end-volume

volume gv0-replicate-1
    subvolumes gv0-client-3 gv0-client-4 gv0-client-5
end-volume

volume gv0-replicate-2
    subvolumes gv0-client-6 gv0-client-7 gv0-client-8
end-volume

volume gv0-replicate-3
    subvolumes gv0-client-9 gv0-client-10 gv0-client-11
end-volume

--------------------------------------------
####
# 我们设置了2个条带,因此相邻的2个gv0-replicate组成一个条带(stripe)组,合计2个:gv0-stripe-0 -> gv0-stripe-1
#
volume gv0-stripe-0
    subvolumes gv0-replicate-0 gv0-replicate-1
end-volume

volume gv0-stripe-1
    subvolumes gv0-replicate-2 gv0-replicate-3
end-volume
--------------------------------------------
####
# 默认的行为是分散,因此相邻的2个gv0-stripe组成一个分散(distribute)组gv0-dht。
#
volume gv0-dht
    type cluster/distribute
    subvolumes gv0-stripe-0 gv0-stripe-1
end-volume

--------------------------------------------
############################################
# 分别对应:
# gv0-client-0 -> gv0-client-1 -> gv0-client-2
# ...
node72:/data/gv0/brick1 node73:/data/gv0/brick1 node86:/data/gv0/brick1
node72:/data/gv0/brick2 node73:/data/gv0/brick2 node86:/data/gv0/brick2
node72:/data/gv0/brick3 node73:/data/gv0/brick3 node86:/data/gv0/brick3
node72:/data/gv0/brick4 node73:/data/gv0/brick4 node86:/data/gv0/brick4
#
#
# 猜测:如果写入文件A1,A2,A3,A4,A5等,则有如下表现,
# A1 -> 分散 到 gv0-dht/gv0-stripe-0
------------切割 为 2个数据块(因为stripe=2)分别写入:gv0-replicate-0 和 gv0-replicate-1
----------------若写入:gv0-replicate-0
--------------------复制 到 3个brick中(因为replica=3):gv0-client-0 gv0-client-1 gv0-client-2【对应brick1】
----------------若写入:gv0-replicate-1
--------------------复制 到 3个brick中(因为replica=3):gv0-client-3 gv0-client-4 gv0-client-5【对应brick2】

# A2 分散 到 gv0-dht/gv0-stripe-1
------------切割 为 2个数据块(因为stripe=2)分别写入:gv0-replicate-2 和 gv0-replicate-3
----------------若写入:gv0-replicate-2
--------------------复制 到 3个brick中(因为replica=3):gv0-client-6 gv0-client-7 gv0-client-8【对应brick3】
----------------若写入:gv0-replicate-3
--------------------复制 到 3个brick中(因为replica=3):gv0-client-9 gv0-client-10 gv0-client-11【对应brick4】

# A3 分散 到 gv0-dht/gv0-stripe-0
# A4 分散 到 gv0-dht/gv0-stripe-1
# A5 分散 到 gv0-dht/gv0-stripe-0

预测:
1)循环写入条带组的成员中
2)镜像,3份容量一致的数据块
3)条带,大约为文件大小的一半
4)卷的容量:
A1-> A1.m + A1.n
-- A1.m -> R0
---- R0 -> C0/C1/C2
-- A1.n -> R1

因此,
容量(R0) = 容量(C0)
容量(gv0) = 容量(R0+R1+R2+R3)= 16T * 4 = 64T




三、客户端测试
配置hosts解析上述3个节点
10.0.200.72 node72
10.0.200.73 node73
10.0.200.86 node86

# yum install glusterfs-fuse -y 
# mount -t glusterfs 10.0.200.72:/gv0 /mnt
# df -h |grep mnt
10.0.200.72:/gv0   64T  131M   64T   1% /mnt

【测试1】dd写5个文件“A1->A6”,看下文件是怎么分布的:
# dd if=/dev/zero of=/mnt/A1 bs=1024 count=32000      
# dd if=/dev/zero of=/mnt/A2 bs=1024 count=24000 
# dd if=/dev/zero of=/mnt/A3 bs=1024 count=20000 
# dd if=/dev/zero of=/mnt/A4 bs=1024 count=16000 
# dd if=/dev/zero of=/mnt/A5 bs=1024 count=12000 
# dd if=/dev/zero of=/mnt/A6 bs=1024 count=160000 

服务端:(3个节点表现一致,只列出一个节点上的输出内容)
============
[root@node86 gv0]# find . -type f -name 'A*' -exec ls -l {} \; |sort -n -k5
-rw-r--r-- 2 root root 12189696 Sep 24 11:24 ./brick3/A5
-rw-r--r-- 2 root root 12288000 Sep 24 11:24 ./brick4/A5
-rw-r--r-- 2 root root 16252928 Sep 24 11:23 ./brick4/A4
-rw-r--r-- 2 root root 16384000 Sep 24 11:23 ./brick3/A4
-rw-r--r-- 2 root root 20447232 Sep 24 11:23 ./brick4/A3
-rw-r--r-- 2 root root 20480000 Sep 24 11:23 ./brick3/A3
-rw-r--r-- 2 root root 24510464 Sep 24 11:22 ./brick1/A2
-rw-r--r-- 2 root root 24576000 Sep 24 11:22 ./brick2/A2
-rw-r--r-- 2 root root 32636928 Sep 24 11:14 ./brick3/A1
-rw-r--r-- 2 root root 32768000 Sep 24 11:14 ./brick4/A1
-rw-r--r-- 2 root root 163708928 Sep 24 11:36 ./brick1/A6
-rw-r--r-- 2 root root 163840000 Sep 24 11:36 ./brick2/A6

小结:
1)循环写入条带组的成员中【不符合】
A1 -> brick3+brick4 -> gv0-stripe-1
A2 -> brick1+brick2 -> gv0-stripe-0
A3 -> brick3+brick4 -> gv0-stripe-1
A4 -> brick3+brick4 -> gv0-stripe-1
A5 -> brick3+brick4 -> gv0-stripe-1
A6 -> brick1+brick2 -> gv0-stripe-0

判断:随机分散到某个stripe组中

2)镜像【符合预期】
观察发现,所有的./brick3/A1的文件大小一致,./brick4/A1的大小也一致,说明是镜像。

3)条带【不符合】
dd生成的文件大小比较奇怪,例如A1,文件大小:32M,可是:
./brick3/A1:32636928
./brick4/A1:32768000
2个数据块的大小都接近32M,且其中一个数据块是和完整的文件大小一致。

【测试2】接着,我们再次测试写入几个小文件
# for i in `seq 1 1000`;do echo $i >>/mnt/B1;done  
# for i in `seq 1 10000`;do echo $i >>/mnt/B2;done
# for i in `seq 1 100000`;do echo $i >>/mnt/B3;done
# cat /mnt/B3 >>/mnt/B4 && cat /mnt/B3 >>/mnt/B4
# cat /mnt/B4 >>/mnt/B5 && cat /mnt/B4 >>/mnt/B5
# ll /mnt/ -h
total 5.5M
-rw-r--r-- 1 root root 3.9K Sep 24 12:19 B1
-rw-r--r-- 1 root root  48K Sep 24 12:20 B2
-rw-r--r-- 1 root root 576K Sep 24 12:05 B3
-rw-r--r-- 1 root root 1.2M Sep 24 12:28 B4
-rw-r--r-- 1 root root 2.3M Sep 24 12:32 B5

服务端:(3个节点表现一致,只列出一个节点上的输出内容)
============
# find . -type f -name 'B*' -exec ls -lh {} \; |sort -k3 -t'/'
-rw-r--r-- 2 root root 0 Sep 24 12:19 ./brick2/B1
-rw-r--r-- 2 root root 3.9K Sep 24 12:19 ./brick1/B1
-rw-r--r-- 2 root root 0 Sep 24 12:19 ./brick2/B2
-rw-r--r-- 2 root root 48K Sep 24 12:20 ./brick1/B2
-rw-r--r-- 2 root root 512K Sep 24 12:04 ./brick4/B3
-rw-r--r-- 2 root root 576K Sep 24 12:05 ./brick3/B3
-rw-r--r-- 2 root root 1.0M Sep 24 12:28 ./brick4/B4
-rw-r--r-- 2 root root 1.2M Sep 24 12:28 ./brick3/B4
-rw-r--r-- 2 root root 2.2M Sep 24 12:32 ./brick3/B5
-rw-r--r-- 2 root root 2.3M Sep 24 12:32 ./brick4/B5


【测试3】测试一个大文件
# find . -type f -name 'C*' -exec ls -lh {} \; |sort -k3 -t'/' 
-rw-r--r-- 2 vdsm kvm 4.2G Jul 24  2014 ./brick1/CentOS-6.5-x86_64-bin-DVD1.iso
-rw-r--r-- 2 vdsm kvm 4.2G Jul 24  2014 ./brick2/CentOS-6.5-x86_64-bin-DVD1.iso

到此为止,我们都在迷惑,为何会在2个条带中出现2个文件大小几乎和源文件都相等的文件呢?

可能大文件更容易观察,我们很快发现,假设上面的文件大小是真实的,则和df的结果表现的不一致:
# df -h /data
Filesystem            Size  Used Avail Use% Mounted on
/dev/mapper/vg0-lv01   16T  6.3G   16T   1% /data

开始好奇,为何实际容量是6.3G,赶紧去data目录看一下:
# du -h /data/gv0/ |grep G
3.2G    /data/gv0/brick1/.glusterfs/1f/86
3.2G    /data/gv0/brick1/.glusterfs/1f
3.2G    /data/gv0/brick1/.glusterfs
3.2G    /data/gv0/brick1
3.2G    /data/gv0/brick2/.glusterfs/1f/86
3.2G    /data/gv0/brick2/.glusterfs/1f
3.2G    /data/gv0/brick2/.glusterfs
3.2G    /data/gv0/brick2
6.3G    /data/gv0/

原来,gluster已经将文件切割为2个数据块

到此,我们可以再度小结一下:
1)存在多个数据组时,随机分散到某个组
2)存在指定的镜像数量和条带
3)关于组合方式的解释
Number of Bricks: 2 x 2 x 3 = 12
意味着:2(分散) x 2(条带) x 3(镜像)

配置
gluster volume create gv0 replica 3 transport tcp \
node72:/data/gv0/brick1 node73:/data/gv0/brick1 node86:/data/gv0/brick1

则意味着:1(分散)x 3(镜像)

配置
gluster volume create gv0 replica 3 transport tcp \
node72:/data/gv0/brick1 node73:/data/gv0/brick1 node86:/data/gv0/brick1 \
node72:/data/gv0/brick2 node73:/data/gv0/brick2 node86:/data/gv0/brick2

则意味着:2(分散)x 3(镜像)

其他组合,依此类推。




四、清理数据
[root@node72 gv0]# gluster volume stop gv0
[root@node72 gv0]# gluster volume delete gv0
每台主机上:
# find /data/gv0 -delete








五、排错
【Q1】、启动 glusterd 报错:/usr/lib64/glusterfs/3.4.4/rpc-transport/rdma.so: cannot open shared object file: No such file or directory
A:之前使用过其他版本的glusterfs,因此/var/lib/glusterd目录需要移除。
# mv /var/lib/glusterd /tmp/glusterd_old
# service glusterd start
Starting glusterd:                                         [  OK  ]


【Q2】、创建卷时报错 volume create: gv0: failed: /data/gv0/brick1 or a prefix of it is already part of a volume
A:之前创建卷时,报错,
volume create: gv0: failed
因此,有信息遗留,需要清理。
# cd /data/gv0/brick1
# attr -lq .
glusterfs.volume-id
# setfattr -x trusted.glusterfs.volume-id .

或者批量:
# cd /data/gv0
# for i in `ls .`; do setfattr -x trusted.glusterfs.volume-id $i; done



【Q3】、因为挂载卷时报错,域名解析异常
A:挂载的gluster节点是通过域名提供服务的,因此,需要配置客户端能正常解析集群中所有节点的域名。