打印

ZFS文件系统的特点和调优

本帖已经被作者加入个人空间

ZFS文件系统的特点和调优

ZFS文件系统在设计上与传统的文件系统有很大的不同。我们需要对ZFS的几个基本概念有
所了解:
Record Size
Record Size 也就是通常所说的文件系统的block size。ZFS采用的是动态的Record Size,也就
是说ZFS会根据文件大小选择*适合*的512字节的整数倍作为存储的块大小,最大的Record
Size为128KB。通常没有必要手工设置Record Size。如果手工把Record Size调小,将不会得
空间的节省,并且常常会影响性能。ZFS的Block是计算checksum的单位,一个文件用到
的block越多,计算checksum以及维护metadata的开销就会越大。
目前ZFS的版本下,只有一种情况需要手工调小Record Size:大文件上的小数据量的更新。
常见的情况是数据库的数据文件在ZFS上,并且是做OLTP为主的应用。原因是大文件的
blocksize是128KB,如果只更新其中一小部分数据,由于ZFS是copy-on-write的方式来更新
数据,这种情况下仍然要读写128KB的数据,造成了不必要的开销。
另外,修改了Record Size后,对之前创建的文件不起作用。
ARC (Adaptive Replacement Cache)
这实际上是ZFS的文件系统的cache。它是一个可以自动伸缩的cache。目前一个操作系统实
例里只有一个ARC,不管这个操作系统上有多少个ZFS Pool。而且metadata和实际的数据都
共用这个ARC。
如果没有其它应用或操作系统本身争用内存,ZFS会尽可能多地使用物理内存作为cache。如
果事先知道应用程序或操作系统需要使用多少内存,可以考虑限制ARC的大小。在/etc/system
中设置,例子:set zfs:zfs_arc_max=0x200000000 (设置ARC最大为8GB)
还可以使用如下工具来监测ARC的使用情况。

bash-3.00# ./zfs_arcstat.pl
Time read miss miss% dmis dm% pmis pm% mmis mm% arcsz c
14:41:03 10M 2M 21 2M 21 0 0 97K 77 2G 2G
14:41:04 890 228 25 228 25 0 0 8 100 2G 2G
14:41:05 1K 273 25 273 25 0 0 7 100 2G 2G
14:41:06 880 221 25 221 25 0 0 5 100 2G 2G
14:41:07 1K 272 25 272 25 0 0 10 52 2G 2G
14:41:08 1K 244 24 244 24 0 0 4 100 2G 2G
14:41:09 1K 294 25 294 25 0 0 10 100 2G 2G
14:41:10 1K 258 25 258 25 0 0 6 66 2G 2G

各列的含义,在这个Perl脚本里有描述。该工具的下载地址是:
http://www.solarisinternals.com/wiki/index.php/Arcstat
TXG (Transaction Groups)
应用的文件写操作一般分为两种,同步写和普通写操作。同步写是指写操作必须物理地写到
存储介质上才能返回给应用,通常这种情况发生在open文件时指定了O_DSYNC或O_SYNC
属性,以及调用fsync()等;普通写操作是指写操作写到文件系统cache里即可返回给应用,通
常以普通方式打开文件后的write(),fwrite()操作都是这种操作。TXG (Transaction Groups)则是
负责管理如何将文件系统cache(ARC)里的数据同步到磁盘上的机制。
对于写进文件系统cache里的每一个数据都会被编入一个TXG,通常情况下每隔5秒钟或文件
系统cache里有太多脏数据(待写入磁盘的数据达到ARC的一半),当前TXG里的所有数据
会被同步到磁盘,同时启动下一个TXG。每一个ZFS Pool同时最多会有3个TXG,分别处于
3种状态:open, quiescing, syncing。当TXG不能在5秒内把数据同步到磁盘上时将会影响
open TXG,从而引起应用写操作的阻塞。这个现象叫做写抑制(throttling)。
当前的Solaris 版本(Solaris 10 8/07)对写抑制的控制不是非常好,当进行密集的写操作并且
ARC较大、磁盘系统较慢时容易使TXG同步数据的时间非常长,发生throttling从而使应用的
后续写操作的响应时间非常长。在新的opensolaris发行包里,这个问题已经有了很大的改进,
ZFS会监测ARC接收数据的速度和ARC数据同步到磁盘上的速度,并自动调整ARC接收数
据的速度。另外ARC脏数据的大小限制改为1/8物理内存。通过这种控制可以使应用的写操
作响应时间更为均匀稳定。
ZIL (ZFS Intent Log)
对于同步写操作,ZFS为系统中每一个ZFS文件系统维护一个ZIL(ZFS Intent log)。同步写操
作的数据会先写入ZIL,并且会把磁盘的write cache的数据同步到磁盘上,然后应用的写操作
返回。当文件提交命令发生时,ZFS会把ZIL里该文件的数据同步到磁盘上。
缺省情况下,ZIL是在ZFS存储池中动态分配的。某些同步写操作(比如数据库的联机重做日
志或NFS COMMIT)如果响应时间慢将会极大影响性能。为了不使ZIL受其它I/O操作的影
响,可以考虑采用一个专门的快速设备如NVRAM,SSD(Solid State Disk)等做ZIL,以下命令
为ZFS存储池添加专用的ZIL:
zpool add <pool> log <log devices>
另外,由于每次同步写操作会使ZFS把磁盘 write cache的数据同步到磁盘上,对于SAN的存
储,频繁地flush cache会严重影响性能并且是不必要的。这个问题在OpenSolaris里已经得到
解决,解决办法是让设备驱动程序向存储系统发出适当的命令选项,从而使存储系统可以忽
略从non-volatile cache同步到磁盘的请求。前提是存储系统可以识别驱动程序发出的命令选项。
I/O scheduler and priorities
缺省情况下,ZFS会限制每一个它能看到的存储池里的设备的I/O队列长度为35,并且通常读
操作的优先级高于写操作。这种做法的目的是保证较好的I/O service time。
根据实际的应用需求和存储设备的不同,可能需要调整I/O队列的大小。比如为了得到更好地
响应时间,在/etc/system里设置:set zfs:zfs_vdev_max_pending = 10
Prefetch (file level and device level)
和其它文件系统一样,ZFS也有预读的功能。ZFS文件系统的预读分为file-level和devicelevel

