MooseFS使用总结
2010-12-08 12:55:12 阿炯

流行的开源分布式文件系统比较

现在有海量的数据文件(1000万个文件)需要存储,需要让其他计算机可以很容易地访问,数据无价,还希望这个文件系统带冗余功能。首先注意到的是Ubuntu Enterprise Cloud的提供者:Eucalyptus。它提供了和AWS(Amazon Web Service)几乎完全兼容的云计算接口,看起来似乎是个云存储的靠谱解决方案。

Eucalyptus模仿Amazon的S3服务,提供了一个叫做 Walrus的存储服务组件。可是经过一番探索,我发现Eucalyptus想说爱你不容易。一方面是因为Eucalyptus配置起来很麻烦,缺乏文档,网上几乎找不到任何相关帮助;另一方面,虽然理论上Eucalyptus和AWS的EC2/S3兼容,但实际上并非如此,很多在AWS上可以用的工具,在Eucalyptus上就无法使用最关键是,直到最后我把Walrus配置完成之后,才发现Walrus根本不像我想的那样,是一个带冗余的云存储系统。而只是一个实现了S3接口的单机软件而已。实际上Walrus和Eucalyptus的另一个组件sc(storage controller)没有任何关联,Walrus只是提供了和S3一致的接口,而它的实现方式,既不带冗余,也不能分开部署在多台服务器上。于是我开始寻找一个真正的分布式文件系统,来解决我的存储难题。

一找才发现,市面上各种分布式文件系统品种繁多,层出不穷。列举几个主要的:mogileFS:Key-Value型元文件系统,不支持FUSE,应用程序访问它时需要API,主要用在web领域处理海量小图片,效率相比 mooseFS高很多。

FastDFS:国人在mogileFS的基础上进行改进的key-value型文件系统,同样不支持FUSE,提供比 mogileFS更好的性能。

mooseFS:支持FUSE,相对比较轻量级,对master服务器有单点依赖,用c编写,性能相对较好,国内用的人比较多glusterFS:支持FUSE,比mooseFS庞大。

ceph:支持FUSE,客户端已经进入了linux-2.6.34内核,也就是说可以像ext3/rasierFS一样,选择ceph为文件系统。彻底的分布式,没有单点依赖,用C编写,性能较好。基于不成熟的btrfs,其本身也非常不成熟。

lustre:Oracle公司的企业级产品,非常庞大,对内核和ext3深度依赖。

NFS:老牌网络文件系统,具体不了解,反正NFS最近几年没发展,肯定不能用。本来我打算用mogileFS,因为它用的人最多,而且我的主要需求都是在web方面。

但是研究了它的api之后发现,Key-Value型文件系统没有目录结构,导致不能用list某个子目录的所有文件,不能直接像本地文件系统一样操作,干什么事情都需要一个api,让人十分不爽。mogileFs这种做法,可能是受同一个开发团队的另一个大名鼎鼎的产品memcached的侦听端口+api模式影响,也有可能是 mogileFS刚开始设计的时候,FUSE还没有开始流行。

总之要找一个支持FUSE的分布式文件系统,最后就在mooseFS, glusterFS, ceph中选择。从技术上来看,ceph肯定是最棒的,用c编写,进入linux-2.6.34内核,基于btrfs文件系统,保证了它的高性能,而多台 master的结构彻底解决了单点依赖问题,从而实现了高可用。可是ceph太不成熟了,它基于的btrfs本身就不成熟,它的官方网站上也明确指出不要把ceph用在生产环境中。

而glusterFS比较适合大型应用,口碑相对较差,因此也不考虑。最后我选择了缺点和优点同样明显的mooseFS。虽然它有单点依赖,它的 master非常占内存。但是根据我的需求,mooseFS已经足够满足我的存储需求。国内mooseFS的人比较多,并且有很多人用在了生产环境,更加坚定了我的选择。

一、MFS介绍:
Distinctive features of MooseFS are:

MooseFS优越特性如下:
- higher reliability (data can be stored in several copies on separate computers)
高可用性(数据可以存储在多个机器上的多个副本)

- dynamically expanding disk space by attaching new computers/disks
可动态扩展随时新增加机器或者是磁盘

- possibility of storing deleted files for a defined period of time ("trash bin" service on a file system level)
可回收在指定时间内删除的文件(“垃圾回收站”是一个系统级别的服务)

- possibility of creating snapshot of a file, which means coherent copy of the whole file, even while the file is being written.
可以对整个文件甚至在正在写入的文件创建文件的快照。

MFS文件系统结构: 包含4种角色: 
管理服务器managing server (master) :负责各个数据存储服务器的管理,文件读写调度,文件空间回收以及恢复.多节点拷贝。

single computer managing the whole filesystem,storing metadata for every file (information on size, attributes and file localisation(s), including all information about non-regular files, i.e.directories, sockets, pipes and devices).

