Azure的VM的设计中,Disk相关的设计是非常重要的一个内容,本文将介绍Azure上的VM的Disk相关的一些最佳实践和一些小的技巧。
一、Azure VM中Disk的存储账户设计
1. Storage类型的选择
Azure VM的Disk服务是Azure Storage中blob存储服务中的Page Blob。Azure的Storage服务的种类有:
目前,国内还只有LRS、GRS和RA-GRS三种模式。由于LRS的Ingress和Egress的吞吐量比GRS都要大(请参考下面Storage Account的limitation表格),因此如果存储账户是用做VM的Disk,除非有特殊用途,建议采用LRS的模式。
2. Storage Account的名字的设计
Storage Account Name是Storage Account的标识。具体Storage Account在后台的逻辑拓扑结构如下:
而Storage Account的负载均衡是通过Storage Account实现的。不同的Storage Account Name通过DNS解析,到不同的Storage Stamp。因此Storage Account Name的选择在某种程度上会影响Disk的性能。这主要是因为:
a. Azure存储使用分区(Partition)的方案来扩展和负载平衡。
就是说,一部分Storage Account在一个分区内,有可能多个Storage Account解析出来的IP地址都是一个,就是说这些Storage Account在一个分区内。而分区的划分是基于'键'的。而键是由Storage Account Name来决定的。如果客户选择Storage Account的名字比较相似,比如:msftpayroll, msftperformance, msftemployees,或者带时间戳的:log20160101, log20160102, log20160102,这些Storage Account有可能都被分配到同一个partition下。
b. Azure的partition是可以动态调整的。
Azure Storage有自动Balance的功能,当某一个Container的负载过高时,系统会自动进行负载的调整,实现负载均衡。但这个调整的过程中,存储的调用等的时延会增加。
c. 基于上面的讨论,建议在存储账户的设计时,就考虑这些因素。
最佳实践是:仔细检查帐户、容器、blob的命名约定。应该考虑使用散列函数给某些帐户名称前添加3位散列值。比如:5sx-msftpayroll, 79h-msftperformance, n2a-msftemployees,如果企业命名规定中必须使用时间戳或数字标识,建议不要采用简单的前缀添加或后缀添加,这样有可能使所有访问集中到一个Partition上。如果采用时间,建议采用ssmmhh的模式,或在时间前加3位散列值。如果采用数字标识,建议在数字标识前加3位散列值,比如:jha-log20160101, a9g-log20160102, i76-log20160102。在linux bash里,可以通过下面的命令实现随机数:
cat /proc/sys/kernel/random/uuid | md5sum |cut -b 1-3
或者
echo $(date +%t%N)$RANDOM | md5sum | cut -b 1-3
3. Storage Account的高可用设计
如果创建的Storage Account主要是用于VM Disk使用的,那在Storage Account的设计中,高可用性变的至关重要。根据这几年Azure项目中碰到的问题,建议的最佳实践是:
a. VM的Disk分散到不同的Storage Account
一般会把Web、APP的VM Disk分成两组,分别放到Left和Right两个Storage Account。这样万一当有一个Storage Account出现故障时,不会影响所有的VM。另外对于DB的Disk,建议一个DB VM的Disk放到一个存储账户中,如图所示。
b. 同一层VM的Disk放到不同的Storage Account
在a中提到的部署模式下,如果客户的VM数量比较多,这样部署也存在问题:有可能会hit到Storage Account的性能上限,这时会出现VM重启或无法启动的情况,这点在后面会介绍。为了避免这种问题建议将Storage Account再细分,部署如下:
每一组VM分两个Storage Account,尽量将Disk分散部署。
4. Storage Account的容量设计
每个Storage Account都有各种指标的限制,与Disk相关的具体如下:
Resource | Default Limit |
Number of storage accounts per subscription | 200 |
TB per storage account | 500 TB |
Max size of a page blob | 1 TB |
Total Request Rate (assuming 1 KB object size) per storage account | Up to 20,000 IOPS, entities per second, or messages per second |
Target throughput for single blob | Up to 60 MB per second, or up to 500 requests per second |
Max ingress2 per storage account (European and Asian Regions) | 5 Gbps if GRS/ZRS3 enabled, 10 Gbps for LRS |
Max egress2 per storage account (European and Asian Regions) | 10 Gbps if RA-GRS/GRS/ZRS3 enabled, 15 Gbps for LRS |
其中每个Storage Account最大20,000个IOPS。而每个普通Disk的IOPS是500 IOPS。所以当一个Storage Account的Disk超过40个时(40*500 IOPS=20,000 IOPS),VM会出现重启或者不能启动的情况。
因此建议在每个Storage Account里的Disk的数量不要超过20个。由于Storage Account的数量相对比较大,而且没有费用产生,因此在有大量VM的情况下,建议多开Storage Account,以减少每个Storage Account中Disk的数量。
二、Azure VM中Disk挂载的一些技巧
在物理机环境下,Disk在Linux系统中的序号是以这块盘加入VM的顺序决定的。当Azure VM重新启动时,如果VM挂载了多块盘,由可能出现磁盘名称改变的情况。如果在/etc/fstab中挂载采用的是/dev/sdx的方式,有可能出现挂载错误,造成应用不能使用的情况。
解决这个问题的方法有两种:
1.采用在/etc/fstab中采用uuid进行挂载的方式
在完成fdisk和mkfs后,查看分区的uuid:
[root@hwvpntestcentos by-uuid]# pwd/dev/disk/by-uuid[root@hwvpntestcentos by-uuid]# lltotal 0lrwxrwxrwx. 1 root root 10 Feb 7 08:35 4357d916-ea92-49eb-b52e-250bb5ff9e15 -> ../../sdc1lrwxrwxrwx. 1 root root 10 Feb 7 08:33 73115bac-e4f6-4ec4-ab84-c203352ca8f6 -> ../../sdb1lrwxrwxrwx. 1 root root 10 Feb 7 08:33 feab1e37-ed03-4d4f-9734-4d4de8590e34 -> ../../sda1
/etc/fstab的配置如下:
# /etc/fstab# Created by anaconda on Thu Oct 27 14:05:24 2016## Accessible filesystems, by reference, are maintained under '/dev/disk'# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info#UUID=feab1e37-ed03-4d4f-9734-4d4de8590e34 / xfs defaults 0 0UUID=4357d916-ea92-49eb-b52e-250bb5ff9e15 /disk1 ext4 defaults 0 0
挂载fstab中定义的分区:
[root@hwvpntestcentos by-uuid]# mount -a[root@hwvpntestcentos by-uuid]# df -hFilesystem Size Used Avail Use% Mounted on/dev/sda1 30G 1.3G 29G 5% /devtmpfs 1.7G 0 1.7G 0% /devtmpfs 1.7G 0 1.7G 0% /dev/shmtmpfs 1.7G 8.3M 1.7G 1% /runtmpfs 1.7G 0 1.7G 0% /sys/fs/cgroup/dev/sdb1 133G 61M 126G 1% /mnt/resourcetmpfs 345M 0 345M 0% /run/user/1000/dev/sdc1 9.8G 37M 9.2G 1% /disk1
2.采用lvm逻辑卷的方式挂载
lvm分三步:
pvcreate:[root@hwvpntestcentos dev]# pvcreate /dev/sdcPhysical volume '/dev/sdc' successfully created[root@hwvpntestcentos dev]# pvcreate /dev/sddPhysical volume '/dev/sdd' successfully created[root@hwvpntestcentos dev]# pvsPV VG Fmt Attr PSize PFree/dev/sdc lvm2 --- 10.00g 10.00g/dev/sdd lvm2 --- 10.00g 10.00g[root@hwvpntestcentos dev]# pvdisplay'/dev/sdc' is a new physical volume of '10.00 GiB'--- NEW Physical volume ---PV Name /dev/sdcVG NamePV Size 10.00 GiBAllocatable NOPE Size 0Total PE 0Free PE 0Allocated PE 0PV UUID TdVhKK-TDgM-wH52-a9Yd-fXuS-vWRf-6XpvE8 '/dev/sdd' is a new physical volume of '10.00 GiB'--- NEW Physical volume ---PV Name /dev/sddVG NamePV Size 10.00 GiBAllocatable NOPE Size 0Total PE 0Free PE 0Allocated PE 0PV UUID vZB460-GBeB-tgtX-6HGD-BTNY-e0nO-zqnTcU
vgcreate:
[root@hwvpntestcentos dev]# vgcreate data-vg /dev/sdc /dev/sddVolume group 'data-vg' successfully created[root@hwvpntestcentos dev]# vgsVG #PV #LV #SN Attr VSize VFreedata-vg 2 0 0 wz--n- 19.99g 19.99g[root@hwvpntestcentos dev]# vgdisplay--- Volume group ---VG Name data-vgSystem IDFormat lvm2Metadata Areas 2Metadata Sequence No 1VG Access read/writeVG Status resizableMAX LV 0Cur LV 0Open LV 0Max PV 0Cur PV 2Act PV 2VG Size 19.99 GiBPE Size 4.00 MiBTotal PE 5118Alloc PE / Size 0 / 0Free PE / Size 5118 / 19.99 GiBVG UUID iCYHkh-jnPS-6YVT-ox6y-VT2s-vH2P-mCy6fZ
lvcreate:
[root@hwvpntestcentos dev]# lvcreate -i 2 -I 1024 -l 5118 -n data-lv data-vgLogical volume 'data-lv' created.[root@hwvpntestcentos dev]# lvsLV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convertdata-lv data-vg -wi-a----- 19.99g[root@hwvpntestcentos dev]# lvdisplay--- Logical volume ---LV Path /dev/data-vg/data-lvLV Name data-lvVG Name data-vgLV UUID 39jXWa-ncvE-Qz8X-aSKg-1n4o-7uVa-1VxGQELV Write Access read/writeLV Creation host, time hwvpntestcentos, 2017-02-07 08:48:05 +0000LV Status available# open 0LV Size 19.99 GiBCurrent LE 5118Segments 1Allocation inheritRead ahead sectors auto- currently set to 8192Block device 253:0
其中-i表示采用Raid0的方式实现磁盘的逻辑卷。此时在/dev/data-vg中存在data-lv的逻辑卷:
[root@hwvpntestcentos data-vg]# pwd/dev/data-vg[root@hwvpntestcentos data-vg]# lltotal 0lrwxrwxrwx. 1 root root 7 Feb 7 08:48 data-lv -> ../dm-0
对这个逻辑卷进行格式化:
mkfs.ext4 /dev/data-vg/data-lv
编辑/etc/fstab
# /etc/fstab# Created by anaconda on Thu Oct 27 14:05:24 2016## Accessible filesystems, by reference, are maintained under '/dev/disk'# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info#UUID=feab1e37-ed03-4d4f-9734-4d4de8590e34 / xfs defaults 0 0/dev/data-vg/data-lv /disk1 ext4 defaults 0 0
进行挂载:
[root@hwvpntestcentos data-vg]# vim /etc/fstab[root@hwvpntestcentos data-vg]# mount -a[root@hwvpntestcentos data-vg]# df -hFilesystem Size Used Avail Use% Mounted on/dev/sda1 30G 1.3G 29G 5% /devtmpfs 1.7G 0 1.7G 0% /devtmpfs 1.7G 0 1.7G 0% /dev/shmtmpfs 1.7G 8.3M 1.7G 1% /runtmpfs 1.7G 0 1.7G 0% /sys/fs/cgroup/dev/sdb1 133G 61M 126G 1% /mnt/resourcetmpfs 345M 0 345M 0% /run/user/1000/dev/mapper/data--vg-data--lv 20G 45M 19G 1% /disk1
这种情况下,底层disk的磁盘再如何变化,磁盘挂载不会出现问题。