file-level的预读是指ZFS可以检测到文件读取的模式,预先读入文件的后续部分从而减少I/O
操作以提高性能。对于大并发量的针对不同文件的读操作,file-level的预读通常不会带来好处,
可以把预读关掉:在/etc/system里设置:set zfs:zfs_prefetch_disable = 1 。
Device-level的预读是指在读取数据块时,会读取设备相邻的数据,假定相邻数据随后会被用
到。Device-level的预读有时会读入不需要的数据反而会影响性能,在新的opensolaris发行包
里,Device-level的预读只预读metadata。
RAIDZ and RAIDZ2
ZFS提供了类似传统RAID5和RAID6的功能,分别叫做RAIDZ和RAIDZ2。但RAIDZ的实
现与传统RAID5有很大不同:RAIDZ的所有写操作都是Full-Stripe write,结合ZFS的copyon-
write和checksum的机制,可以保证数据的一致性,无需像传统的RAID5那样需要昂贵的
NVRAM来保证条带数据的一致性。
RAIDZ的stripe size是完全动态的。每一个文件系统块(record)在存储时会平均分配到RAIDZ
group里的所有磁盘上,并以512字节为单位。例如,假设一个4KB的文件,如果存储在4+1
的RAIDZ group,则4KB的数据会分散到4个磁盘上,每个磁盘上存储1KB。因此一个
RAIDZ group里的设备不应过多,否则会影响读操作的性能。一般建议为3~9个。RAIDZ比
较适合大文件的顺序读写。
由于RAIDZ在设计上的特殊性,在数据恢复时需要通过metadata来恢复,要遍历整个pool。
当某块磁盘出现故障时,RAIDZ重建的速度与metadata的数量有关。当有大量metadata数据
时,比如大量snapshots或pool里的文件数量庞大,数据重建的速度会较慢。在这种情况下,
可以考虑创建多个pool。当然,对一个很空的文件系统,RAIDZ的重建时间会很短。
|-- AI by Spruce Lab -- | Discover the Info. Tech. for Personal! && Powered by Solaris & Oracle

通告:即日起启用新MSN和Mail地址:aic.lab.sif@gmail.com 原来的最多1个月后停用!

TOP

ZFS文件系统的部署规划建议