单个机器管理整个文件系统,用来存储记录每一个文件的Metadata(记录文件的大小、文件的属性、文件的位置,也包括非规则文件的系统,如目录、sockets、管道和设备)

元数据日志服务器Metalogger server(Metalogger):负责备份master服务器的变化日志文件,文件类型为changelog_ml.*.mfs,以便于在master server出问题的时候接替其进行工作。

数据存储服务器data servers (chunkservers)  :负责连接管理服务器,听从管理服务器调度,提供存储空间,并为客户提供数据传输。

客户机挂载使用client computers  :通过fuse内核接口挂接远程管理服务器上所管理的数据存储服务器,.看起来共享的文件系统和本地unix文件系统使用一样的效果。

说说mfs优势:

0. 通用文件系统,不需要修改上层应用就可以使用(支持fuse)。
1. 可以在线扩容,体系架构可伸缩性极强。
2. 部署简单。
3. 体系架构高可用,除开master组件无单点故障。
4. 文件对象高可用,可设置任意的文件冗余程度,而绝对不会影响读或者写的性能。
5. 提供Windows回收站的功能。
6. 提供类似Java语言的 GC(垃圾回收)。
7. 提供netapp,emc,ibm等商业存储的snapshot特性。
8. google filesystem的一个c实现。
9. 提供web gui监控接口。
10. 提高随机读或写的效率。
11. 提高海量小文件的读写效率。
可能的瓶颈:
0). master本身的性能瓶颈。mfs系统master存在单点故障如何解决?网上有人提供moosefs+drbd+heartbeat 来保证master单点问题?不过在使用过程中不可能完全不关机和间歇性的网络中断!
短期对策:按业务切分

1). 体系架构存储文件总数的可遇见的上限。(mfs把文件系统的结构缓存到master的内存中,个人认为文件越多,master的内存消耗越大,8g对应2500kw的文件数,2亿文件就得64GB内存 )。
短期对策:按业务切分

2). 单点故障解决方案的健壮性。

二、mfs各元素主要配置文件

1、master
主服务器
Metadata is stored in memory of the managing server and simultaneously is being saved on disk (as a periodically updated binary file and immediately updated incremental logs). The main binary file as well as the logs are replicated to metaloggers (if present).

Metadata元数据存储在master服务器的内存中,同时也保存在磁盘上(作为一个定期更新的二进制文件,并实时的更新changelog日志)。如果存在metaloggers的话,主要的二进制文件以及日志也复制到metaloggers中。

How much CPU/RAM resources are used?
消耗多少CPU和内存资源

In our environment (ca. 500 TiB, 25 million files, 2 million folders distributed on 26 million chunks on 70 machines) the usage of chunkserver CPU (by constant file transfer) is about 15-20% and chunkserver RAM usually consumes about 100MiB (independent of amount of data).

在我们的测试环境中(大约500 TiB的数据,250万份文件,200万文件夹,分成260万块分布在70机器上),chunkserver的CPU使用情况为(持续的文件传输)约为15-20%同时chunkserver内存使用100MiB(和数据量的多少无关)。

The master server consumes about 30% of CPU (ca. 1500 operations per second) and 8GiB RAM. CPU load depends on amount of operations and RAM on number of files and folders.

master服务器消耗约30%的CPU(每秒钟约1500次操作)和8G的内存。 CPU负载取决于操作的次数,内存的使用取决于文件和文件夹的个数。

File data is divided to fragments (chunks) of maximum size 64MB each which are stored as files on selected disks on data servers (chunkservers). Each chunk is saved on different computers in a number of copies equal to a "goal" for the given file.

文件数据是按块为单位(块的最大大小64MB以上)存储在数据服务器(chunkservers)上指定磁盘上。如果设置的goal的存储分数和机器个数相同,不同的块儿会存储在每一个机器上。

What sort of sizing is required for the Master  server?
对Master主服务器有什么需求?

The most important factor is RAM of mfsmaster machine, as the full file system structure is cached in RAM for speed. Besides RAM mfsmaster machine needs some space on HDD for main metadata file together with incremental logs.
最重要的因素就是mfsmaster机器的内存,因为整个文件系统结构都缓存到内存中以便加快访问速度。除了内存mfsmaster机器还需要一定硬盘大小用来存储Metadata数据和增长的日志文件。

The size of the metadata file is dependent on the number of files (not on their sizes). The size of incremental logs depends on the number of operations per hour, but length (in hours) of this incremental log is configurable.
Metadata文件的大小是取决于文件数的多少(而不是他们的大小)。changelog日志的大小是取决于每小时操作的数目,但是这个时间长度(默认是按小时)是可配置的。

