xref: /netbsd-src/external/bsd/openldap/dist/doc/guide/admin/tuning.sdf (revision 7330f729ccf0bd976a06f95fad452fe774fc7fd1)
1# $OpenLDAP$
2# Copyright 1999-2019 The OpenLDAP Foundation, All Rights Reserved.
3# COPYING RESTRICTIONS APPLY, see COPYRIGHT.
4
5H1: Tuning
6
7This is perhaps one of the most important chapters in the guide, because if
8you have not tuned {{slapd}}(8) correctly or grasped how to design your
9directory and environment, you can expect very poor performance.
10
11Reading, understanding and experimenting using the instructions and information
12in the following sections, will enable you to fully understand how to tailor
13your directory server to your specific requirements.
14
15It should be noted that the following information has been collected over time
16from our community based FAQ. So obviously the benefit of this real world experience
17and advice should be of great value to the reader.
18
19
20H2: Performance Factors
21
22Various factors can play a part in how your directory performs on your chosen
23hardware and environment. We will attempt to discuss these here.
24
25
26H3: Memory
27
28Scale your cache to use available memory and increase system memory if you can.
29
30See {{SECT:Caching}} for BDB cache tuning hints.
31Note that LMDB uses no cache of its own and has no tuning options, so the Caching
32section can be ignored when using LMDB.
33
34
35H3: Disks
36
37Use fast filesystems, and conduct your own testing to see which filesystem
38types perform best with your workload. (On our own Linux testing, EXT2 and JFS
39tend to provide better write performance than everything else, including
40newer filesystems like EXT4, BTRFS, etc.)
41
42Use fast subsystems. Put each database and logs on separate disks
43(for BDB this is configurable via {{DB_CONFIG}}):
44
45>       # Data Directory
46>       set_data_dir /data/db
47>
48>       # Transaction Log settings
49>       set_lg_dir /logs
50
51
52H3: Network Topology
53
54http://www.openldap.org/faq/data/cache/363.html
55
56Drawing here.
57
58
59H3: Directory Layout Design
60
61Reference to other sections and good/bad drawing here.
62
63
64H3: Expected Usage
65
66Discussion.
67
68
69H2: Indexes
70
71H3: Understanding how a search works
72
73If you're searching on a filter that has been indexed, then the search reads
74the index and pulls exactly the entries that are referenced by the index.
75If the filter term has not been indexed, then the search must read every single
76 entry in the target scope and test to see if each entry matches the filter.
77Obviously indexing can save a lot of work when it's used correctly.
78
79H3: What to index
80
81You should create indices to match the actual filter terms used in
82search queries.
83
84>        index cn,sn,givenname,mail eq
85
86Each attribute index can be tuned further by selecting the set of index types to generate. For example, substring and approximate search for organizations (o) may make little sense (and isn't like done very often). And searching for {{userPassword}} likely makes no sense what so ever.
87
88General rule: don't go overboard with indexes. Unused indexes must be maintained and hence can only slow things down.
89
90See {{slapd.conf}}(8) and {{slapdindex}}(8) for more information
91
92
93H3: Presence indexing
94
95If your client application uses presence filters and if the
96target attribute exists on the majority of entries in your target scope, then
97all of those entries are going to be read anyway, because they are valid
98members of the result set. In a subtree where 100% of the
99entries are going to contain the same attributes, the presence index does
100absolutely NOTHING to benefit the search, because 100% of the entries match
101that presence filter.
102
103So the resource cost of generating the index is a
104complete waste of CPU time, disk, and memory. Don't do it unless you know
105that it will be used, and that the attribute in question occurs very
106infrequently in the target data.
107
108Almost no applications use presence filters in their search queries. Presence
109indexing is pointless when the target attribute exists on the majority of
110entries in the database. In most LDAP deployments, presence indexing should
111not be done, it's just wasted overhead.
112
113See the {{Logging}} section below on what to watch out for if you have a frequently searched
114for attribute that is unindexed.
115
116
117H2: Logging
118
119H3: What log level to use
120
121The default of {{loglevel stats}} (256) is really the best bet. There's a corollary to
122this when problems *do* arise, don't try to trace them using syslog.
123Use the debug flag instead, and capture slapd's stderr output. syslog is too
124slow for debug tracing, and it's inherently lossy - it will throw away messages when it
125can't keep up.
126
127Contrary to popular belief, {{loglevel 0}} is not ideal for production as you
128won't be able to track when problems first arise.
129
130H3: What to watch out for
131
132The most common message you'll see that you should pay attention to is:
133
134>       "<= bdb_equality_candidates: (foo) index_param failed (18)"
135
136That means that some application tried to use an equality filter ({{foo=<somevalue>}})
137and attribute {{foo}} does not have an equality index. If you see a lot of these
138messages, you should add the index. If you see one every month or so, it may
139be acceptable to ignore it.
140
141The default syslog level is stats (256) which logs the basic parameters of each
142request; it usually produces 1-3 lines of output. On Solaris and systems that
143only provide synchronous syslog, you may want to turn it off completely, but
144usually you want to leave it enabled so that you'll be able to see index
145messages whenever they arise. On Linux you can configure syslogd to run
146asynchronously, in which case the performance hit for moderate syslog traffic
147pretty much disappears.
148
149H3: Improving throughput
150
151You can improve logging performance on some systems by configuring syslog not
152to sync the file system with every write ({{man syslogd/syslog.conf}}). In Linux,
153you can prepend the log file name with a "-" in {{syslog.conf}}. For example,
154if you are using the default LOCAL4 logging you could try:
155
156>       # LDAP logs
157>       LOCAL4.*         -/var/log/ldap
158
159For syslog-ng, add or modify the following line in {{syslog-ng.conf}}:
160
161>       options { sync(n); };
162
163where n is the number of lines which will be buffered before a write.
164
165
166H2: Caching
167
168We all know what caching is, don't we?
169
170In brief, "A cache is a block of memory for temporary storage of data likely
171to be used again" - {{URL:http://en.wikipedia.org/wiki/Cache}}
172
173There are 3 types of caches, BerkeleyDB's own cache, {{slapd}}(8)
174entry cache and {{TERM:IDL}} (IDL) cache.
175
176
177H3: Berkeley DB Cache
178
179There are two ways to tune for the BDB cachesize:
180
181(a) BDB cache size necessary to load the database via slapadd in optimal time
182
183(b) BDB cache size necessary to have a high performing running slapd once the data is loaded
184
185For (a), the optimal cachesize is the size of the entire database.  If you
186already have the database loaded, this is simply a
187
188>       du -c -h *.bdb
189
190in the directory containing the OpenLDAP ({{/usr/local/var/openldap-data}}) data.
191
192For (b), the optimal cachesize is just the size of the {{id2entry.bdb}} file,
193plus about 10% for growth.
194
195The tuning of {{DB_CONFIG}} should be done for each BDB type database
196instantiated (back-bdb, back-hdb).
197
198Note that while the {{TERM:BDB}} cache is just raw chunks of memory and
199configured as a memory size, the {{slapd}}(8) entry cache holds parsed entries,
200and the size of each entry is variable.
201
202There is also an IDL cache which is used for Index Data Lookups.
203If you can fit all of your database into slapd's entry cache, and all of your
204index lookups fit in the IDL cache, that will provide the maximum throughput.
205
206If not, but you can fit the entire database into the BDB cache, then you
207should do that and shrink the slapd entry cache as appropriate.
208
209Failing that, you should balance the BDB cache against the entry cache.
210
211It is worth noting that it is not absolutely necessary to configure a BerkeleyDB
212cache equal in size to your entire database. All that you need is a cache
213that's large enough for your "working set."
214
215That means, large enough to hold all of the most frequently accessed data,
216plus a few less-frequently accessed items.
217
218For more information, please see: {{URL:http://www.oracle.com/technology/documentation/berkeley-db/db/ref/am_conf/cachesize.html}}
219
220H4: Calculating Cachesize
221
222The back-bdb database lives in two main files, {{F:dn2id.bdb}} and {{F:id2entry.bdb}}.
223These are B-tree databases. We have never documented the back-bdb internal
224layout before, because it didn't seem like something anyone should have to worry
225about, nor was it necessarily cast in stone. But here's how it works today,
226in OpenLDAP 2.4.
227
228A B-tree is a balanced tree; it stores data in its leaf nodes and bookkeeping
229data in its interior nodes (If you don't know what tree data structures look
230 like in general, Google for some references, because that's getting far too
231elementary for the purposes of this discussion).
232
233For decent performance, you need enough cache memory to contain all the nodes
234along the path from the root of the tree down to the particular data item
235you're accessing. That's enough cache for a single search. For the general case,
236you want enough cache to contain all the internal nodes in the database.
237
238>       db_stat -d
239
240will tell you how many internal pages are present in a database. You should
241check this number for both dn2id and id2entry.
242
243Also note that {{id2entry}} always uses 16KB per "page", while {{dn2id}} uses whatever
244the underlying filesystem uses, typically 4 or 8KB. To avoid thrashing,
245your cache must be at least as large as the number of internal pages in both
246the {{dn2id}} and {{id2entry}} databases, plus some extra space to accommodate
247the actual leaf data pages.
248
249For example, in my OpenLDAP 2.4 test database, I have an input LDIF file that's
250about 360MB. With the back-hdb backend this creates a {{dn2id.bdb}} that's 68MB,
251and an {{id2entry}} that's 800MB. db_stat tells me that {{dn2id}} uses 4KB pages, has
252433 internal pages, and 6378 leaf pages. The id2entry uses 16KB pages, has 52
253internal pages, and 45912 leaf pages. In order to efficiently retrieve any
254single entry in this database, the cache should be at least
255
256>       (433+1) * 4KB + (52+1) * 16KB in size: 1736KB + 848KB =~ 2.5MB.
257
258This doesn't take into account other library overhead, so this is even lower
259than the barest minimum. The default cache size, when nothing is configured,
260is only 256KB.
261
262This 2.5MB number also doesn't take indexing into account. Each indexed
263attribute results in another database file.  Earlier versions of OpenLDAP
264kept these index databases in Hash format, but from OpenLDAP 2.2 onward
265the index databases are in B-tree format so the same procedure can
266be used to calculate the necessary amount of cache for each index database.
267
268For example, if your only index is for the objectClass attribute and db_stat
269reveals that {{objectClass.bdb}} has 339 internal pages and uses 4096 byte
270pages, the additional cache needed for just this attribute index is
271
272>       (339+1) * 4KB =~ 1.3MB.
273
274With only this index enabled, I'd figure at least a 4MB cache for this backend.
275(Of course you're using a single cache shared among all of the database files,
276so the cache pages will most likely get used for something other than what you
277accounted for, but this gives you a fighting chance.)
278
279With this 4MB cache I can slapcat this entire database on my 1.3GHz PIII in
2801 minute, 40 seconds. With the cache doubled to 8MB, it still takes the same 1:40s.
281Once you've got enough cache to fit the B-tree internal pages, increasing it
282further won't have any effect until the cache really is large enough to hold
283100% of the data pages. I don't have enough free RAM to hold all the 800MB
284id2entry data, so 4MB is good enough.
285
286With back-bdb and back-hdb you can use "db_stat -m" to check how well the
287database cache is performing.
288
289For more information on {{db_stat}}: {{URL:http://www.oracle.com/technology/documentation/berkeley-db/db/utility/db_stat.html}}
290
291H3: {{slapd}}(8) Entry Cache (cachesize)
292
293The {{slapd}}(8) entry cache operates on decoded entries. The rationale - entries
294in the entry cache can be used directly, giving the fastest response. If an entry
295isn't in the entry cache but can be extracted from the BDB page cache, that will
296avoid an I/O but it will still require parsing, so this will be slower.
297
298If the entry is in neither cache then BDB will have to flush some of its current
299cached pages and bring in the needed pages, resulting in a couple of expensive
300I/Os as well as parsing.
301
302The most optimal value is of course, the entire number of entries in the database.
303However, most directory servers don't consistently serve out their entire database, so setting this to a lesser number that more closely matches the believed working set of data is
304sufficient. This is the second most important parameter for the DB.
305
306As far as balancing the entry cache vs the BDB cache - parsed entries in memory
307are generally about twice as large as they are on disk.
308
309As we have already mentioned, not having a proper database cache size will
310cause performance issues. These issues are not an indication of corruption
311occurring in the database. It is merely the fact that the cache is thrashing
312itself that causes performance/response time to slowdown.
313
314
315H3: {{TERM:IDL}} Cache (idlcachesize)
316
317Each IDL holds the search results from a given query, so the IDL cache will
318end up holding the most frequently requested search results.  For back-bdb,
319it is generally recommended to match the "cachesize" setting.  For back-hdb,
320it is generally recommended to be 3x"cachesize".
321
322{NOTE: The idlcachesize setting directly affects search performance}
323
324
325H2: {{slapd}}(8) Threads
326
327{{slapd}}(8) can process requests via a configurable number of threads, which
328in turn affects the in/out rate of connections.
329
330This value should generally be a function of the number of "real" cores on
331the system, for example on a server with 2 CPUs with one core each, set this
332to 8, or 4 threads per real core.  This is a "read" maximized value. The more
333threads that are configured per core, the slower {{slapd}}(8) responds for
334"read" operations.  On the flip side, it appears to handle write operations
335faster in a heavy write/low read scenario.
336
337The upper bound for good read performance appears to be 16 threads (which
338also happens to be the default setting).
339