OpenLDAP 2.3 / 2.4并发问题

时间:2014-12-11 13:48:26

标签: java linux ldap openldap

使用Open LDAP进行身份验证和其他读取请求时遇到并发问题(版本测试2.3.43和2.4.39)

当发出100个并发绑定请求时,测试代码大约需要150毫秒。将此值增加到1000个并发请求会将时间增加到9303毫秒。 因此,从x10并发请求中我们看到时间增加了x62。

这是预期的行为吗?或者我们的OpenLDAP服务器配置/ linux主机配置中缺少什么?

注意:我们已经针对基于Windows的Apache DS服务器2.0.0(相同的树结构等)运行此测试代码以进行比较和针对该服务器,性能结果在我们通常期望的情况下(即100x需要~80ms) ,1000x需要~400ms,10,000x需要~2700ms)

slapd.conf中的设置:

cachesize       100000
idlcachesize    300000
database        bdb
suffix          "dc=company,dc=com"
rootdn          "uid=admin,ou=system"
rootpw          secret
directory       /var/lib/ldap
index objectClass                       eq,pres
index ou,cn,mail,surname,givenname      eq,pres,sub
index uidNumber,gidNumber,loginShell    eq,pres
index uid,memberUid                     eq,pres,sub
index nisMapName,nisMapEntry            eq,pres,sub
sizelimit       100000
loglevel        256

测试代码:

import java.util.ArrayList;
import javax.naming.NamingException;
import javax.naming.directory.DirContext;
import org.springframework.ldap.core.LdapTemplate;
import org.springframework.ldap.core.support.LdapContextSource;
public class DirectoryServiceMain {
    public static void main(String[] args) {
        int concurrentThreadCount = 100;

        LdapContextSource ctx = new LdapContextSource();

        ctx.setUrls(new String [] { "ldap://ldap1.dev.company.com:389/", "ldap://ldap1.dev.company.com:389/" });
        ctx.setBase("dc=company,dc=com");
        ctx.setUserDn("uid=admin,ou=system");
        ctx.setPassword("secret");

        ctx.setPooled(true);
        ctx.setCacheEnvironmentProperties(false);
        LdapTemplate template = new LdapTemplate();
        template.setContextSource(ctx);

        long startTime = System.currentTimeMillis();
        ArrayList<Thread> threads = new ArrayList<>();
        for(int i = 0; i < concurrentThreadCount; i++) {
            Thread t = new Thread(
                () ->  {                   
                    DirContext context = template.getContextSource().getContext("uid=username,dc=users,uid=office,dc=suborganisations,uid=ABC,dc=organisations,dc=company,dc=com",
                                                                           "password");
                    try {
                        context.close();
                    } catch(NamingException e) {}

                });

            t.start();
            threads.add(t);
        }

        boolean alive = true;
        while(alive) {
            alive = false;
            for(Thread t : threads) {
                if(t.isAlive()) {
                    alive = true;
                    try {Thread.sleep(10);} catch(InterruptedException e) {}
                } 
            }
        }

        long endTime = System.currentTimeMillis();

        System.out.println("Total time: " + (endTime - startTime));
    }
}

ulimit -n 131072

*更新* 如果在每个t.start()之后添加了一点延迟(例如Thread.sleep(1)),那么n个并发线程的处理时间会大大减少。

1 个答案:

答案 0 :(得分:3)

更长的答案是,如果您使用BDB作为数据库,那么您可能会看到超过一定数量的并发请求的线性扩展问题。 BDB有自己的db_config文件,您可以配置该文件以提供更好的性能特征。您还可以考虑更改为专门为open ldap编写的MDB,并使用最少的配置进行更好的线性扩展。

您还应该考虑通过将jndi ldap连接池大小设置为LDAPContextSource来限制并发连接的数量:

Map<String, Object> map = new HashMap<>();
map.put("com.sun.jndi.ldap.connect.pool.initsize", 2);
map.put("com.sun.jndi.ldap.connect.pool.maxsize", 2);
map.put("com.sun.jndi.ldap.connect.pool.prefsize", 2);
ctx.setBaseEnvironmentProperties(map);