FreeBSD 使用手册
上一页 | 第12章 　设置和调整 | 下一页

# 12.13 调整内核限制

## 12.13.1 文件/进程限制

### 12.13.1.1 `kern.maxfiles`

`kern.maxfiles` 可以根据系统的需要适当增减。 这个变量用于指定在系统中允许的文件描述符的最大数量。 当文件描述符表满的时候， “`file: table is full`” 会在系统消息缓冲区中反复出现， 您可以使用 `dmesg` 命令来观察这一现象。

每个打开的文件、 套接字和管道， 都会占用一个文件描述符。 在大型生产服务器上， 可能会轻易地用掉数千个文件描述符， 具体用量取决于服务的类型和并行启动的服务数量。

在早期版本的 FreeBSD 中， `kern.maxfiles` 的默认值， 是根据您内核配置文件中的 `maxusers` 选项计算的。 `kern.maxfiles` 这个数值， 会随 `maxusers` 成比例地增减。 当编译定制的内核时， 按照您系统的用途来修改这个值是个好主意。 这个数字同时还决定内核的许多预设的限制值。 有时， 尽管并不会真的有 256 个用户同时连接一台生产服务器， 但对于高负载的 web 服务器而言， 却可能需要与之类似的资源。

变量 `kern.maxusers` 会在系统启动时， 根据可用内存的尺寸进行计算， 在内核开始运行之后， 可以通过只读的 `kern.maxusers` sysctl 变量值来进行观察。 有些情况下， 可能会希望使用更大或更小一些的 `kern.maxusers`， 它可以以加载器变量的形式进行配置； 类似 64、 128 和 256 这样的值都并不罕见。 我们不推荐使用超过 256 的值， 除非您需要巨量的文件描述符； 根据 `kern.maxusers` 推算默认值的那些变量， 一般都可以在引导甚至运行时通过 `/boot/loader.conf` (请参见 loader.conf(5) 联机手册或 `/boot/defaults/loader.conf` 文件来获得相关的指导) 或这篇文档的其余部分所介绍的方式来调整。

在较早的版本中， 如果您明确地将 `maxusers` 设置为 `0`， 则系统会自动地根据硬件配置来确定这个值。[1]。 在 FreeBSD 5.X 和更高版本中， `maxusers` 如果不指定的话， 就会取默认值 `0`。 如果希望自行管理 `maxusers`， 则应配置一个不低于 4 的值， 特别是使用 X Window System 或编译软件的时候。 这样做的原因是， `maxusers` 所决定的一个最为重要的表的尺寸会影响最大进程数， 这个数值将是 `20 + 16 * maxusers`。 因此如果将 `maxusers` 设置为 1， 您就只能同时运行 36 个进程， 这还包括了 18 个左右的系统引导时启动的进程， 以及 15 个左右的， 在您启动 X Window System 时所引发的进程。 即使是简单的任务， 如阅读联机手册， 也需要启动多至九个的进程， 用以过滤、 解压缩， 并显示它。 将 `maxusers` 设为 64 将允许您同时执行最多 1044 个进程， 这几乎足以满足任何需要了。 不过， 如果您看在启动其它程序， 或运行用以支持大量用户的服务 (例如 `ftp.FreeBSD.org`) 时， 看到令人担忧的 proc table full 错误， 就应该提高这一数值， 并重新联编内核。

> 注意: `maxusers` 并 不能 限制实际能够登录到您系统上来的用户的数量。 它的主要作用是根据您可能支持的用户数量来为一系列系统数据表设置合理的尺寸， 以便提供支持他们所需运行的进程资源。

### 12.13.1.2 `kern.ipc.somaxconn`

`kern.ipc.somaxconn` sysctl 变量 限制了接收新 TCP 连接侦听队列的大小。对于一个经常处理新连接的高负载 web服务环境来说，默认的 `128` 太小了。 大多数环境这个值建议增加到 `1024` 或者更多。 服务进程会自己限制侦听队列的大小(例如 sendmail(8) 或者 Apache)， 常常在它们的配置文件中有设置队列大小的选项。 大的侦听队列对防止拒绝服务 DoS 攻击也会有所帮助。

## 12.13.2 网络限制

`NMBCLUSTERS` 内核配置选项指出了系统可用的网络Mbuf的数量。 一个高流量的服务器使用一个小数目的网络缓存会影响 FreeBSD 的性能。 每个 cluster 可能需要2K内存，所以一个1024的值需要在内核中给网络缓存保留2M内存。 可以用简单的方法计算出来需要多少网络缓存。 如果您有一个同时发生1000个以上连接的web服务器， 并且每个连接用掉16K接收和发送缓存， 就需要大概32M网络缓存来确保web服务器的工作。 一个好的简单计算方法是乘以2，所以2x32Mb/2Kb=64MB/2kb=32768。 我们建议在有大量内存的机器上把这个值设置在4096到32768之间。 没有必要把它设置成任意太高的值，它会在启动时引起崩溃。 netstat(1) 的 `-m` 选项可以用来观察网络cluster使用情况。

`kern.ipc.nmbclusters` 可以用来在启动时刻调节这个。 仅仅在旧版本的 FreeBSD 需要使用 `NMBCLUSTERS` config(8) 选项。

