1、背景
Linux nfs客户端对于同时发起的NFS请求数量进行了控制,若该参数配置较小会导致IO性能较差。可以如下命令配置该参数:
cat /proc/sys/sunrpc/tcp_slot_table_entries
默认编译的内核该参数最大值为256,可适当提高该参数的值来取得较好的性能,以root身份执行以下命令
echo "options sunrpc tcp_slot_table_entries=128" >> /etc/modprobe.d/sunrpc.conf
echo "options sunrpc tcp_max_slot_table_entries=128" >> /etc/modprobe.d/sunrpc.conf
sysctl -w sunrpc.tcp_slot_table_entries=128
修改完成后,您需要重新挂载文件系统或重启机器。
2、原因分析
下面来分析下tcp_slot_table_entries这个参数是如何影响nfs性能的
nfs协议使用sunrpc通信,linux kernel中sunrpc的实现是单连接和长链接,只有在一些特殊情况下才会新建连接。为了提高并发性能,在单连接的基础上提供多个slot。
nfs client发送请求过程简化如下:
(1)、每个nfs请求首先会分配一个空闲的slot,用来保存buffer和xid等一些环境上下文。
(2)、slot分配成功后,做一些初始化的工作,等待socket可写(send buffer是否满),
(3)、编码,包括slot的xid,nfs请求序列化成xdr。
(4)、调用send_request把编码后的数据包发送到对端。
(5)、收到对端的请求后,从header中解码出xid,根据xid找到对应的slot和上下文。
(6)、请求处理结束后释放slot。
从上述分析和上图中可以看出slot的个数决定了同时处理nfs请求的个数。slot个数越多,nfs请求并发处理能力越强,如果slot个数很小,而nfs请求又很多,就会在client排队等待。而不幸的是linux很多发行版本中,slot个数默认值都是2,所以基本上只有串行处理的能力,即使应用层有再多的并发也没有用。
上述分析做了简化处理,具体可以参考kernel代码实现。linux kernel中,nfs client的实现在fs/nfs/目录下,sunrpc的实现在net/sunrpc/目录下。