1 million files takes approximately 300 MiB of RAM. Installation of 25 million files requires about 8GiB of RAM and 25GiB space on HDD.
100万文件大约需要300M内存。25百万份文件大约需要8GiB内存和25GiB硬盘空间。

master主要文件
mfsmaster.cfg
configuration file for MooseFS master process

参数说明如下:
#WORKING_USER和WORKING_GROUP:是运行master server的用户和组;
#SYSLOG_IDENT:是master server在syslog中的标识,也就是说明这是由master server产生的;
#LOCK_MEMORY:是否执行mlockall()以避免mfsmaster 进程溢出(默认为0,即否);
#NICE_LEVE:运行的优先级(如果可以默认是 -19; 注意: 进程必须是用root启动);
#EXPORTS_FILENAME:被挂接目录及其权限控制文件的存放位置
#DATA_PATH:metadata files and lock file存放路径,此目录下大致有以下文件:metadata,changelog,sessions,stats,lock。
#BACK_LOGS:metadata的change log文件数目(默认是 50);
#REPLICATIONS_DELAY_INIT:(initial delay in seconds before starting replications)初始延迟复制的时间(默认是300s);
#REPLICATIONS_DELAY_DISCONNECT:(replication delay in seconds after chunkserver disconnection) chunkserver断开后复制延迟(默认是3600s);
# MATOML_LISTEN_HOST:用于metalogger连接的IP地址(默认是*,代表任何IP);
# MATOML_LISTEN_PORT:监听metalogger请求的端口地址(默认是9419);
# MATOCS_LISTEN_HOST:用于chunkserver连接的IP地址(默认是*,代表任何IP);
# MATOCS_LISTEN_PORT:监听chunkserver连接的端口地址(默认是9420);
# MATOCU_LISTEN_HOST:用于客户端挂接连接的IP地址(默认是*,代表任何IP);
# MATOCU_LISTEN_PORT:监听客户端挂载连接的端口地址(默认是9421);
# CHUNKS_LOOP_TIME :(Chunks loop frequency in seconds)chunks的回环频率(默认是:300秒);
# CHUNKS_DEL_LIMIT:(Maximum number of chunks to delete in one loop)在一个loop中可以删除chunks的最大数 (默认:100)
# CHUNKS_WRITE_REP_LIMIT:(Maximum number of chunks to replicate to one chunkserver in one loop)在一个loop里复制到一个chunkserver的最大chunk数目(默认是1)
# CHUNKS_READ_REP_LIMIT:(Maximum number of chunks to replicate from one chunkserver in one loop)在一个loop里从一个chunkserver复制的最大chunk数目(默认是5)
# REJECT_OLD_CLIENTS:弹出低于1.6.0的客户端挂接(0或1,默认是0)

mfsexports.cfg
MooseFS access control file
地址可以指定的几种表现形式:所有ip,单个ip,IP网络地址/位数掩码,IP网络地址/子网掩码,ip段范围。

权限部分:
ro  只读模式共享
rw  读写方式共享
alldirs  许挂载任何指定的子目录
maproot   映射为root,还是指定的用户
password  指定客户端密码

.mfsmaster.lock
lock file of running MooseFS master process
mfsmaster.lock文件记录正在运行的MooseFS 的主进程

metadata.mfs, metadata.mfs.back
MooseFS filesystem metadata image
metadata.mfs, metadata.mfs.back是MooseFS文件系统的元数据metadata的镜像

changelog.*.mfs
MooseFS filesystem metadata change logs (merged into metadata.mfs once per hour)
changelog.*.mfs 是MooseFS文件系统元数据的改变日志(每一个小时合并到metadata.mfs中一次)

The size of the  metadata file is dependent on the number of files (not on their sizes). The size of incremental logs depends on the number of operations per hour。
Metadata文件的大小取决于文件数(而不是他们的大小),Changelog的大小取决于每小时的操作次数。

2、metalogger
主要文件:
mfsmetalogger.cfg

# WORKING_USER = mfs
# WORKING_GROUP = mfs
# SYSLOG_IDENT = mfsmetalogger
# LOCK_MEMORY = 0
# NICE_LEVEL = -19
# DATA_PATH = /usr/local/mfs/var/mfs
# BACK_LOGS = 50

META_DOWNLOAD_FREQ = 1 # metadata download frequency in hours (default is 24, at most BACK_LOGS/2) 。metadata元数据下载间隔时间(默认是24小时,单位是小时,至多是BACK_LOGS的1/2)
# MASTER_RECONNECTION_DELAY = 5   # delay in seconds before trying to reconnect to master after disconnection。在失去连接之后延迟多少秒重新连接master
MASTER_HOST = 192.168.5.230
# MASTER_PORT = 9419
# MASTER_TIMEOUT = 60 # timeout (in seconds) for master connections。Master连接超时时间(单位是秒)
# deprecated, to be removed in MooseFS 1.7
# LOCK_FILE = /var/run/mfs/mfsmetalogger.lock
.mfsmetalogger.lock

