14.9.内核参数优化 ================= 14.9.1.文件/进程优化 -------------------- 14.9.1.1. ``kern.maxfiles`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 可根据系统的要求来提高或降低 `sysctl(8) `__ 变量 ``kern.maxfiles``\ 。这个变量表示系统中文件描述符的最大数量。当文件描述符表已满时,\ ``file: table is full`` 会在系统消息缓冲区中反复显示,可以用 `dmesg(8) `__ 查看。 每个打开的文件、套接字或 fifo 都占用一个文件描述符。大规模的生产型服务器可能很容易需要成千上万的文件描述符,这取决于同时运行的服务的种类和数量。 在较早的 FreeBSD 版本中,\ ``kern.maxfiles`` 的默认值来自于内核配置文件中的 ``maxusers``\ 。\ ``kern.maxfiles`` 的增长与 ``maxusers`` 的值成比例。当编译一个定制内核时,应根据系统的使用情况来设置这个内核配置选项。从这个数字来看,内核被赋予了大部分的预定义优化。即使一台生产机器可能没有 256 个并发用户,但所需要的资源可能与一个高规模的网络服务器相似。 `sysctl(8) `__ 只读变量 ``kern.maxusers`` 在启动时根据系统中可用的内存量自动确定大小,也可以在运行时通过检查 ``kern.maxusers`` 的值来确定。有些系统需要更大或更小的 ``kern.maxusers`` 值,64、128 和 256 的值多为常见。除非需要大量的文件描述符,否则不建议超过 256。许多被 ``kern.maxusers`` 设置为默认值的可调整值可以在启动时或运行时在 ``/boot/loader.conf`` 中被单独重新设置。请参考 `loader.conf(5) `__ 和 **/boot/defaults/loader.conf** 以了解更多细节和一些提示。 在较早的版本中,如果 ``maxusers`` 被设置为 0(注 2),系统会自动进行调整。在设置这个选项时,至少要把 ``maxusers`` 设置为 4,特别是在系统运行 Xorg 或用来编译软件的情况下。\ ``maxusers`` 设置的最重要的表是最大进程数,它被设置为 ``20 + 16 * maxusers``\ 。如果 ``maxusers`` 被设置为 1,则只能有 36 个同时进行的进程,包括系统在启动时启动的 18 个左右的进程和 Xorg 使用的 15 个左右的进程。即使是一个简单的任务,比如阅读一个手册页面,也会启动 9 个进程来过滤、解压和查看它。将 ``maxusers`` 设置为 64,最多允许 1044 个同时进行的进程,这应该足以满足几乎所有的用途。但是,如果在试图启动另一个程序时显示错误,或者服务器在运行时有大量的并发用户,请增加数量并重新编译。 **注意** ``maxusers`` 并 *不* 限制可以登录机器的用户数量。相反,考虑到系统中的最大用户数和每个用户将运行的进程数,它将各种表的大小设置为合理值。 .. **注 2** 自动调整算法将 ``maxusers`` 设定为等同系统中的内存量,最小为 32,最大为 384。 14.9.1.2. ``kern.ipc.soacceptqueue`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ `sysctl(8) `__ 变量 ``kern.ipc.soacceptqueue`` 限制了用于接受新 TCP 连接的监听队列的大小。默认值 128 通常太低,不利于稳健地处理高负荷的 web 服务器上的新连接。对于这样的环境,建议将这个值增加到 1024 或更高。像 `sendmail(8) `__ 或 Apache 这样的服务可能本身就限制了监听队列的大小,但通常在其配置文件中会有一个指令来调整队列大小。大的监听队列在避免拒绝服务(DoS)攻击方面更具优势。 14.9.2.网络优化 --------------- 内核配置选项 ``NMBCLUSTERS`` 决定了系统可用的网络 Mbufs 的数量。一个大量使用的服务器,如果 Mbufs 的数量很低,会妨碍性能。每个簇代表大约 2K 的内存,所以 1024 的值代表 2 兆字节的内核内存保留给网络缓冲区。可以做一个简单的计算来计算出需要多少个。一个网络服务器的最大同时连接数为 1000,每个连接使用 6K 的接收和 16K 的发送缓冲区,需要大约 32MB 的网络缓冲区来覆盖网络服务器。一个好的经验法则是乘以 2,所以 2 x 32 MB / 2 KB = 64 MB / 2 kB = ``32768``\ 。对于拥有更大内存的机器,建议使用 4096 和 32768 之间的值。千万不要为这个参数随意指定一个高的值,因为它可能导致启动时崩溃。要观察网络缓冲族的使用情况,可以使用 `netstat(1) `__ ``-m``\ 。 应该使用可调参数 ``kern.ipc.nmbclusters`` 来在启动时进行优化。只有老版本的 FreeBSD 需要使用 ``NMBCLUSTERS`` 内核选项 `config(8) `__\ 。 对于大量使用 ``sendfile(2)`` 系统调用的繁忙服务器,可能需要通过内核配置选项 ``NSFBUFS`` 或在 **boot/loader.conf** 中设置其值来增加 `sendfile(2) `__\ 冲区的数量 (详见 `oader(8) `__)。这个参数需要优化的一个常见指标是看到当进程处于 ``sfbufa`` 状态时。\ `sysctl(8) `__ 变量 ``kern.ipc.nsfbufs`` 是只读的。这个参数在名义上与 ``kern.maxusers`` 呈比例关系,但可能需要进行相应的调整。 **重要** 即使一个套接字被标记为非阻塞,在其上调用 `sendfile(2) `__ 时仍可能会导致 `sendfile(2) `__ 的调用阻塞,除非有足够的 ``struct sf_buf`` 可用。 14.9.2.1. ``net.inet.ip.portrange.*`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ `sysctl(8) `__ 变量 ``net.inet.ip.portrange.*`` 控制自动绑定到 TCP 和 UDP 套接字的端口号范围,其中有三个范围:低范围,默认范围和高范围。大多数网络程序使用默认范围,它由 ``net.inet.ip.portrange.first`` 和 ``net.inet.ip.portrange.last`` 控制,它们的默认值分别为 1024 和 5000。绑定的端口范围用于出站连接,在某些情况下,系统有可能运行到端口之外。这种情况最常发生在运行一个高负荷的网络代理时。当运行一个主要处理传入连接的服务器,如 Web 服务器,或有有限数量的传出连接,如邮件中转时,端口范围不是问题。对于端口不足的情况,建议适度增加 ``net.inet.ip.portrange.last``\ 。10000、20000 或 30000 的数值可能是合理的。在改变端口范围时要考虑到防火墙的影响。一些防火墙可能会阻止大范围的端口,通常是低编号的端口,并希望系统使用较高范围的端口进行外发连接。出于这个原因,不建议降低 ``net.inet.ip.portrange.first`` 的值。 14.9.3.虚拟内存 --------------- 14.9.3.1. ``kern.maxvnodes`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 虚拟节点(vnode)是一个文件或目录的内部存在形式。增加操作系统可用的虚拟节点的数量可以减少磁盘 I/O。通常情况下,这是由操作系统处理的,不需要改变。在某些情况下,磁盘 I/O 是一个瓶颈,系统正在耗尽虚拟节点,这时需要增加虚拟节点。非活跃和空闲的内存的数量需要被考虑在内。 要查看当前正在使用的虚拟节点的数量: .. raw:: latex \diilbookstyleinputcell .. code:: shell-session # sysctl vfs.numvnodes vfs.numvnodes: 91349 查看虚拟节点的最大数量: .. raw:: latex \diilbookstyleinputcell .. code:: shell-session # sysctl kern.maxvnodes kern.maxvnodes: 100000 如果当前的虚拟节点使用量接近最大值,可以尝试将 ``kern.maxvnodes`` 的数值增加到 ``1000``\ 。应密切关注 ``vfs.numvnodes`` 的数量,如果它再次攀升到最大值,将需要进一步增加 ``kern.maxvnodes``\ 。除此之外,\ `top(1) `__ 报告的内存的使用变化是可见的,并且应该有更多的内存处于活动状态。