高度可扩展性的文件系统:Lustre

jopen 11年前

Lustre为Xyratex公司所有,Lustre是一个高度可扩展性的文件系统,可带来快速的性能体验。它还可以处理“几万节点和PB级存储”。
高度可扩展性的文件系统:Lustre

1 Lustre概述
Lustre是面向集群的存储架构,它是基于Linux平台的开源集群(并行)文件系统,提供与POSIX兼容的文件系统接口。Lustre两个最大特征是高扩展性和高性能,能够支持数万客户端系统、PB级存储容量、数百GB的聚合 I/O吞吐量。Lustre是Scale-Out存储架构,借助强大的横向扩展能力,通过增加服务器即可方便扩展系统总存储容量和性能。Lustre的集群和并行架构,非常适合众多客户端并发进行大文件读写的场合,但目前对于小文件应用非常不适用,尤其是海量小文件应用LOSF(Lots Of Small Files)。Lustre广泛应用于各种环境,目前部署最多的为高性能计算HPC,世界超级计算机TOP 10中的70%,TOP 30中的50%,TOP 100中的40%均部署了Lustre。另外,Lustre在石油、天然气、制造、富媒体、金融等行业领域也被大量部署应用。

 

2 Lustre Stripe
Lustre采用对象存储技术,将大文件分片并以类似RAID0的方式分散存储在多个OST上,一个文件对应多个OST上的对象。Lustre系统中,每个文件对应MDT上的一个元数据文件,inode以扩展属性记录了数据分片布局信息,包括stripe_count(对象数), stripe_size(分片大小), stripe_offset(起始OST)以及每个OST对象信息。当客户数据端访问文件时,首先从MDS请求文件元数据并获得分片布局信息(stripe layout),然后直接与多个OST同时交互进行并发读写。Lustre这种数据分片策略,提高了多用户访问的并发度和聚合I/O带宽,这是 Lustre获得高性能的主要因素。再者,Stripe还能够使得Lustre可以存储超大文件,突破单一OST对文件大小的限制。当然,数据分片策略同时也会带来负面影响,比如增加系统负载和数据风险。

 

Lustre的OST数量可以达到数千,但是出于复杂性、性能、实际存储需求等考虑,目前设计实现中将单个文件对象数限制为160个。对于EXT4 后端文件系统,单个文件最大可达2TB,因此Lustre单个文件最大可以达到320TB。那么,Lustre如何在可用OST集合中选择合适的OST 呢?目前有两种选择算法,即Round-Robin和随机加权算法,这两种算法调度的依据是,任意两个OST剩余存储容量相差是否超过20%的阈值。一般在系统使用之初,直接使用Round-Robin算法以顺序轮转方式选择OST,这种算法非常高效。随着文件数据量的增加,一旦达到20%的阈值,Lustre将启用随机加权算法选择OST。Lustre维护着一个剩余空间的优先列表,采用随机算法在此列表中选择OST,这种算法会产生开销并影响性能。如果任意两个OST剩余存储容量相差重新降到20%阈值之内,则重新启用Round-Robin算法选择OST。Lustre在创建文件时就按照分片模式并采用OST选择算法,预先创建好文件所需的OST对象。分片模式可以使用lfs setstripe进行设置,或者由系统自动选择缺省模式,文件目录会自动继承父目录的分片模式,但可以进行修改。数据写入后,文件分片模式就不能修改,新加入的OST只会参与新创建的文件目录OST选择调度。Lustre目前还没有实现OST存储空间的自动均衡,需要手工进行数据迁移复制达到均衡的效果。

 