changelog_ml.*.mfs
MooseFS filesystem metadata change logs (backup of master change log files)
changelog_ml.*.mfs是MooseFS文件系统的元数据的changelog日志(备份的Master 的Master的changelog日志。)

metadata.ml.mfs.back
Latest copy of complete metadata.mfs.back file from MooseFS master.
metadata.ml.mfs.back是从Master主机上下载的最新的完整metadata.mfs.back的拷贝

sessions.ml.mfs
Latest copy of sessions.mfs file from MooseFS master.
sessions.ml.mfs是从master下载的最新的sessions.mfs文件拷贝。

3、chunker
主要文件:
mfschunkserver.cfg

# WORKING_USER = mfs
# WORKING_GROUP = mfs
# SYSLOG_IDENT = mfschunkserver
# LOCK_MEMORY = 0
# NICE_LEVEL = -19
# DATA_PATH = /usr/local/mfs/var/mfs
# MASTER_RECONNECTION_DELAY = 5 (delay in seconds before trying to reconnect to master after disconnection)在失去连接之后延迟多少秒重新连接master
MASTER_HOST = 192.168.5.230 元数据服务器的名称或地址,可以是主机名,也可以是ip地址。只要数据存储服务器能访问到元数据服务器就行。
# MASTER_PORT = 9420
# MASTER_TIMEOUT = 60
# CSSERV_LISTEN_HOST = *  #IP address to listen on for client (mount) connections (* means any) 允许挂载的客户端连接的IP地址(*允许全部)
# CSSERV_LISTEN_PORT = 9422
# CSSERV_TIMEOUT = 5      #timeout (in seconds) for client (mount) connections
客户端挂载连接的超时时间(单位为秒)
# HDD_CONF_FILENAME = /usr/local/mfs/etc/mfshdd.cfg #分配给MFS使用的磁盘空间配置文件的位置
# HDD_TEST_FREQ = 10   #chunk test period in seconds 块的测试期(单位为秒)
# deprecated, to be removed in MooseFS 1.7
# LOCK_FILE = /var/run/mfs/mfschunkserver.lock
# BACK_LOGS = 50

mfshdd.cfg
list of directories (mountpoints) used for MooseFS storage (one per line; directory prefixed by * character causes given directory to be freed by replicating all data already stored there to another locations) Lines starting with # character are ignored as comments。

mfschunkserver.lock
lock file of running MooseFS chunkserver process

4、mfsclient(mount)

三、MFS读写性能:
简单测试结果:
写:time dd if=/dev/zero of=/usr/mfstest/test2/zhhtest500M  bs=1024k count=500
读:time dd if=/usr/mfstest/test2/zhhtest500M  of=/dev/null

1copy

2copy

1copy

2copy

1M

0m0.042s

0m0.042s

0m0.017s

0m0.017s

2M

0m0.056s

0m0.066s

0m0.030s

0m0.055s

5M

0m0.073s

0m0.079s

0m0.070s

0m0.071s

10M

0m0.119s

0m0.131s

0m0.136s

0m0.197s

20M

0m0.250s

0m0.288s

0m0.291s

0m0.376s

50M

0m0.514s

0m0.589s

0m0.896s

0m0.886s

100M

0m0.977s

0m7.497s

0m1.677s

0m1.787s

200M

0m7.910s

0m22.270s

0m2.683s

0m3.129s

500M

0m22.465s

0m51.735s

0m6.559s

0m6.990s

1G

0m52.346s

1m48.056s

0m17.319s

0m17.154s

2G

1m46.224s

3m46.283s

0m41.608s

0m34.435s

5G

4m41.956s

9m34.798s

2m9.200s

1m56.183s

10G

9m29.037s

19m26.237s

3m55.222s

3m24.914s

100G

95m53.500s

195m7.173s

32m4.295s

41m26.995s


总结规律:
1、读速度:ca 71M/s   写速度:ca 22M/s  9M/s   (以500M计算)
2、goal的设置和读写速度的关系?貌似没有关系。

What average write/read speeds can we expect?
理想的平均写和读的速度是多少?

The raw reading / writing speed obviously depends mainly on the performance of the used hard disk drives and the network capacity and its topology and varies from installation to installation. The better performance of hard drives used and better throughput of the net, the higher performance of the whole system.

原始的读/写速度很明显是主要取决于所使用的硬盘的性能、网络的容量和拓扑结构的,使用的硬盘和网络的吞吐量越好,整个系统的性能也就会越好。

In our in-house commodity servers (which additionally make lots of extra calculations) and simple gigabyte Ethernet network on a petabyte-class installation  on Linux (Debian) with goal=2 we have write speeds of about 20-30 MiB/s and reads of 30-50MiB/s. For smaller blocks the write speed decreases, but reading is not much affected.

