上公有云都会谈到云原生架构。其中重要一点就是计算与存储的解耦合。这就意味着在架构里要尽可能把数据与计算分离,让计算可以随时随地访问到数据。
Azure提供了File Storage来实现共享数据存储,但是有两个比较大的限制:1、对Linux支持有版本要求,需要较高版的Linux才能支持;2、单个File Share有容量限制,最大不能超过5TB。
对于很对用户,如果Linux版本较低或者对共享容量有较大要求时,File Storage就无法满足要求了。而Blob Storage没有容量限制(500TB),但却无法直接在Linux里当做文件系统使用。不过还好,有其他的解决方式方便的实现在Linux里挂载Blob,这就是Blobfuse。
Blobfuse的配置使用
fuse是一个开源的文件系统适配器,可以方便的挂载Linux不能原生支持的文件系统。而Blobfuse就是fuse的扩展,实现了Linux里操作Blob。
Azure上有一篇文档介绍fuse的使用:
如何使用 Blobfuse 将 Blob 存储装载为文件系统
但是这篇文档有些小问题,完全照做可能做不通,下边以CentOS为例,详细描述安装使用的方法。
Blobfuse的安装
先在Azure.com上创建一台CentOS6.9的虚机和一个存储账户,并在存储账户中创建一个Container:
现在Container里是空的.
登录到创建的虚机,按照文档说明说先添加MS的Linux软件库(如果是CentOS或RedHat7,请将如下链接的6改为7):sudo rpm -Uvh https://packages.microsoft.com/config/rhel/6/packages-microsoft-prod.rpm
然后安装Blobfuse:sudo yum install -y blobfuse
这里文档有个错误,还需要安装fuse,否则运行可能会报错:sudo yum install -y fuse
Blobfuse的配置
为了防止网络问题导致写入不成功,Blobfuse采用了本地缓存机制,将本地目录作为缓存,操作文件时,首先将文件放到这个缓存目录里,然后再进行文件系统操作。
为了保证性能,建议使用内存虚拟的ramdisk或者Azure的临时盘空间来做缓存。本文档里,采用临时盘缓存的方式。
Centos下,临时盘默认挂载在/mnt/resource目录下,我们在此目录下创建缓存目录,并将目录的宿主改为当前用户:sudo mkdir /mnt/resource/tmp
sudo chown blobfusevm /mnt/resource/tmp
现在需要配置mount的blob信息,包含认证信息(AccountName、AccountKey,不会找这些信息的好好看一下存储账户介绍),需要mount的container等。
这些新科可以通过环境变量设置,也可以通过配置文件设置,这里采用配置文件的方式。
创建一个配置文件(fuse.cfg):vi fuse.cfg
文件内容如下:
accountName blobfusesa
accountKey WGujAXmp+ifX/4I+WW6fwUT2eVouE7nHocnfL/3JJdHBksZr2pLG10cVp5vsP5MNbGM+bhJhT5ivhrRHaHvJCw==
containerName blobfusecontainer
创建一个目录用作挂载Blob:mkdir blobdir
挂载Blob
现在可以执行命令挂载Blob:blobfuse ~/blobdir --tmp-path=/mnt/resource/tmp --config-file=./fuse.cfg -o attr_timeout=240 -o entry_timeout=240 -o negative_timeout=120
却出现了权限问题。
产生这个问题的原因是安装blobfuse时,默认创建了一个名为 fuse的组,只有在这个组里的用户才能执行:more /etc/group
把当前用户添加到这个组:sudo usermod -a -G fuse blobfusevm
重新登录后,再次挂载:
挂载成功。
进入该目录并创建一个文件file01:cd blobdir
touch file01
再到azure的portal上检查container的内容:
在Linux下创建的文件出现了,说明目录与container的对应关系确实存在,挂载是成功的。
往前再走一步
关于容量的那些问题
在CentOS里检查文件系统容量:df -k
挂载的blob的容量只有大约8GB,远远没到存储账户的上限500TB,甚至连File Storage的单个共享容量5TB都没达到。为什么会这样?
产生的原因是我们选择了VM的临时盘来做缓存空间,而虚机的size是B2s,分配的临时盘是8GB,所以这里文件系统的容量显示为8GB。
那么,如果我们要存放的数据要大于缓存空间会出现什么情况?其实并不会影响,缓存只是暂时存处数据,里边的数据如果已经上传到blob,并且不再使用后,会自动删除,腾出空间来使用。
对此做一个测试,在挂载目录下生成一个4GB的文件:dd if=/dev/zero bs=1MB of=file02 count=4000
可以看到在缓存目录下也生成了同样文件,占用了大约4GB空间。
查看虚机的metrics,文件创建后,网络流量开始突然增大,持续往Blob写入:
同样,磁盘先有大量写入(生成文件),然后大量读出(传到Blob):
再查看缓存使用情况,容量已经空出,并且缓存目录下的文件消失(被自动清除):
缓存目录下的文件被清除的时间可以通过挂载时的参数–file-cache-timeout-in-seconds=指定,单位为秒,默认120.当文件关闭超过这个时间会被自动删除。
缓存目录的设计可以大大提高Blob文件操作效率,避免网络影响。但是设置缓存目录时一定要注意容量大小,需要超过同时操作的所有文件总和。如果临时盘空间不满足,可以挂载一块大容量的空余磁盘设置为缓存目录,满足需求。
关于月饼的特殊性
在Azure.cn(Mooncacke,俗称月饼)上进行同样测试:
却出现错误,无法连接到container。
仔细想想配置过程中对blob的配置,只提供了存储账户名和秘钥,没有关于路径的信息。因为木人情况下Blobfuse会去连接Global Azure,所以无需关于路径的信息。
而MC不一样,采用了不同的Endpoint格式,所以用默认配置,Blobfuse无法找到对应的Container。
找到问题就有了解决方法,在配置文件里加上对应的Endpoint即可:
再去挂载就没问题了:
这给了一个启发,Blobfuse访问Blob是通过http或https的方式,理论上可以跨wan,在不同region甚至on-premise的Linux上去挂载Blob。现在测试是否可行。
将MC上的配置文件传到Global的虚机:scp ./fuse.cfg [email protected]:~/mcfuse.cfg
在Global的虚机上用新的配置文件挂载:
生成一个文件并在MC的portal检查:
由于是个空文件,所以很快就上传到了MC的Container。
小小的总结一下
通过测试,充分说明可以将Blob当做共享存储挂载到Linux里。不收Linux版本限制,并且空间足够大。
由于挂载方式是通过http或https,可以跨广域网,而且不会受到445端口的影响。
缓存目录的设置是个需要注意的地方,避免容量不都导致的问题。
其他一些配置细节,例如权限管理、加密传输等,可以参考Blobfuse的主页:
Blobfuse主页