存储系统以及文件系统的部署规划远比调优重要,因为一旦存储了数据,可以调整的余地已
经非常小了。以下是关于ZFS文件系统规划的一些建议:
● 使用最新的Solaris版本或OpenSolaris版本。
ZFS技术更新非常快,其中包含了很多性能改进和bug的修复。这些更新反映在最新的
OpenSolaris版本里。Solaris里关于ZFS的更新会滞后一些。如果要求不是很严格的话,可以
考虑使用OpenSolaris。(每一个OpenSolaris的版本,SUN可以提供18个月的付费支持。每
一个Solaris的版本,SUN可以提供至少7年的付费支持。)
● 对于server应用应使用64位的Solaris操作系统
ZFS以及ARC使用kernel memory。如果使用32位的操作系统,由于kernel的地址空间和应
用的地址空间共享4GB,ZFS会受到很大限制。另外对于x86/x64硬件,64位系统通常会得到
更高的性能。
● 使用整个磁盘而不是某个分区或slice来作为ZFS的存储设备
使用整个磁盘作为ZFS的存储设备可以使ZFS打开磁盘的写cache,并且方便将来存储池
import和export的操作(比如磁盘迁移到另外的机器上)。一个磁盘上如果有多个分区并安装
了不同的文件系统将会带来磁盘管理上的麻烦。
● 让ZFS直接管理磁盘
实践证明,让ZFS直接管理磁盘而不是hardware RAID往往可以得到更好地性能。因为ZFS
有自己的I/O 调度的算法,让ZFS直接管理磁盘可以让ZFS更好地做出I/O调度以及文件系统
块的分配策略。如果要使用外部存储系统,建议每个ZFS看到的设备包含较少的磁盘。总之,
ZFS更喜欢廉价的硬件。
● 存储池的设备分散到多个控制器上
这主要是从性能和可用性上的考虑。例如,对于Sun x4500,一个可选的Pool的规划为:
root@x4500 # zpool create -f zfspool \
raidz c5t7d0 c4t7d0 c7t7d0 c6t7d0 c1t7d0 c0t7d0 \
raidz c5t6d0 c4t6d0 c7t6d0 c6t6d0 c1t6d0 c0t6d0 \
raidz c5t5d0 c4t5d0 c7t5d0 c6t5d0 c1t5d0 c0t5d0 \
raidz c4t4d0 c7t4d0 c6t4d0 c1t4d0 c0t4d0 \
raidz c5t3d0 c4t3d0 c7t3d0 c6t3d0 c1t3d0 \
raidz c5t2d0 c4t2d0 c7t2d0 c6t2d0 c0t2d0 \
raidz c5t1d0 c4t1d0 c7t1d0 c1t1d0 c0t1d0 \
raidz c4t0d0 c7t0d0 c6t0d0 c1t0d0 c0t0d0 \
spare c0t3d0 c1t2d0 c6t1d0
● 把root pool 和data pool分开
Opensolaris现在支持ZFS作为根文件系统,这带来了很多好处,比如快照,克隆,系统升级
方便等。从维护的角度来讲,应该把root pool 和data pool分开,因为root pool有一些限制比
如不能做RAIDZ等。另外如果root pool 和data pool不分开的话,重装系统或迁移数据时都会
有麻烦。
● 不要让ZFS Pool太满
当文件系统太满时,对于写操作需要寻找空闲块的时间会明显变长,影响性能。
● 对于大量小文件的应用不建议使用RAIDZ
前面对ZFS文件系统的介绍中提到,RAIDZ会影响读操作的性能。因为一个文件系统块被均
匀分摊到RAIDZ group的所有磁盘上,读一个块需要读RAIDZ group中所有的磁盘。这对于
小文件来讲性能影响会尤其明显。另外大量小文件意味着大量的metadata,如果建了一个大的
基于RAIDZ的存储池,当RAIDZ做数据恢复时磁盘重建的时间可能会很长。
|-- AI by Spruce Lab -- | Discover the Info. Tech. for Personal! && Powered by Solaris & Oracle

通告:即日起启用新MSN和Mail地址:aic.lab.sif@gmail.com 原来的最多1个月后停用!

TOP