在我们的测试环境中,将MFS安装在linux(Debian)上设置存储的份数为2,一般的测试服务器(还做了其他较大量的计算),G太网络,使用Pbyte级别的数据,测试的结果为写的速度大约在20-30MB/s,读的速度为30-50MB/s。对于小文件写的速度有些下降,但是对于读的速度是没有影响的。

Does the goal setting influence writing/reading speeds?
设置文件存储的份数是否影响写/读的速度?

Generally speaking,  it doesn’t. The goal setting can influence the reading speed only under certain conditions. For example, reading the same file at the same time by more than one client would be faster when the file has goal set to 2 and not goal=1.

一般来说,它是有影响的。在一定条件下,存储份数的设置会影响的读取的速度。例如,当文件设置存储两份而不是一份时能加快对同一文件有多个客户端读取的速度。

But the situation in the real world when several computers read the same file at the same moment is very rare; therefore, the goal setting has rather little influence on the reading speeds.

但是在真实的环境中,多个机器同时读取同一个文件的机率是比较小的,因此,存储分数的设置对读取的速度影响是比较小的。

Similarly, the writing speed is not much affected by the goal setting.(if only the file is bigger than 64MiB)

同样,设置存储份数对写的速度影响也是不太大的(只有文件超过64M的时候)。

四、灾难测试、恢复及其他测试
1、client机器无论怎样操作都不会影响master。