Lustre缺省情况下,stripe_count = 1, stripe_size = 1MB, stripe_offset = -1,即每个文件仅包含一个OST对象,分片大小为1MB,起始OST由Lustre自动选择。实际上这种分片模式就是不对文件进行分片存储,显然不能满足许多应用的存储需求,实际应用时需要在分析数据特点、网络环境、访问行为的基础上进行适当配置。分片不是越多越好,在满足存储需求的前提下,应该使得 OST对象数量尽可能少。应用lustre Stripe时,应该考虑如下因素:
(1)提供高带宽访问。 Lustre文件分片并存储于多个OSS,对于单一大文件来说,它可以提供远大于单一OSS提供的聚合I/O带宽。在HPC环境中,成百上千的客户端会同时并发读写同一个文件,当文件很大时,分散与多个OSS能够获得非常高的聚合带宽。Lustre文件系统理论上可以提供2.5 TB/s的带宽,经过验证的带宽达到240 GB/s。当然对于小于1GB的文件来说,分片数量不宜多于4个,更多分片不会带来更高的性能提升,还会引入额外开销。对于小文件,文件大小本身可能小于分片大小,实际上是不作分片,对性能不会有提升。
(2)改善性能。如果聚合的客户端带宽超过单个OSS的带宽,文件分片存储策略可以充分利用聚合的OSS带宽,极大提高性能,为应用程序提供高速的数据读写访问。合理的分片数量可以估算,客户端聚合I/O带宽除以单个OSS I/O性能即可得到。
(3)提供超大容量文件。 Lustre后端文件系统采用改进的EXT3文件系统(接近于EXT4),单个文件最大为2TB。如果不进行分片,则单个Lustre文件最大只能为 2TB。Lustre目前分片最多可达到160个,因此文件最大可以达到320TB,这是容量是非常大的,基本上可以满足所有单一文件存储容量的需求。
(4)提高存储空间利用率。当Lustre剩余存储空间有限时,每个OSS的剩余空间也就更加有限,这时再写入一个的大文件至单一OSS很大可能会由于空间不足而失败。采用分片策略,写入单个OSS的对象容量会成倍减小,如果OSS数量选择合适,文件仍然可以写入Lustre系统。这使得Lustre存储空间利用更为充分,有效提高了利用率。
(5)增加负载。Stripe会导致额外的锁和网络操作消耗,比如stat, unlink,虽然这些操作可以并发执行,但仍会对性能产生影响。另外,分片多会造成服务器的开销。设想这样一个情形:Lustre中有100个 OSS,100个客户端,100个文件,每个客户端访问一个文件。如果不分片,则每个客户端仅与一个OSS相互,可以进行顺序I/O读写。如果每个文件分成100片,则每个客户端都需要分别与100个OSS进行相交,并发访问时,OSS上的磁盘I/O为随机读写。这些都是额外的负载开销,一定程度上影响性能。
(6)增加风险。从概率的角度看,多个OSS发生故障的概率要高出单个OSS许多。文件分片存储于多个 OSS上,一个分片不可用就会导致整个文件不可访问,即使其他分片仍然是完好的。因此,分片大大增加了数据发生丢失的风险,需要采用适当的措施进行保护,比如RAID5/6或者Failover。

 

3 Lustre I/O性能特征

(1)写性能优于读性能
Lustre系统中通常写性能会优于读性能。首先,对于写操作,客户端是以异步方式执行的,RPC调用分配以及写入磁盘顺序按到达顺序执行,可以实现聚合写以提高效率。而对于读,请求可能以不同的顺序来自多个客户端,需要大量的磁盘 seek与read操作,显著影响吞吐量。其次,目前Lustre没有实现OST read cache,仅仅在客户端实现了Readahead。这样的设计也是有充分理由的,每个OST有可能会有大量客户端并发访问,如果进行数据预读,内存消耗将会非常大,而且这个是不可控制的。Writecache是在客户端上实现的,内存占用不会太大并且是可控的。再者,对于TCP/IP网络而言,读会占用更多的CPU资源。读操作,Lustre需要从网络接口缓存进行数据Copy而获得所需数据,而写操作可以通过sendfile或Zero Copy避免额外的数据复制。

(2)大文件性能表现好
Lustre的元数据与数据分离、数据分片策略、数据缓存和网络设计非常适合大文件顺序I/O访问,大文件应用下性能表现非常好。这些设计着眼于提高数据访问的并行性,实现极大的聚合I/O带宽,这其中关键得益于数据分片设计(具体见上面的分析)。另外,后端改进的EXT3文件系统本身也非常适合大文件I/O。

(3)小文件性能表现差
然而,Lustre的设计却非常不利于小文件I/O,尤其是LOSF(Lots of small files)。Lustre在读写文件前需要与MDS交互,获得相关属性和对象位置信息。与本地文件系统相比,增加了一次额外的网络传输和元数据访问开销,这对于小文件I/O而言,开销是相当大的。对于大量频繁的小文件读写,Lustre客户端Cache作用会失效,命中率大大降低。如果文件小于物理页大小,则还会产生额外的网络通信量,小文件访问越频繁开销越大,对Lustre总体I/O性能影响就越大。OST后端采用改进的EXT3文件系统,它对小文件的读写性能本身就不好,其元数据访问效率不高,磁盘寻址延迟和磁盘碎片问题严重。这也是大多数磁盘文件系统的缺点,Reiserfs是针对小文件设计的文件系统,性能表现要好很多。Lustre的设计决定了它对小文件I/O性能表现差,实际I/O带宽远低于所提供的最大带宽。在4个OSS的千兆网络配置下,单一客户端小文件读写性能不到4MB/s。

 

