Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
nginx
GitHub Repository: nginx/nginx.org
Path: blob/main/xml/en/docs/freebsd_tuning.xml
1 views
1
<!--
2
Copyright (C) Igor Sysoev
3
Copyright (C) Nginx, Inc.
4
-->
5
6
<!DOCTYPE article SYSTEM "../../../dtd/article.dtd">
7
8
<article name="Tuning FreeBSD for the highload"
9
link="/en/docs/tuning_freebsd.html"
10
lang="en"
11
rev="1">
12
13
14
<section id="listen_queues"
15
name="Listen queues">
16
17
<para>
18
After the connection has been established it is placed in the listen queue
19
of the listen socket.
20
To see the current listen queues state, you may run the command
21
<command>netstat -Lan</command>”:
22
23
<programlisting>
24
Current listen queue sizes (qlen/incqlen/maxqlen)
25
Proto Listen Local Address
26
tcp4 <b>10</b>/0/128 *.80
27
tcp4 0/0/128 *.22
28
</programlisting>
29
30
This is a normal case: the listen queue of the port *:80 contains
31
just 10 unaccepted connections.
32
If the web server is not able to handle the load, you may see
33
something like this:
34
35
<programlisting>
36
Current listen queue sizes (qlen/incqlen/maxqlen)
37
Proto Listen Local Address
38
tcp4 <b>192/</b>0/<b>128</b> *.80
39
tcp4 0/0/128 *.22
40
</programlisting>
41
42
Here are 192 unaccepted connections and most likely new coming connections
43
are discarding. Although the limit is 128 connections, FreeBSD allows
44
receiving 1.5 times connections than the limit before it starts to discard
45
the new connections. You may increase the limit using
46
47
<programlisting>
48
sysctl kern.ipc.soacceptqueue=4096
49
</programlisting>
50
51
However, note that the queue is only a damper to quench bursts.
52
If it is always overflowed, this means that you need to improve the web server,
53
but not to continue to increase the limit.
54
You may also change the listen queue maximum size in nginx configuration:
55
56
<programlisting>
57
listen 80 backlog=1024;
58
</programlisting>
59
60
However, you may not set it more than the current
61
<path>kern.ipc.soacceptqueue</path> value.
62
By default nginx uses the maximum value of FreeBSD kernel.
63
</para>
64
65
</section>
66
67
68
<section id="socket_buffers"
69
name="Socket buffers">
70
71
<para>
72
When a client sends a data, the data first is received by the kernel
73
which places the data in the socket receiving buffer.
74
Then an application such as the web server
75
may call <c-func>recv</c-func> or <c-func>read</c-func> system calls
76
to get the data from the buffer.
77
When the application wants to send a data, it calls
78
<c-func>send</c-func> or <c-func>write</c-func>
79
system calls to place the data in the socket sending buffer.
80
Then the kernel manages to send the data from the buffer to the client.
81
In modern FreeBSD versions the default sizes of the socket receiving
82
and sending buffers are respectively 64K and 32K.
83
You may change them on the fly using the sysctls
84
<path>net.inet.tcp.recvspace</path> and
85
<path>net.inet.tcp.sendspace</path>.
86
Of course the bigger buffer sizes may increase throughput,
87
because connections may use bigger TCP sliding windows sizes.
88
And on the Internet you may see recommendations to increase
89
the buffer sizes to one or even several megabytes.
90
However, such large buffer sizes are suitable for local networks
91
or for networks under your control.
92
Since on the Internet a slow network client may ask a large file
93
and then it will download the file during several minutes if not hours.
94
All this time the megabyte buffer will be bound to the slow client,
95
although we may devote just several kilobytes to it.
96
</para>
97
98
<para>
99
There is one more advantage of the large sending buffers for
100
the web servers such as Apache which use the blocking I/O system calls.
101
The server may place a whole large response in the sending buffer, then may
102
close the connection, and let the kernel to send the response to a slow client,
103
while the server is ready to serve other requests.
104
You should decide what is it better to bind to a client in your case:
105
a tens megabytes Apache/mod_perl process
106
or the hundreds kilobytes socket sending buffer.
107
Note that nginx uses non-blocking I/O system calls
108
and devotes just tens kilobytes to connections,
109
therefore it does not require the large buffer sizes.
110
</para>
111
112
</section>
113
114
115
<section id="mbufs"
116
name="mbufs, mbuf clusters, etc.">
117
118
<para>
119
Inside the kernel the buffers are stored in the form of chains of
120
memory chunks linked using the <i>mbuf</i> structures.
121
The mbuf size is 256 bytes and it can be used to store a small amount
122
of data, for example, TCP/IP header. However, the mbufs point mostly
123
to other data stored in the <i>mbuf clusters</i> or <i>jumbo clusters</i>,
124
and in this kind they are used as the chain links only.
125
The mbuf cluster size is 2K.
126
The jumbo cluster size can be equal to a CPU page size (4K for amd64),
127
9K, or 16K.
128
The 9K and 16K jumbo clusters are used mainly in local networks with Ethernet
129
frames larger than usual 1500 bytes, and they are beyond the scope of
130
this article.
131
The page size jumbo clusters are usually used for sending only,
132
while the mbuf clusters are used for both sending and receiving.
133
134
To see the current usage of the mbufs and clusters and their limits,
135
you may run the command <nobr><command>netstat -m</command>”.</nobr>
136
Here is a sample from FreeBSD 7.2/amd64 with the default settings:
137
138
<programlisting>
139
1477/<b>3773/5250 mbufs</b> in use (current/cache/total)
140
771/2203/<b>2974/25600 mbuf clusters</b> in use (current/cache/total/max)
141
771/1969 mbuf+clusters out of packet secondary zone in use
142
(current/cache)
143
296/863/<b>1159/12800 4k (page size) jumbo clusters</b> in use
144
(current/cache/total/max)
145
0/0/0/6400 9k jumbo clusters in use (current/cache/total/max)
146
0/0/0/3200 16k jumbo clusters in use (current/cache/total/max)
147
3095K/8801K/11896K bytes allocated to network(current/cache/total)
148
0/0/0 requests for mbufs denied (mbufs/clusters/mbuf+clusters)
149
0/0/0 requests for jumbo clusters denied (4k/9k/16k)
150
0/0/0 sfbufs in use (current/peak/max)
151
0 requests for sfbufs denied
152
0 requests for sfbufs delayed
153
523590 requests for I/O initiated by sendfile
154
0 calls to protocol drain routines
155
</programlisting>
156
157
There are 12800 page size jumbo clusters,
158
therefore they can store only 50M of data.
159
If you set the <path>net.inet.tcp.sendspace</path> to 1M,
160
then merely 50 slow clients will take all jumbo clusters
161
requesting large files.
162
</para>
163
164
<para>
165
You may increase the clusters limits on the fly using:
166
167
<programlisting>
168
sysctl kern.ipc.nmbclusters=200000
169
sysctl kern.ipc.nmbjumbop=100000
170
</programlisting>
171
172
The former command increases the mbuf clusters limit
173
and the latter increases page size jumbo clusters limit.
174
Note that all allocated mbufs clusters will take about 440M physical memory:
175
(200000 &times; (2048 + 256)) because each mbuf cluster requires also the mbuf.
176
All allocated page size jumbo clusters will take yet about 415M physical memory:
177
(100000 &times; (4096 + 256)).
178
And together they may take 845M.
179
</para>
180
181
<para>
182
There is way not to use the jumbo clusters while serving static files:
183
the <i>sendfile()</i> system call.
184
The sendfile allows sending a file or its part to a socket directly
185
without reading the parts in an application buffer.
186
It creates the mbufs chain where the mbufs point to the file pages that are
187
already present in FreeBSD cache memory, and passes the chain to
188
the TCP/IP stack.
189
Thus, sendfile decreases both CPU usage by omitting two memory copy operations,
190
and memory usage by using the cached file pages.
191
</para>
192
193
</section>
194
195
196
<section id="proxying"
197
name="Outgoing connections">
198
199
200
<programlisting>
201
net.inet.ip.portrange.randomized=0
202
net.inet.ip.portrange.first=1024
203
net.inet.ip.portrange.last=65535
204
</programlisting>
205
206
</section>
207
208
209
<section id="finalizing_connection"
210
name="Finalizing connection">
211
212
<programlisting>
213
net.inet.tcp.fast_finwait2_recycle=1
214
</programlisting>
215
216
</section>
217
218
</article>
219
220