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