4 Lustre小文件优化
实际上前面已经提到,Lustre并不适合小文件I/O应用,性能表现非常差。因此,建议不要将Lustre应用于LOSF场合。不过,Lustre操作手册仍然给出了一些针对小文件的优化措施。
(1)通过应用聚合读写提高性能,比如对小文件进行Tar,或创建大文件或通过loopback mount来存储小文件。小文件系统调用开销和额外的I/O开销非常大,应用聚合优化可以显著提高性能。另外,可以使用多节点、多进程/多线程尽可能通过聚合来提高I/O带宽。
(2)应用采用O_DIRECT方式进行直接I/O,读写记录大小设置为4KB,与文件系统保持一致。对输出文件禁用locking,避免客户端之间的竞争。
(3)应用程序尽量保证写连续数据,顺序读写小文件要明显优于随机小文件I/O。
(4)OST采用SSD或更多的磁盘,提高IOPS来改善小文件性能。创建大容量OST,而非多个小容量OST,减少日志、连接等负载。
(5)OST采用RAID 1+0替代RAID 5/6,避免频繁小文件I/O引起的数据校验开销。

Lustre提供了强大的系统监控与控制接口用于进行性能分析与调优,对于小文件I/O,也可以通过调整一些系统参数进行优化。
(1)禁用所有客户端LNET debug功能:缺省开启多种调试信息,sysctl -w lnet.debug=0,减少系统开销,但发生错误时将无LOG可询。
(2)增加客户端Dirty Cache大小:lctl set_param osc./*.max_dirty_mb=256,缺省为32MB,增大缓存将提升I/O性能,但数据丢失的风险也随之增大。
(3)增加RPC并行数量:echo 32 > /proc/fs/lustre/osc/*-OST000*/max_rpcs_in_flight,缺省为8,提升至32将提高数据和元数据性能。不利之处是如果服务器压力很大,可能反而会影响性能。
(4)控制Lustre striping:lfs setstripe -c 0/1/-1 /path/filename,如果OST对象数大于1,小文件性能会下降,因此将OST对象设置为1。
(5)客户端考虑使用本地锁:mount -t lustre -o localflock,如果确定多个进程从同一个客户端进行写文件,则可用localflock代替flock,减少发送到MDS的RPC数量。
(6)使用loopback mount文件:创建大Lustre文件,与loop设备关联并创建文件系统,然后将其作为文件系统进行mount。小文件作用其上,则原先大量的MDS 元数据操作将转换为OSS读写操作,消除了元数据瓶颈,可以显著提高小文件性能。这种方法应用于scratch空间可行,但对于生产数据应该谨慎使用,因为Lustre目前工作在这种模式下还存在问题。操作方法如下:
 dd if=/dev/zero of=/mnt/lustre/loopback/scratch bs=1048576 count=1024
 losetup /dev/loop0 /mnt/lustre/loopback/scratch
 mkfs -t ext4 /dev/loop0
 mount /dev/loop0 /mnt/losf

 

5 Lustre I/O最佳实践
Lustre具有鲜明的I/O特点,并具有非常高的扩展性和大文件I/O性能。如果进行适当的配置和操作,Lustre则会展现更高的性能。下面给出一些Lustre I/O最佳实践,可根据实际应用情况择优实践。
(1)使用单进程读取完整的共享小文件,需要时传输数据至其他进程。
(2)使用单进程访问容量在(1MB, 1GB)之间的小文件,将文件OST对象数设为1。
(3)使用单进程访问大于1GB的中等文件,文件OST对象数不超过4个。
(4)远大于1GB的大文件OST对象数应设为>4,这种文件不要采用顺序I/O或file-per-process的I/O访问模式。
(5)限制单个目录下的文件数量,包含大量小文件的目录stripe_count设置为1。
(6)小文件存放在单一OST上,单进程文件创建和读写性能会得到提高。
(7)包含大量小文件的目录存放在单一OST上,文件创建性能会提到极大提升。
(8)尽量避免频繁地打开和关闭文件。
(9)仅在必要时使用ls -l,它会与所有相关的OST交互,操作代价很大,尽可能使用ls和lfs find代替。
(10)考虑使用I/O中间件来改善性能,如ADIOS、HDF5、MPI-IO。


项目主页:http://www.open-open.com/lib/view/home/1389362402180