Sun x4500作为文件服务器的调优
Sun x4500在互联网行业的典型应用就是作为文件服务器。通常数据是通过网络以http的方式
提供给客户端的机器。根据经验,Sun x4500上可以做一些优化:
系统参数
/etc/system:
set noexec_user_stack = 1 * for security, prevent execution on stack
set zfs:zfs_prefetch_disable = 1 * If the data is seldom re-used, turn off prefetch
set zfs:zfs_arc_max = 0x200000000 * 8GB cache size, leave some RAM for applications
set zfs:zfs_vdev_max_pending = 10 * for better I/O response time
set ip:ip_soft_rings_cnt = 3 * tcp/ip tuning
set ip:ip_squeue_soft_rings = 1 * tcp/ip tuning
set rlim_fd_cur = 65536 * allow applications to open more files simultaneously
网络设置
● 创建网络聚合
Sun x4500提供了4个千兆网口。作为一个高负荷的文件服务器,只使用一个千兆网口会造成
性能瓶颈。可以创建网络聚合(link aggregation)来同时使用多个网口。Solaris上管理 link
aggregation的命令是dladm。
以下是创建网络聚合的例子:创建3个网口的聚合。剩下一个网口可以做管理和监控用。但应
注意用于管理的网口的IP地址最好与聚合网口的IP地址在不同的网段上,否则业务网络的出
包可能会从管理用的网口出去,从而带宽受限制。
注意网络聚合还需要交换机的支持和配置(支持LACP协议)。
# dladm show-link
# ifconfig e1000g1 unplumb
# ifconfig e1000g2 unplumb
# ifconfig e1000g3 unplumb
# dladm create-aggr -d e1000g1 -d e1000g2 -d e1000g3 1
# ifconfig aggr1 plumb <new IP> up
# dladm show-aggr
(optional)If you want the config persistent after reboot, please:
# vi /etc/hostname.aggr1
<put the IP address in this file>
# reboot -- -r
● 主机上的网络流量监控
网络流量的监控可以用一个开源的工具nicstat来查看。
[bash]# nicstat 5
Time Int rKB/s wKB/s rPk/s wPk/s rAvs wAvs %Util Sat
17:05:17 lo0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
17:05:17 e1000g0 0.61 4.07 4.95 6.63 126.2 628.0 0.04 0.00
17:05:17 e1000g1 225.7 176.2 905.0 922.5 255.4 195.6 0.33 0.00
nicstat的下载地址:http://blogs.sun.com/timc/entry/ ... _network_monitoring
● TCP/IP的调整
创建一个脚本,根据需要调整相应的ndd参数
# cat /etc/rc2.d/S99ndd.sh
ndd -set /dev/tcp tcp_conn_req_max_q 8192 //应对大并发量的连接请求
ndd -set /dev/tcp tcp_conn_req_max_q0 8192 //应对大并发量的连接请求
ndd -set /dev/tcp tcp_recv_hiwat 131072 //增大tcp/ip 的receive buffer
ndd -set /dev/tcp tcp_xmit_hiwat 131072 //增大tcp/ip的send buffer
● 网络中断的调整
缺省情况下,Sun x4500四个网口的中断都会集中在一个CPU上。当网络流量很大时会成为瓶
颈。解决办法是:
#eeprom e1000g_intpt_bind_cpus=0,1,3 //让网络中断分散到第0,1,3号CPU
#reboot
● disable ipfilter
ipfilter会影响性能,如果不用的话可以disable掉:
#scvadm disable svc:/network/ipfilter:default
Sun x4500上Web server的设置
Web server的种类很多,常用的有apache,Sun Java Enterprise System webserver, lighttpd, nginx
等。对于Solaris上运行的开源Web server,建议下载使用SUN优化过的版本,里面包含了
apache, lighttpd和nginx。下载地址:http://cooltools.sunsource.net/coolstack/
无论采用哪种web server都要注意以下几点:
● 有足够的工作线程/进程来处理客户端的连接。
● 网络I/O复用模式
Solaris上没有epoll,可以使用/dev/poll或event port。某些Web server对event port的支持不是
很好,建议使用/dev/poll。
● 有足够的工作线程/进程来驱动I/O。
新一代的webserver都支持网络I/O复用,可以用较少的进程处理大量的网络连接。但是由于
这些webserver并不是专为文件服务所设计的,并且没有采用异步I/O。较少的进程往往不能
产生足够的I/O量,造成大量客户端长时间等待。所以需要加大webserver的工作进程数量。
对于lighttpd可以增加到32个进程,对于nginx甚至可以增加到上百个进程。
● 根据需要调整web server的I/O size
可以使用truss命令来观察web server每次I/O的大小,如果可能的话通过修改配置或源码的方
式调整I/O size,以提高I/O性能。
参考和推荐资源
● ZFS best practice guide
http://www.solarisinternals.com/ ... est_Practices_Guide
● ZFS evil tuning guide
http://www.solarisinternals.com/ ... S_Evil_Tuning_Guide
|-- AI by Spruce Lab -- | Discover the Info. Tech. for Personal! && Powered by Solaris & Oracle

通告:即日起启用新MSN和Mail地址:aic.lab.sif@gmail.com 原来的最多1个月后停用!

TOP


感谢一直以来您对我们的支持!
当前时区 GMT+8, 现在时间是 2008-11-21 00:57 京ICP证060528 号

Designed By 17DST