客户端强制kill -9杀掉mfsmount进程,需要先umount,然后再mount。否则会提示:
fuse: bad mount point `/usr/mfstest/': Transport endpoint is not connected
see: /usr/local/mfs/bin/mfsmount -h for help

2、matser、metalogger、chunker、client端,服务器关机(init0)和重启(init6)时,程序都是正常关闭,无需修复。

3、master启动后,metalogger、chunker、client三个元素都能自动与master建立连接。
正常启动顺序:matser---chunker---metalogger---client
关闭顺序:client---chunker---metalogger---master
但实际中无论如何顺序启动或关闭,未见任何异常。

4、整个mfs体系中,直接断电只有master有可能无法启动。
使用mfsmetarestore -a修复才能启动,如果无法修复,使用metalogger上的备份日志进行恢复。(几次测试发现:如果mfsmetarestore -a无法修复,则使用metalogger也无法修复)。

强制使用metadata.mfs.back创建metadata.mfs,可以启动master,但丢失的数据暂无法确定(此问题已经请教MFS开发小组)。

直接断电测试过程,使用mfsmetarestore –a无法修复,使用metalogger也无法修复的情况较少发生。5次只有一次无法修复。

5、chunker的维持:chunker的块(chunks)能够自动复制或删除
对一个目录设定“goal”,此目录下的新创建文件和子目录均会继承此目录的设定,但不会改变已经存在的文件及目录的copy份数。但使用-r选项可以更改已经存在的copy份数。

goal设置为2,只要两个chunker有一个能够正常运行,数据就能保证完整性。假如每个文件的goal(保存份数)都不小于2,并且没有under-goal文件(可以用mfsgetgoal –r和mfsdirinfo命令来检查),那么一个单一的chunkserver在任何时刻都可能做停止或者是重新启动。以后每当需要做停止或者是重新启动另一个chunkserver的时候,要确定之前的chunkserver被连接,而且要没有under-goal chunks。

实际测试时,传输一个大文件,设置存储2份。传输过程中,关掉chunker1,这样绝对会出现有部分块只存在chunker2上;启动chunker1,关闭chuner2,这样绝对会有部分块只存在chuner1上。

把chunker2启动起来。整个过程中,客户端一直能够正常传输。在客户端查看,一段时间内,无法查看;稍后一段时间后,就可以访问了。文件正常,使用mfsfileinfo 查看此文件,发现有的块分布在chunker1上,有的块分布在chuner2上。使用mfssetgoal 2和mfssetgoal -r 2均不能改变此文件的目前块的现状。但使用mfssetgoal -r 1后,所有块都修改成1块了,再mfssetgoal -r 2,所有块都修改成2份了。

测试chunker端,直接断电情况下,chunker会不会出问题:
a、数据传输过程中,关掉chunker1,等待数据传输完毕后,开机启动chunker1.
chunker1启动后,会自动从chunker2复制数据块。整个过程中文件访问不受影响。

b、数据传输过程中,关掉chunker1,不等待数据传输完毕,开机启动chunker1.
chunker1启动后,client端会向chunker1传输数据,同时chunker1也从chunker2复制缺失的块。

如果有三台chunker,设置goal=2,则随机挑选2个chunker存储。

如果有一个chunker不能提供服务,则剩余的2个chunker上肯定有部分chunks保存的是一份。则在参数(REPLICATIONS_DELAY_DISCONNECT = 3600)后,只有一份的chunks会自动复制一份,即保存两份。

保存两份后,如果此时坏掉的chunker能够提供服务后,此时肯定有部分chunks存储了三份,mfs会自动删除一份。

6、chunks修复 :mfsfilerepair
mfsfilerepair deals with broken files (those which cause I/O errors on read operations) to make them partially readable. In case of missing chunk it fills missing parts of file with zeros; in case of chunk version mismatch it sets chunk version known to mfsmaster to highest one found on chunkservers. Note: because in the second case content mismatch can occur in chunks with the same version, it’s advised to make a copy (not a snapshot!) and delete original file after "repairing".

Mfsfilerepair主要是处理坏文件的(如写操作引起的I/O错误)使文件能够部分可读。作用如下:在丢失块的情况下使用0对丢失文件进行填充;在块的版本号不匹配时设置快的版本号为master上已知的能在chunkerservers找到的最高版本号;注意:因为在第二种情况的内容不匹配,可能发生在块具有相同的版本,建议进行文件的拷贝(而不是进行不快照!),并删除原始文件再进行文件的修复。

Client端大文件传输过程中,强制拔下master主机电源,造成master非法关闭,使用mfsmetarestore -a修复后,master日志报告有坏块:
Jan 19 17:22:17 ngmaster mfsmaster[3250]: chunkserver has nonexistent chunk (000000000002139F_00000001), so create it for future deletion
Jan 19 17:22:18 ngmaster mfsmaster[3250]: (192.168.5.232:9422) chunk: 000000000002139F creation status: 20
Jan 19 17:25:18 ngmaster mfsmaster[3250]: chunk 000000000002139F has only invalid copies (1) - please repair it manually
Jan 19 17:25:18 ngmaster mfsmaster[3250]: chunk 000000000002139F_00000001 - invalid copy on (192.168.5.232 - ver:00000000)
Jan 19 17:26:43 ngmaster mfsmaster[3250]: currently unavailable chunk 000000000002139F (inode: 135845 ; index: 23)
Jan 19 17:26:43 ngmaster mfsmaster[3250]: * currently unavailable file 135845: blog.xxx.cn-access_log200904.tar.gz

Client端使用mfsfilerepair修复
[root@localhost mfstest]# /usr/local/mfs/bin/mfsfilerepair blog.xxx.cn-access_log200904.tar.gz
blog.xxt.cn-access_log200904.tar.gz:
chunks not changed: 23
chunks erased: 1
chunks repaired: 0
查看master日志,发现:
Jan 19 17:30:17 ngmaster mfsmaster[3250]: chunk hasn't been deleted since previous loop - retry
Jan 19 17:30:17 ngmaster mfsmaster[3250]: (192.168.5.232:9422) chunk: 000000000002139F deletion status: 13
Jan 19 17:35:16 ngmaster mfsmaster[3250]: chunk hasn't been deleted since previous loop - retry
Jan 19 17:35:16 ngmaster mfsmaster[3250]: (192.168.5.232:9422) chunk: 000000000002139F deletion status: 13
Client端执行以下操作后,master不再报告相关信息:
mv blog.xxt.cn-access_log200904.tar.gz blog.xxt.cn-access_log200905.tar.gz

7、chunker的空间
每一个chunkserver的磁盘都要为增长中的chunks保留些磁盘空间,从而达到创建新的chunk。只有磁盘都超过256M并且chunkservers报告自由空间超过1GB总量才可以被新的数据访问。最小的配置,应该从几个G 字节的存储。

When doing df -h on a filesystem the results are different from what I would expect taking into account actual sizes of written files.

在文件系统上做df –h得到的结果和我已经写进去的文件大小不一致?

Every chunkserver sends its own disk usage increased by 256MB for each used partition/hdd, and a sum of these master sends to the client as total disk usage. If you have 3 chunkservers with 7 hdd each, your disk usage will be increased by 3*7*256MB (about 5GB). Of course it's not important in real life, when you have for example 150TB of hdd space.

每个chunkerserver每次以256M的磁盘空间进行申请,而发给客户端的是这个空间加起来的总和。例如:如果你有3个chunkerserver7个分区磁盘,每次你的硬盘使用会增加3*7*256MB (大约5GB)。当然如果在现实生活中你的硬盘大小为150T的大小,这是对你来说是不重要的。

There is one other thing. If you use disks exclusively for MooseFS on chunkservers df will show correct disk usage, but if you have other data on your MooseFS disks df will count your own files too.

另外,如果你的chunkservers使用专用的磁盘,df将显示正确的磁盘使用情况。但是如果你有其他的数据在你的MooseFS磁盘上,df将会计算你所有的文件。

If you want to see usage of your MooseFS files use 'mfsdirinfo' command.
如果你想看你的MooseFS文件的使用情况,请使用'mfsdirinfo'命令。

8、快照snapshot
可以快照任何一个文件或目录,语法:mfsmakesnapshot src dst
但是src和dst必须都属于mfs体系,即不能mfs体系中的文件快照到其他文件系统。both elements must be on the same device。元素必须是相同的设备上。

Mfsappendchunks:追加chunks到一个文件
append file chunks to another file. If destination file doesn't exist then it's created as empty file and then chunks are appended.

追加文件块到另一个文件。如果目标文件不存在,则会创建一个空文件,然后继续将块进行追加。

9、回收站 trash bin
设置文件或目录的删除时间。一个删除的文件能够存放在“ 垃圾箱”中的时间称为隔离时间, 这个时间可以用mfsgettrashtime 命令来查看,用mfssettrashtime 命令来设置。单位为秒。

单独安装或挂载MFSMETA 文件系统,它包含目录/ trash (包含仍然可以被还原的删除文件的信息)和/ trash/undel (用于获取文件)。

把删除的文件,移到/ trash/undel下,就可以恢复此文件。在MFSMETA 的目录里,除了trash 和trash/undel 两个目录,还有第三个目录reserved,该目录内有已经删除的文件,但却被其他用户一直打开着。在用户关闭了这些被打开的文件后,reserved 目录中的文件将被删除,文件的数据也将被立即删除。此目录不能进行操作。

10、文件描述符
1.5.12版本,进行大量小文件写时,出现了一个严重错误,有可能和操作系统文件描述符有关。操作系统默认文件描述符为1024.1.6.11版本默认为100000,建议上线时,master和chunker修改文件描述符,即修改/etc/security/limits.conf添加'* - nofile 65535'。

最初我们尝试过采用HeartBeat来在两台主控间切换,依靠官方提供的mfs元日志恢复工具来在每次切换时恢复日志,但实际测试中发现这方案依旧不可靠,一旦发生浮动IP切换,日志仍然可能在恢复中丢失少量信息,导致群集中文件损坏。为此,在HA的基础上又构筑了DRBD来确保关键数据的不可中断性。

11、对master的单点故障的解决办法

其官方所提供的解决方案:
从备份中恢复一个master。
1)、安装一个mfsmaster
2)、利用同样的配置来配置这台mfsmaster(利用备份来找回mfsmaster.cfg),可见配置文件也是需要备份的。
3)、找回metadata.mfs.back文件,可以从备份中找,也可以中metalogger主机中找(如果启动了metalogger服务),然后把metadata.mfs.back放入data目录,一般为${prefix}/var/mfs。
4)、从在master宕掉之前的任何运行metalogger服务的服务器上拷贝最后metadata文件,然后放入mfsmaster的数据目录。
5)、利用mfsmetarestore命令合并元数据changelogs,可以用自动恢复模式mfsmetarestore –a,也可以利用非自动化恢复模式,语法如下:
mfsmetarestore -m metadata.mfs.back -o metadata.mfs changelog_ml.*.mfs
评价:这种在有些情况下无效,当在你刚写完文件时,在断掉master的网卡后,在metalogger机器上做恢复后,客户端上不能对某些文件正常访问,会长时间地卡在那里。通过mfsfileinfo在查看文件属性时,会发现一些的块无效提示,在文件文件里也能看到一些提示信息。数据会丢失,完整性得不到保障。

MFS+HA+DRBD的效果
DRBD相信很多人都有了解,它是一个类似于网络RAID1的实现,在双机之间进行实时的块设备数据同步,通常会和HA结合使用。我们在这个应用环境中,将主控的日志目录单独存储在一个块设备上(日志的增长是可控且能设定回滚周期的,所以日志容量问题不存在),并部署两个相同的主控环境,将一个同样容量的块设备和对应的主控机日志存储设备设为HA+DRBD同步,在这个环节中,非常关键的一点是在HA资源定义配置中,必须先切DRBD,再切换mfs服务,否则mfs客户端不能及时探测到虚拟浮动IP的的变化,导致挂载失效。

haresource示例:
master1 drbddisk::r0 Filesystem::/dev/drbd0::/mnt/drbd::ext3 mfs Ipaddr::192.168.2.103/24/eth0

在读写测试中,我们尝试了往mfs挂载点中不间断写入十万个文件,并统计了md5值列表。然后在其它mfs挂载目录中,再一次重复上述步骤,期间多次切换主备,可观察到每次切换时虽然I/O会进入等待循环,但一旦另一端的主控点正常启动、浮动IP恢复,写入会马上继续,这一步结束后,我们再次统计新写入的十万个文件的md5列表,途中同样多次人工切换主备,最终仍然不影响数据的可靠性,得到的md5值列表和之前的完全一致。类似目的的测试,我们也反复尝试了单个大文件的读写校验,结果令人比较满意。

要是出现网络中断及master机器突然断电,mfsmaster非正常关闭,没有将其运行过程所掌握的文件信息回写到磁盘的话,在备机取得相关ip及资源后,也不能正常启动,会出现像第一次开启mfsmaster时那样的提示:“将'metadata.mfs.empty'复制成'metadata.mfs'”等。

‘drbd+heartbeat(keepalived)’这种方法能提供对元数据的完整性更有保障,当master在出现断网后,在backup上无法启动mfsmaster进程,除非在原master机器上正常关闭了mfsmaster进程。因为在mfsmaster开始运行时,会将其data目录下的metadata.mfs文件复制为metadata.mfs.back,将现有的metadata.mfs文件读入到内存中,并删除了metadata.mfs,而内存中的此文件则发生了改变,但它不会在文件系统里'有所表现'。这样在mfsmaster主机出现异常时,或mfsmaster没有正常关闭时,该文件都不会写到磁盘上(或定期地将新增内容更新到metadata.mfs.back文件中?)!而这段时间所产生的文件信息将会丢失。

在使用drbd方案时,在进行切换时要保证master机上的mfsmaster进程要能正常关闭且不能断网,当然你不能使用像dell r610这样的机器了(打了网卡补丁后还会有断网现象!410也有该现象)。

综其观之,MFS是一个非常具有潜力的分布式存储方案,结合HA+DRBD来弥补了它本身的主控单点后,在企业应用中的价值更上一层。虽然它还没有经历真正的长期应用的考验,但目前已经达到的程度,已有足够的理由来支持我们对它作进一步的推广和关注,假以时日,相信还会有更多的经验和价值能从中开掘出来。


五、因部分的Chunkserver防火墙问题导致的写入出错

现象:使用rsync工具向mfs中同步文件时,写入一会就会报出如下面错误:

>f+++++++++ freeoa-20200318.zst
23.72G  17%   19.74MB/s    1:31:22
rsync: writefd_unbuffered failed to write 4 bytes to socket [sender]: Broken pipe (32)
rsync: write failed on "/mnt/freeoa-20200318.zst": Input/output error (5)
rsync error: error in file IO (code 11) at receiver.c(322) [receiver=3.0.9]
rsync: connection unexpectedly closed (69 bytes received so far) [sender]
rsync error: error in rsync protocol data stream (code 12) at io.c(605) [sender=3.0.9]

开启挂载时的调试输出
/opt/lizardfs/bin/mfsmount -d -c mfsmount.cfg
/opt/lizardfs/bin/mfsmount -o mfsdebug -c mfsmount.cfg

unique: 31747, opcode: WRITE (16), nodeid: 178, insize: 4176, pid: 13805

[WARN] write file error, inode: 178, index: 1 - Chunkserver timed out (server 172.18.20.83:9422) (try counter: 7)
mfsmount[13209]: write file error, inode: 178, index: 1 - Chunkserver timed out (server 172.18.20.83:9422) (try counter: 7)
[WARN] write file error, inode: 177, index: 0 - Connection error: ETIMEDOUT (Operation timed out) (server 172.18.20.70:9422) (try counter: 10)
mfsmount[13209]: write file error, inode: 177, index: 0 - Connection error: ETIMEDOUT (Operation timed out) (server 172.18.20.70:9422) (try counter: 10)
[WARN] write file error, inode: 178, index: 1 - Chunkserver timed out (server 172.18.20.83:9422) (try counter: 8)
mfsmount[13209]: write file error, inode: 178, index: 1 - Chunkserver timed out (server 172.18.20.83:9422) (try counter: 8)
[WARN] write file error, inode: 177, index: 0 - Chunkserver timed out (server 172.18.20.83:9422) (try counter: 11)
mfsmount[13209]: write file error, inode: 177, index: 0 - Chunkserver timed out (server 172.18.20.83:9422) (try counter: 11)
[WARN] write file error, inode: 178, index: 1 - Connection error: ETIMEDOUT (Operation timed out) (server 172.18.20.70:9422) (try counter: 9)
mfsmount[13209]: write file error, inode: 178, index: 1 - Connection error: ETIMEDOUT (Operation timed out) (server 172.18.20.70:9422) (try counter: 9)

一些个人的分析:我是设定的goal为2,刚好一台关闭了防火墙而另一台阻塞了访问进入,这也可能是能写入一点进去的原因,但报超时错误正好又是那台没有开启防火墙的机器上,这就让人觉得很奇怪。后在防火墙中加入了对应的入口端口规则后问题得到了解决(连续写入了2.2T后无任何错误报出)。
#mfs chunkserver
iptables -A INPUT -p tcp --dport 9422 -j ACCEPT



该文章最后由 阿炯 于 2020-03-18 15:24:17 更新,目前是第 2 版。