OpenLDAP Tutorial :: Make it faster!!!1!
OpenLDAP, if you think about it, SHOULD be faster than the flat-file system for large sets of users. User lookups for example, in a flat-file system must be done in a linear search. If we assume 1000 users, it is a mathmatical certainty that half the users will be found before the 500th user, half found after the 500th user. So on average, a user lookup will take 1/2n steps. In a database, which utilizes some sort of tree, we sould be looking at around log(n) steps.
Ok, great. You passed CS 2420, Data Structures. That and a dollar will get you a cup of coffee. Go Google "LDAP slow" and see what others think. To start of with, every lookup must first check the flat-files. Even with ZERO users in the OpenLDAP database, it takes SIX times longer to get results on a finger command.
We expect overhead, but where's the payoff promised by the binary search tree? Where's our flying cars? Where? It's right here!
So whats fast? Slow? Normal?
Ok, it's true. The problem might not be that pronounced for small n. And as far as adding and deleting goes, OpenLDAP pwn3s flat-file! Here's some data for you:
| Flat-File System (time in seconds) | ||||
|---|---|---|---|---|
| n users | insertion time | deletion time | ls -l 1000 files | |
| 1000 | 135 or 0.14 each | 125 or 0.13 each | 1.7 | |
| 3000 | 753 or 0.25 each | 584 or 0.19 each | 3.6 | |
| 6000 | 3134 or 0.52 each | 1980 or 0.33 each | 5.2 | |
| 9000 | 6589 or 0.73 each | 4217 or 0.47 each | 8.5 | |
| 11000 | 10052 or 0.91 each | 6002 or 0.55 each | 10.4 | |
Flat file system gets really slow under a large user set. You read that correctly, it took about 2.8 hours to add 11000 users. This is our base-line performance.
Crack-head bechmarkers: I'm well aware that this depends on the hardware, et al.
Now some OpenLDAP data. Out-of-the-box performance (No, not like a stripper):
| Default OpenLDAP System (time in seconds) | ||||
|---|---|---|---|---|
| n users | insertion time | deletion time | ls -l 1000 files | |
| 1000 | 34 or 0.03 each | 23 or 0.02 each | 77 | |
| 3000 | 117 or 0.04 each | 75 or 0.03 each | 264 | |
| 6000 | 260 or 0.04 each | 157 or 0.03 each | 431 | |
| 9000 | 467 or 0.05 each | 281 or 0.03 each | 782 | |
| 11000 | 609 or 0.06 each | 354 or 0.03 each | 500 | |
As you see above, OpenLDAP is smoking fast for adds and deletes. As long as you don't actually USE the data, you're fine. How can we make this faster?
LDAP Indices! Do ya speak it?
Database packages like BDB can be made MUCH faster by instantiating an INDEX. Indexes are subsets of tables that make operations faster. For more information about database indexes, read the Wikipedia entry. You can think of them as databases OF the database.
What we have to do is figure out what to index. If we index everything, we basically create an index database that's just as big as the normal database.
We know that a typical ls -l will look up the uid to get username and the gid to get the group name.
Edit /etc/ldap/slapd.conf and add the following:
index uidNumber eq
index gidNumber eq
Then stop slapd, run slapindex, and start slapd.
you@ldapserver: /etc/init.d/slapd stop
you@ldapserver: slapindex
you@ldapserver: /etc/init.d/slapd start
Here are some results with these two indices in effect:
| OpenLDAP System with uidNumber and gidNumber indexed(time in seconds) | ||||
|---|---|---|---|---|
| n users | insertion time | deletion time | ls -l 1000 files | |
| 1000 | 47 or 0.05 each | 27 or 0.03 each | 4.41 | |
| 3000 | 140 or 0.05 each | 94 or 0.03 each | 5.86 | |
| 6000 | 326 or 0.05 each | 202 or 0.03 each | 5.96 | |
| 9000 | 511 or 0.06 each | 320 or 0.04 each | 5.87 | |
| 11000 | 675 or 0.06 each | 622 or 0.06 each | 6.47 | |
Here's our flying cars! For a small hit in add/delete, we get amazing actual use! To ls -l 1000 files (all different owner uids and gids), and with 11,000 users, it only took 6.47 seconds. Thats about 1/3 faster than flat-file and over a hundred times faster than stock OpenLDAP!
NSCD to the rescue
NSCD, or Name Service Caching Daemon can cache user lookups, making them faster when they are requested again. The cache is stored in memory, and can be VERY fast.
Name caching? Well, back in the day, geeks traded hosts files around that tied domain names to IP addresses. Like a sneaker-net DNS. These text files coule get pretty long, so NSCD was made to cache the common domain names. And while it was at it, it could also cache passwd and group lookups. Sweet!
Install nscd.
apt-get install nscd
Here's an excerpt from the default /etc/nscd.conf file:
enable-cache passwd yes
positive-time-to-live passwd 600
negative-time-to-live passwd 20
suggested-size passwd 211
check-files passwd yes
enable-cache group yes
positive-time-to-live group 3600
negative-time-to-live group 60
suggested-size group 211
check-files group yes
enable-cache hosts yes
positive-time-to-live hosts 3600
negative-time-to-live hosts 20
suggested-size hosts 211
check-files hosts yes
The default nscd.conf file will help some as is. The hosts portion we can ignore (unless you are sneaker-netting your DNS). The time-to-live values you can fine tune to varying degrees of success. positive means queries that were positive, like a UID being found. negative results can ALSO be cached and a TTL established. What we care about is the suggested-size values.
The default nscd.conf file will help some as is. The hosts portion we can ignore (unless you are sneaker-netting your DNS). The time-to-live values you can fine tune to varying degrees of success. positive means queries that were positive, like a UID being found. negative results can ALSO be cached and a TTL established. What we care about is the suggested-size values.
These caches are really hash tables. Hash tables should be a prime number that is more than double the data size expected. You did pass Data Structures, right? If we assume 11,000 users maximum (out of my ass), then the hash table should be no smaller than 22003. Naturally, then, I set mine to 32011. P for plenty as we say in the Army.
After you set the suggested-size for passwd and group, restart nscd
you@ldapserver: /etc/init.d/nscd restart
Here are some results with these two indices and NSCD in effect:
| OpenLDAP System, indices, NSCD suggested-size = 32011(time in seconds) | ||||
|---|---|---|---|---|
| n users | insertion time | deletion time | ls -l 1000 files | |
| 1000 | 38 or 0.04 each | 27 or 0.03 each | 0.83 | |
| 3000 | 124 or 0.04 each | 90 or 0.03 each | 0.89 | |
| 6000 | 300 or 0.05 each | 229 or 0.04 each | 0.94 | |
| 9000 | 510 or 0.06 each | 307 or 0.04 each | 0.94 | |
| 11000 | 615 or 0.06 each | 453 or 0.04 each | 1.03 | |
By combining NSCD and LDAP indices, our system is now over 10 times faster than the flat-file system. MMV.


