Whamcloud - gitweb
LUDOC-108 dne: Manual includes DNE usage instructions.
[doc/manual.git] / LustreTuning.xml
1 <?xml version='1.0' encoding='UTF-8'?>
2 <!-- This document was created with Syntext Serna Free. --><chapter xmlns="http://docbook.org/ns/docbook" xmlns:xl="http://www.w3.org/1999/xlink" version="5.0" xml:lang="en-US" xml:id="lustretuning">
3   <title xml:id="lustretuning.title">Lustre Tuning</title>
4   <para>This chapter contains information about tuning Lustre for better performance and includes the following sections:</para>
5   <itemizedlist>
6     <listitem>
7       <para><xref linkend="dbdoclet.50438272_55226"/></para>
8     </listitem>
9     <listitem>
10       <para><xref linkend="dbdoclet.mdstuning"/></para>
11     </listitem>
12     <listitem>
13       <para><xref linkend="dbdoclet.50438272_73839"/></para>
14     </listitem>
15     <listitem>
16       <para><xref linkend="dbdoclet.libcfstuning"/></para>
17     </listitem>
18     <listitem>
19       <para><xref linkend="dbdoclet.lndtuning"/></para>
20     </listitem>
21     <listitem>
22       <para><xref linkend="dbdoclet.50438272_25884"/></para>
23     </listitem>
24     <listitem>
25       <para><xref linkend="dbdoclet.50438272_80545"/></para>
26     </listitem>
27     <listitem>
28       <para><xref linkend="dbdoclet.50438272_45406"/></para>
29     </listitem>
30   </itemizedlist>
31   <note>
32     <para>Many options in Lustre are set by means of kernel module parameters. These parameters are contained in the <literal>/etc/modprobe.d/lustre.conf</literal> file.</para>
33   </note>
34   <section xml:id="dbdoclet.50438272_55226">
35       <title>
36           <indexterm><primary>tuning</primary></indexterm>
37 <indexterm><primary>tuning</primary><secondary>service threads</secondary></indexterm>
38           Optimizing the Number of Service Threads</title>
39     <para>An OSS can have a minimum of 2 service threads and a maximum of 512 service threads. The number of service threads is a function of how much RAM and how many CPUs are on each OSS node (1 thread / 128MB * num_cpus). If the load on the OSS node is high, new service threads will be started in order to process more requests concurrently, up to 4x the initial number of threads (subject to the maximum of 512). For a 2GB 2-CPU system, the default thread count is 32 and the maximum thread count is 128.</para>
40     <para>Increasing the size of the thread pool may help when:</para>
41     <itemizedlist>
42       <listitem>
43         <para>Several OSTs are exported from a single OSS</para>
44       </listitem>
45       <listitem>
46         <para>Back-end storage is running synchronously</para>
47       </listitem>
48       <listitem>
49         <para>I/O completions take excessive time due to slow storage</para>
50       </listitem>
51     </itemizedlist>
52     <para>Decreasing the size of the thread pool may help if:</para>
53     <itemizedlist>
54       <listitem>
55         <para>Clients are overwhelming the storage capacity</para>
56       </listitem>
57       <listitem>
58         <para>There are lots of &quot;slow I/O&quot; or similar messages</para>
59       </listitem>
60     </itemizedlist>
61     <para>Increasing the number of I/O threads allows the kernel and storage to aggregate many writes together for more efficient disk I/O. The OSS thread pool is shared--each thread allocates approximately 1.5 MB (maximum RPC size + 0.5 MB) for internal I/O buffers.</para>
62     <para>It is very important to consider memory consumption when increasing the thread pool size. Drives are only able to sustain a certain amount of parallel I/O activity before performance is degraded, due to the high number of seeks and the OST threads just waiting for I/O. In this situation, it may be advisable to decrease the load by decreasing the number of OST threads.</para>
63     <para>Determining the optimum number of OST threads is a process of trial and error, and varies for each particular configuration. Variables include the number of OSTs on each OSS, number and speed of disks, RAID configuration, and available RAM. You may want to start with a number of OST threads equal to the number of actual disk spindles on the node. If you use RAID, subtract any dead spindles not used for actual data (e.g., 1 of N of spindles for RAID5, 2 of N spindles for RAID6), and monitor the performance of clients during usual workloads. If performance is degraded, increase the thread count and see how that works until performance is degraded again or you reach satisfactory performance.</para>
64     <note>
65       <para>If there are too many threads, the latency for individual I/O requests can become very high and should be avoided. Set the desired maximum thread count permanently using the method described above.</para>
66     </note>
67     <section>
68       <title><indexterm><primary>tuning</primary><secondary>OSS threads</secondary></indexterm>Specifying the OSS Service Thread Count</title>
69       <para>The <literal>oss_num_threads</literal> parameter enables the number of OST service threads to be specified at module load time on the OSS nodes:</para>
70       <screen>options ost oss_num_threads={N}</screen>
71       <para>After startup, the minimum and maximum number of OSS thread counts can be set via the <literal>{service}.thread_{min,max,started}</literal> tunable. To change the tunable at runtime, run:</para>
72       <para><screen>lctl {get,set}_param {service}.thread_{min,max,started}</screen></para>
73       <para>Lustre 2.3 introduced binding service threads to CPU partition. This works in a similar fashion to binding of threads on MDS. MDS thread tuning is covered in <xref linkend="dbdoclet.mdsbinding"/>.</para>
74     <itemizedlist>
75       <listitem>
76         <para><literal>oss_cpts=[EXPRESSION]</literal> binds the default OSS service on CPTs defined by <literal>[EXPRESSION]</literal>.</para>
77       </listitem>
78       <listitem>
79         <para><literal>oss_io_cpts=[EXPRESSION]</literal> binds the IO OSS service on CPTs defined by <literal>[EXPRESSION]</literal>.</para>
80       </listitem>
81     </itemizedlist>
82
83       <para>For further details, see <xref linkend="dbdoclet.50438271_87260"/>.</para>
84     </section>
85     <section xml:id="dbdoclet.mdstuning">
86       <title><indexterm><primary>tuning</primary><secondary>MDS threads</secondary></indexterm>Specifying the MDS Service Thread Count</title>
87       <para>The <literal>mds_num_threads</literal> parameter enables the number of MDS service threads to be specified at module load time on the MDS node:</para>
88       <screen>options mds mds_num_threads={N}</screen>
89       <para>After startup, the minimum and maximum number of MDS thread counts can be set via the <literal>{service}.thread_{min,max,started}</literal> tunable. To change the tunable at runtime, run:</para>
90       <para><screen>lctl {get,set}_param {service}.thread_{min,max,started}</screen></para>
91       <para>For details, see <xref linkend="dbdoclet.50438271_87260"/>.</para>
92       <para>At this time, no testing has been done to determine the optimal number of MDS threads. The default value varies, based on server size, up to a maximum of 32. The maximum number of threads (<literal>MDS_MAX_THREADS</literal>) is 512.</para>
93       <note>
94         <para>The OSS and MDS automatically start new service threads dynamically, in response to server load within a factor of 4. The default value is calculated the same way as before. Setting the <literal>_mu_threads</literal> module parameter disables automatic thread creation behavior.</para>
95       </note>
96         <para>Lustre 2.3 introduced new parameters to provide more control to administrators.</para>
97             <itemizedlist>
98               <listitem>
99                 <para><literal>mds_rdpg_num_threads</literal> controls the number of threads in providing the read page service. The read page service handles file close and readdir operations.</para>
100               </listitem>
101               <listitem>
102                 <para><literal>mds_attr_num_threads</literal> controls the number of threads in providing the setattr service to 1.8 clients.</para>
103               </listitem>
104             </itemizedlist>
105         <note><para>Default values for the thread counts are automatically selected. The values are chosen to best exploit the number of CPUs present in the system and to provide best overall performance for typical workloads.</para></note>
106     </section>
107   </section>
108     <section xml:id="dbdoclet.mdsbinding" condition='l24'>
109       <title><indexterm><primary>tuning</primary><secondary>MDS binding</secondary></indexterm>Binding MDS Service Thread to CPU Partitions</title>
110         <para>With the introduction of Node Affinity (<xref linkend="nodeaffdef"/>) in Lustre 2.3, MDS threads can be bound to particular CPU Partitions (CPTs). Default values for bindings are selected automatically to provide good overall performance for a given CPU count. However, an administrator can deviate from these setting if they choose.</para>
111             <itemizedlist>
112               <listitem>
113                 <para><literal>mds_num_cpts=[EXPRESSION]</literal> binds the default MDS service threads to CPTs defined by <literal>EXPRESSION</literal>. For example <literal>mdt_num_cpts=[0-3]</literal> will bind the MDS service threads to <literal>CPT[0,1,2,3]</literal>.</para>
114               </listitem>
115               <listitem>
116                 <para><literal>mds_rdpg_num_cpts=[EXPRESSION]</literal> binds the read page service threads to CPTs defined by <literal>EXPRESSION</literal>. The read page service handles file close and readdir requests. For example <literal>mdt_rdpg_num_cpts=[4]</literal> will bind the read page threads to <literal>CPT4</literal>.</para>
117               </listitem>
118               <listitem>
119                 <para><literal>mds_attr_num_cpts=[EXPRESSION]</literal> binds the setattr service threads to CPTs defined by <literal>EXPRESSION</literal>.</para>
120               </listitem>
121             </itemizedlist>
122   </section>
123   <section xml:id="dbdoclet.50438272_73839">
124       <title>
125           <indexterm><primary>LNET</primary><secondary>tuning</secondary>
126       </indexterm><indexterm><primary>tuning</primary><secondary>LNET</secondary></indexterm>Tuning LNET Parameters</title>
127     <para>This section describes LNET tunables. that may be necessary on some systems to improve performance. To test the performance of your Lustre network, see <link xl:href="LNETSelfTest.html#50438223_71556">Chapter 23</link>: <link xl:href="LNETSelfTest.html#50438223_21832">Testing Lustre Network Performance (LNET Self-Test)</link>.</para>
128     <section remap="h3">
129       <title>Transmit and Receive Buffer Size</title>
130       <para>The kernel allocates buffers for sending and receiving messages on a network.</para>
131       <para><literal>ksocklnd</literal> has separate parameters for the transmit and receive buffers.</para>
132       <screen>options ksocklnd tx_buffer_size=0 rx_buffer_size=0
133 </screen>
134       <para>If these parameters are left at the default value (0), the system automatically tunes the transmit and receive buffer size. In almost every case, this default produces the best performance. Do not attempt to tune these parameters unless you are a network expert.</para>
135     </section>
136     <section remap="h3">
137       <title>Hardware Interrupts (<literal>enable_irq_affinity</literal>)</title>
138       <para>The hardware interrupts that are generated by network adapters may be handled by any CPU in the system. In some cases, we would like network traffic to remain local to a single CPU to help keep the processor cache warm and minimize the impact of context switches. This is helpful when an SMP system has more than one network interface and ideal when the number of interfaces equals the number of CPUs. To enable the <literal>enable_irq_affinity</literal> parameter, enter:</para>
139       <screen>options ksocklnd enable_irq_affinity=1</screen>
140       <para>In other cases, if you have an SMP platform with a single fast interface such as 10Gb Ethernet and more than two CPUs, you may see performance improve by turning this parameter off.</para>
141       <screen>options ksocklnd enable_irq_affinity=0</screen>
142       <para>By default, this parameter is off. As always, you should test the performance to compare the impact of changing this parameter.</para>
143     </section>
144         <section><title><indexterm><primary>tuning</primary><secondary>Network interface binding</secondary></indexterm>Binding Network Interface Against CPU Partitions</title>
145         <para>Luster 2.3 and beyond provide enhanced network interface control. The enhancement means that an administrator can bind an interface to one or more CPU Partitions. Bindings are specified as options to the lnet modules. For more information on specifying module options, see <xref linkend="dbdoclet.50438293_15350"/></para>
146 <para>For example, <literal>o2ib0(ib0)[0,1]</literal> will ensure that all messages for <literal>o2ib0</literal> will be handled by LND threads executing on <literal>CPT0</literal> and <literal>CPT1</literal>. An additional example might be: <literal>tcp1(eth0)[0]</literal>. Messages for <literal>tcp1</literal> are handled by threads on <literal>CPT0</literal>.</para>
147     </section>
148         <section><title><indexterm><primary>tuning</primary><secondary>Network interface credits</secondary></indexterm>Network Interface Credits</title>
149         <para>Network interface (NI) credits are shared across all CPU partitions (CPT). For example, a machine has 4 CPTs and NI credits is 512, then each partition will has 128 credits. If a large number of CPTs exist on the system,  LNet will check and validate the NI credits value for each CPT to ensure each CPT has workable number of credits. For example, a machine has 16 CPTs and NI credits is set to 256, then each partition only has 16 credits. 16 NI credits is low and could negatively impact performance. As a result, LNet will automatically make an adjustment to 8*peer_credits (peer_credits is 8 by default), so credits for each partition is still 64.</para>
150         <para>Modifying the NI Credit count can be performed by an administrator using <literal>ksoclnd</literal> or <literal>ko2iblnd</literal>. For example:</para>
151         <screen>ksocklnd credits=256</screen>
152         <para>applies 256 credits to TCP connections. Applying 256 credits to IB connections can be achieved with:</para>
153         <screen>ko2iblnd credits=256</screen>
154         <note><para>From Lustre 2.3 and beyond, it is possible that LNet may revalidate the NI Credits and the administrator's request do not persist.</para></note>
155         </section>
156         <section><title><indexterm><primary>tuning</primary><secondary>router buffers</secondary></indexterm>Router Buffers</title>
157         <para>Router buffers are shared by all CPU partitions. For a machine with a large number of CPTs, the router buffer number may need to be specified manually for best performance. A low number of router buffers risks starving the CPU Partitions of resources.</para>
158         <para>The default setting for router buffers will typically perform well. LNet automatically sets a default value to reduce the likelihood of resource starvation</para>
159         <para>An administrator may modify router buffers using the <literal>large_router_buffers</literal> parameter. For example:</para>
160         <screen>lnet large_router_buffers=8192</screen>
161         <note><para>From Lustre 2.3 and beyond, it is possible that LNet may revalidate the router buffer setting and the administrator's request do not persist.</para></note>
162         </section>
163         <section><title><indexterm><primary>tuning</primary><secondary>portal round-robin</secondary></indexterm>Portal Round-Robin</title>
164         <para>Portal round-robin defines the policy LNet applies to deliver events and messages to the upper layers. The upper layers are ptlrpc service or LNet selftest.</para>
165         <para>If portal round-robin is disabled, LNet will deliver messages to CPTs based on a hash of the source NID. Hence, all messages from a specific peer will be handled by the same CPT. This can reduce data traffic between CPUs. However, for some workloads, this behavior may result in poorly balancing loads across the CPU.</para>
166         <para>If portal round-robin is enabled, LNet will round-robin incoming events across all CPTs. This may balance load better across the CPU but can incur a cross CPU overhead.</para>
167         <para>The current policy can be changed by an administrator with <literal>echo &lt;VALUE&gt; &gt; /proc/sys/lnet/portal_rotor</literal>. There are four options for <literal>&lt;VALUE&gt;</literal>:</para>
168     <itemizedlist>
169       <listitem>
170         <para><literal>OFF</literal></para>
171                 <para>Disable portal round-robin on all incoming requests.</para>
172       </listitem>
173       <listitem>
174         <para><literal>ON</literal></para>
175                 <para>Enable portal round-robin on all incoming requests.</para>
176       </listitem>
177       <listitem>
178         <para><literal>RR_RT</literal></para>
179                 <para>Enable portal round-robin only for routed messages.</para>
180       </listitem>
181       <listitem>
182         <para><literal>HASH_RT</literal></para>
183                 <para>Routed messages will be delivered to the upper layer by hash of source NID (instead of NID of router.) This is the default value.</para>
184       </listitem>
185     </itemizedlist>
186
187     </section>
188   </section>
189   <section xml:id="dbdoclet.libcfstuning">
190       <title><indexterm><primary>tuning</primary><secondary>libcfs</secondary></indexterm>libcfs Tuning</title>
191 <para>By default, Lustre will automatically generate CPU Partitions (CPT) based on the number of CPUs in the system. The CPT number will be 1 if the online CPU number is less than five.</para>
192         <para>The CPT number can be explicitly set on the libcfs module using <literal>cpu_npartitions=NUMBER</literal>. The value of <literal>cpu_npartitions</literal> must be an integer between 1 and the number of online CPUs.</para>
193 <tip><para>Setting CPT to 1 will disable most of the SMP Node Affinity functionality.</para></tip>
194         <section>
195                 <title>CPU Partition String Patterns</title>
196         <para>CPU Partitions can be described using string pattern notation. For example:</para>
197     <itemizedlist>
198       <listitem>
199         <para><literal>cpu_pattern="0[0,2,4,6] 1[1,3,5,7]</literal></para>
200                 <para>Create two CPTs, CPT0 contains CPU[0, 2, 4, 6]. CPT1 contains CPU[1,3,5,7].</para>
201       </listitem>
202       <listitem> <para><literal>cpu_pattern="N 0[0-3] 1[4-7]</literal></para>
203                 <para>Create two CPTs, CPT0 contains all CPUs in NUMA node[0-3], CPT1 contains all CPUs in NUMA node [4-7].</para>
204       </listitem>
205     </itemizedlist>
206         <para>The current configuration of the CPU partition can be read from <literal>/proc/sys/lnet/cpu_paratitions</literal></para>
207         </section>
208   </section>
209   <section xml:id="dbdoclet.lndtuning">
210       <title><indexterm><primary>tuning</primary><secondary>LND tuning</secondary></indexterm>LND Tuning</title>
211       <para>LND tuning allows the number of threads per CPU partition to be specified. An administrator can set the threads for both <literal>ko2iblnd</literal> and <literal>ksocklnd</literal> using the <literal>nscheds</literal> parameter. This adjusts the number of threads for each partition, not the overall number of threads on the LND.</para>
212                 <note><para>Lustre 2.3 has greatly decreased the default number of threads for <literal>ko2iblnd</literal> and <literal>ksocklnd</literal> on high-core count machines. The current default values are automatically set and are chosen to work well across a number of typical scenarios.</para></note>
213   </section>
214   <section xml:id="dbdoclet.50438272_25884">
215       <title><indexterm><primary>tuning</primary><secondary>lockless I/O</secondary></indexterm>Lockless I/O Tunables</title>
216     <para>The lockless I/O tunable feature allows servers to ask clients to do lockless I/O (liblustre-style where the server does the locking) on contended files.</para>
217     <para>The lockless I/O patch introduces these tunables:</para>
218     <itemizedlist>
219       <listitem>
220         <para><emphasis role="bold">OST-side:</emphasis></para>
221         <screen>/proc/fs/lustre/ldlm/namespaces/filter-lustre-*
222 </screen>
223         <para><literal>contended_locks</literal> - If the number of lock conflicts in the scan of granted and waiting queues at contended_locks is exceeded, the resource is considered to be contended.</para>
224         <para><literal>contention_seconds</literal> - The resource keeps itself in a contended state as set in the parameter.</para>
225         <para><literal>max_nolock_bytes</literal> - Server-side locking set only for requests less than the blocks set in the <literal>max_nolock_bytes</literal> parameter. If this tunable is set to zero (0), it disables server-side locking for read/write requests.</para>
226       </listitem>
227       <listitem>
228         <para><emphasis role="bold">Client-side:</emphasis></para>
229         <screen>/proc/fs/lustre/llite/lustre-*</screen>
230         <para><literal>contention_seconds</literal> - <literal>llite</literal> inode remembers its contended state for the time specified in this parameter.</para>
231       </listitem>
232       <listitem>
233         <para><emphasis role="bold">Client-side statistics:</emphasis></para>
234         <para>The <literal>/proc/fs/lustre/llite/lustre-*/stats</literal> file has new rows for lockless I/O statistics.</para>
235         <para><literal>lockless_read_bytes</literal> and <literal>lockless_write_bytes</literal> - To count the total bytes read or written, the client makes its own decisions based on the request size. The client does not communicate with the server if the request size is smaller than the <literal>min_nolock_size</literal>, without acquiring locks by the client.</para>
236       </listitem>
237     </itemizedlist>
238   </section>
239   <section xml:id="dbdoclet.50438272_80545">
240     <title><indexterm><primary>tuning</primary><secondary>for small files</secondary></indexterm>Improving Lustre Performance When Working with Small Files</title>
241     <para>A Lustre environment where an application writes small file chunks from many clients to a single file will result in bad I/O performance. To improve Lustre&apos;s performance with small files:</para>
242     <itemizedlist>
243       <listitem>
244         <para>Have the application aggregate writes some amount before submitting them to Lustre. By default, Lustre enforces POSIX coherency semantics, so it results in lock ping-pong between client nodes if they are all writing to the same file at one time.</para>
245       </listitem>
246       <listitem>
247         <para>Have the application do 4kB <literal>O_DIRECT</literal> sized I/O to the file and disable locking on the output file. This avoids partial-page IO submissions and, by disabling locking, you avoid contention between clients.</para>
248       </listitem>
249       <listitem>
250         <para>Have the application write contiguous data.</para>
251       </listitem>
252       <listitem>
253         <para>Add more disks or use SSD disks for the OSTs. This dramatically improves the IOPS rate. Consider creating larger OSTs rather than many smaller OSTs due to less overhead (journal, connections, etc).</para>
254       </listitem>
255       <listitem>
256         <para>Use RAID-1+0 OSTs instead of RAID-5/6. There is RAID parity overhead for writing small chunks of data to disk.</para>
257       </listitem>
258     </itemizedlist>
259   </section>
260   <section xml:id="dbdoclet.50438272_45406">
261     <title><indexterm><primary>tuning</primary><secondary>write performance</secondary></indexterm>Understanding Why Write Performance is Better Than Read Performance</title>
262     <para>Typically, the performance of write operations on a Lustre cluster is better than read operations. When doing writes, all clients are sending write RPCs asynchronously. The RPCs are allocated, and written to disk in the order they arrive. In many cases, this allows the back-end storage to aggregate writes efficiently.</para>
263     <para>In the case of read operations, the reads from clients may come in a different order and need a lot of seeking to get read from the disk. This noticeably hampers the read throughput.</para>
264     <para>Currently, there is no readahead on the OSTs themselves, though the clients do readahead. If there are lots of clients doing reads it would not be possible to do any readahead in any case because of memory consumption (consider that even a single RPC (1 MB) readahead for 1000 clients would consume 1 GB of RAM).</para>
265     <para>For file systems that use socklnd (TCP, Ethernet) as interconnect, there is also additional CPU overhead because the client cannot receive data without copying it from the network buffers. In the write case, the client CAN send data without the additional data copy. This means that the client is more likely to become CPU-bound during reads than writes.</para>
266   </section>
267 </chapter>