经常使用 sendfile(2) 系统调用的繁忙的服务器， 有必要通过 `NSFBUFS` 内核选项或者在 `/boot/loader.conf` (查看 loader(8) 以获得更多细节) 中设置它的值来调节 sendfile(2) 缓存数量。 这个参数需要调节的普通原因是在进程中看到 `sfbufa` 状态。sysctl `kern.ipc.nsfbufs` 变量在内核配置变量中是只读的。 这个参数是由 `kern.maxusers` 决定的，然而它可能有必要因此而调整。

> 重要: 即使一个套接字被标记成非阻塞，在这个非阻塞的套接字上呼叫 sendfile(2) 可能导致 sendfile(2) 呼叫阻塞直到有足够的 `struct sf_buf` 可用。

### 12.13.2.1 `net.inet.ip.portrange.*`

`net.inet.ip.portrange.*` sysctl 变量自动的控制绑定在 TCP 和 UDP 套接字上的端口范围。 这里有三个范围：一个低端范围，一个默认范围和一个高端范围。 大多数网络程序分别使用由 `net.inet.ip.portrange.first` 和 `net.inet.ip.portrange.last` 控制的从 1024 到 5000 的默认范围。端口范围用作对外连接，并且某些情况可能用完系统的端口， 这经常发生在运行一个高负荷 web 代理服务器的时候。 这个端口范围不是用来限制主要的例如 web 服务器进入连接或者有固定端口例如邮件传递对外连接的。 有时您可能用完了端口，那就建议适当的增加 `net.inet.ip.portrange.last`。 `10000`、`20000` 或者 `30000` 可能是适当的值。 更改端口范围的时候也要考虑到防火墙。 一些防火墙会阻止端口的大部分范围 (通常是低范围的端口)并且用高端口进行对外连接(──)。 基于这个问题建议不要把 `net.inet.ip.portrange.first` 设的太小。

### 12.13.2.2 TCP 带宽迟延(Bandwidth Delay Product)

限制 TCP 带宽延迟积和 NetBSD 的 TCP/Vegas 类似。 它可以通过将 sysctl 变量 `net.inet.tcp.inflight.enable` 设置成 `1` 来启用。 系统将尝试计算每一个连接的带宽延迟积， 并将排队的数据量限制在恰好能保持最优吞吐量的水平上。

这一特性在您的服务器同时向使用普通调制解调器， 千兆以太网， 乃至更高速度的光与网络连接 (或其他带宽延迟积很大的连接) 的时候尤为重要， 特别是当您同时使用滑动窗缩放， 或使用了大的发送窗口的时候。 如果启用了这个选项， 您还应该把 `net.inet.tcp.inflight.debug` 设置为 `0` (禁用调试)， 对于生产环境而言， 将 `net.inet.tcp.inflight.min` 设置成至少 `6144` 会很有好处。 然而， 需要注意的是， 这个值设置过大事实上相当于禁用了连接带宽延迟积限制功能。 这个限制特性减少了在路由和交换包队列的堵塞数据数量， 也减少了在本地主机接口队列阻塞的数据的数量。在少数的等候队列中、 交互式连接，尤其是通过慢速的调制解调器，也能用低的 往返时间操作。但是，注意这只影响到数据发送 (上载/服务端)。对数据接收(下载)没有效果。

调整 `net.inet.tcp.inflight.stab` 是 不 推荐的。 这个参数的默认值是 20， 表示把 2 个最大包加入到带宽延迟积窗口的计算中。 额外的窗口似的算法更为稳定， 并改善对于多变网络环境的相应能力， 但也会导致慢速连接下的 ping 时间增长 (尽管还是会比没有使用 inflight 算法低许多)。 对于这些情形， 您可能会希望把这个参数减少到 15， 10， 或 5； 并可能因此而不得不减少 `net.inet.tcp.inflight.min` (比如说， 3500) 来得到希望的效果。 减少这些参数的值， 只应作为最后不得已时的手段来使用。

## 12.13.3 虚拟内存

### 12.13.3.1 `kern.maxvnodes`

vnode 是对文件或目录的一种内部表达。 因此， 增加可以被操作系统利用的 vnode 数量将降低磁盘的 I/O。 一般而言， 这是由操作系统自行完成的， 也不需要加以修改。 但在某些时候磁盘 I/O 会成为瓶颈， 而系统的 vnode 不足， 则这一配置应被增加。 此时需要考虑是非活跃和空闲内存的数量。

要查看当前在用的 vnode 数量：

    # sysctl vfs.numvnodes
    vfs.numvnodes: 91349

要查看最大可用的 vnode 数量：

    # sysctl kern.maxvnodes
    kern.maxvnodes: 100000

如果当前的 vnode 用量接近最大值， 则将 `kern.maxvnodes` 值增大 1,000 可能是个好主意。 您应继续查看 `vfs.numvnodes` 的数值， 如果它再次攀升到接近最大值的程度， 仍需继续提高 `kern.maxvnodes`。 在 top(1) 中显示的内存用量应有显著变化， 更多内存会处于活跃 (active) 状态。

### 备注

[1] | 自动调整算法会将 `maxusers` 设置为与主存的数量一样， 或者取其下限 32 或上限 384。

上一页 | 起始页 | 下一页
调整磁盘 | 上一级 | 添加交换空间

本文档和其它文档可从这里下载：ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/.

如果对于FreeBSD有问题，请先阅读文档，如不能解决再联系<questions@FreeBSD.org>.
关于本文档的问题请发信联系 <doc@FreeBSD.org>.