对于性能的优化着实是一个让人郁闷的问题。当然NAS从业者也不例外,而且NAS的问题更加棘手,因为它所涉及的协议和设备很多。本文将从共享协议入手,再到网络,最后到NAS服务器本身,逐层分析NAS性能的影响因素。
NAS的共享协议,就是之前介绍过的NFS和CIFS。他们的读写方式总体相似,但是细节处又有不同。我们先来看CIFS(SMB)的工作方式。
当我们在Windows Explorer上打开一个128KB的文件时,底层的读操作是这样的:
1. 客户端:我想读某文件。
2. NAS: 你有权限,读吧。
3. 客户端:先读64KB。
4. NAS:给你64KB。
5. 客户端:再读接下来的64KB。
6. NAS:给你64KB。
如果这个文件不只128KB,5和6就不断重复,直至整个文件读完。在这个过程中,影响性能的因素有:
1. 客户端总是在收到上一个读请求的回复后,再发送下一个请求。这其实是一种低效率的工作方式。就像某人今晚想吃肯德基的鸡翅和汉堡,他先叫鸡翅外卖,等鸡翅送达后,再叫汉堡外卖。合理的方式是鸡翅和汉堡外卖一起叫。在读文件时体现为:
1. 客户端:我想读某文件。
2. NAS: 你有权限,读吧。
3. 客户端:先读64KB。
4. 客户端:再读接下来的64KB。
5. NAS:给你64KB。
6. NAS:给你64KB。
由于3和4(两个请求),以及5和6(两个回复)可以接连发送,所以节省了往返时间(如下图所示)。SMB2的读操作就是以这种方式工作的。为了优化性能,建议把Windows客户端升级到Windows Vista或以上,然后启用SMB2。
2. 客户端每次读的数据大小,也会影响到性能。在上面的例子中客户端每次读64KB,是一个比较好的数值。如果读的值特别小(比如4KB),会增加读操作和往返次数,从而影响性能。这个值的大小是由客户端和服务器协商决定的。客户端上完全取决于应用程序,服务器上一般有设置选项。比如Windows服务器提供了SizReqBuf这个注册表键值供用户设置。
3. 另外一个性能影响因素是服务器的响应时间。对于读操作,最常用的优化方式是启用“prefetch”。即服务器在回复了前一个读请求后,立即把接下来的数据从硬盘中读出,等着回复下一个请求。
CIFS的写操作和读操作方式相似,对于相同点就不再赘述。不同点主要体现在响应时间的优化方式上。服务器为了优化写操作的响应时间,一般采用 write cache的方式。也就是服务器先把客户端写过来的数据存在cache里,然后向客户端确认。接下来再慢慢把cache里的数据刷进磁盘。当然这种方式存在一定的风险,如果服务器突然断电,cache里的数据就会丢失。客户端的应用程序可以启用write throuth来避免write cache。
下面,我们再看看NFS的工作方式。
和CIFS不同,NFS共享在使用前需要挂载(mount)。挂载时使用的参数很大程度上影响了读写的性能。列举如下:
1. UDP或TCP:在网络非常稳定的情况下,UDP理论上比TCP性能好一点,因为UDP包在协议上的消费比例低。但是如果有网络包丢失,TCP就显示出优势。因为UDP包丢失时,整个读/写操作的所有包都要重传;而TCP包丢失时,只需重传丢失的那个包即可。
2. rsize和wsize,每次读写的最大值。该值对性能的影响和CIFS的第二点是一样的,所以不再赘述。
3. sync和async,sync意味着服务器需要把数据写到磁盘再确认;async则意味着服务器可以把数据存到cache里就确认,然后再慢慢把 cache里的数据刷进磁盘。有一个经常被忽视的严重问题:sync参数会强制wsize变成4KB,这会大大降低写性能。