We are migrating to UnboundID LDAP SK as we were facing some performance issues with sun java / jndi based LDAP operations.
As part o fthis migrating, I have created a method to search groups from AD and with paged control search it is taking more then a minuet to fetch 11000 groups.
However with regular JNDI search it was taking lest then 30 seconds. IT seems the paged searches are taking lot of time, any ideas how to increase the performance, I am using following code to do the search:
try {
final LDAPConnection conn = new LDAPConnection(serverAddress, serverPort,
bindDN, bindPW);
final SearchRequest searchRequest =
new SearchRequest(baseDN, scope, filter);
searchRequest.setControls(new SimplePagedResultsControl(pageSize, true));
int iterationNumber = 1;
while (true)
{
final SearchResult searchResult = conn.search(searchRequest);
System.out.println("Iteration " + (iterationNumber++) + " returned " +
searchResult.getEntryCount() + " entries");
final SimplePagedResultsControl responseControl =
(SimplePagedResultsControl) searchResult.getResponseControl(
SimplePagedResultsControl.PAGED_RESULTS_OID);
final ASN1OctetString cookie = responseControl.getCookie();
if ((cookie == null) || (cookie.getValueLength() == 0))
{
System.out.println("There are no more entries to return.");
break;
}
searchRequest.setControls(
new SimplePagedResultsControl(pageSize, cookie, true));
}
conn.close();
} catch (LDAPSearchException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (LDAPException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I wrote some simple test code to compare the difference in performing a subtree search to retrieve all entries in a server using the simple paged results control using the UnboundID LDAP SDK for Java and JNDI. I tested with a directory containing one million entries using a filter of “(objectClass=*)” to retrieve all entries from the server using pages of 100 entries. In my testing, I saw a performance difference of less than 10% when using the UnboundID LDAP SDK and JNDI, which is nothing like the >100% difference you’re reporting. Are you sure that the code you have using JNDI and the code you have using the UnboundID LDAP SDK do the same thing?
The code I used to test the UnboundID LDAP SDK was:
importcom.unboundid.ldap.sdk.LDAPConnection;importcom.unboundid.ldap.sdk.SearchRequest;importcom.unboundid.ldap.sdk.SearchResult;importcom.unboundid.ldap.sdk.SearchScope;importcom.unboundid.ldap.sdk.controls.SimplePagedResultsControl;/***ThisclassprovidesanexampleofperformingasearchthatusesJNDIto*performasearchwiththesimplepagedresultscontroltoretrieveall*entriesmatchingagivensetofsearchcriteria.*/finalclassTestUnboundIDLDAPSDKPagedSearch{/***UsestheprovidedinformationtoestablishanauthenticatedLDAPconnection*andperformasubtreesearchusingthesimplepagedresultscontrolto*iteratethroughallentriesmatchingasetofsearchcriteria.**@paramserverAddressThedirectoryserveraddress.*@paramserverPortThedirectoryserverport.*@parambindDNTheDNoftheuseraswhomtoauthenticate.*@parambindPWThepasswordfortheuseraswhomtoauthenticate.*@parambaseDNThebaseDNtouseforthesearch.*@paramfilterThefiltertouseforthesearch.*@parampageSizeThemaximumnumberofentriestoretrieveperpage.**@throwsExceptionIfaproblemisencounteredduringprocessing.*/staticvoiddoSearch(finalStringserverAddress,finalintserverPort,finalStringbindDN,finalStringbindPW,finalStringbaseDN,finalStringfilter,finalintpageSize)throwsException{try(LDAPConnectionconn=newLDAPConnection(serverAddress,serverPort,bindDN,bindPW)){finalSearchRequestsearchRequest=newSearchRequest(baseDN,SearchScope.SUB,filter);searchRequest.setControls(newSimplePagedResultsControl(pageSize,true));intnumPages=0;inttotalEntries=0;finallongstartTime=System.currentTimeMillis();while(true){finalSearchResultsearchResult=conn.search(searchRequest);numPages++;finalintiterationEntries=searchResult.getEntryCount();totalEntries+=iterationEntries;finalSimplePagedResultsControlresponseControl=SimplePagedResultsControl.get(searchResult);if(responseControl.moreResultsToReturn()){searchRequest.setControls(newSimplePagedResultsControl(pageSize,responseControl.getCookie(),true));}else{break;}}finallongelapsedTimeMillis=System.currentTimeMillis()-startTime;System.out.println("Retrieved "+totalEntries+" entries across "+numPages+" pages in "+elapsedTimeMillis+"ms with the UnboundID LDAP SDK for Java.");}}}
And the code I used to test JNDI was:
importjava.util.Hashtable;importjavax.naming.Context;importjavax.naming.NamingEnumeration;importjavax.naming.directory.SearchControls;importjavax.naming.directory.SearchResult;importjavax.naming.ldap.Control;importjavax.naming.ldap.InitialLdapContext;importjavax.naming.ldap.LdapContext;importjavax.naming.ldap.PagedResultsControl;importjavax.naming.ldap.PagedResultsResponseControl;/***ThisclassprovidesanexampleofperformingasearchthatusestheUnboundID*LDAPSDKforJavatoperformasearchwiththesimplepagedresultscontrol*toretrieveallentriesmatchingagivensetofsearchcriteria.*/finalclassTestJNDIPagedSearch{/***UsestheprovidedinformationtoestablishanauthenticatedLDAPconnection*andperformasubtreesearchusingthesimplepagedresultscontrolto*iteratethroughallentriesmatchingasetofsearchcriteria.**@paramserverAddressThedirectoryserveraddress.*@paramserverPortThedirectoryserverport.*@parambindDNTheDNoftheuseraswhomtoauthenticate.*@parambindPWThepasswordfortheuseraswhomtoauthenticate.*@parambaseDNThebaseDNtouseforthesearch.*@paramfilterThefiltertouseforthesearch.*@parampageSizeThemaximumnumberofentriestoretrieveperpage.**@throwsExceptionIfaproblemisencounteredduringprocessing.*/staticvoiddoSearch(finalStringserverAddress,finalintserverPort,finalStringbindDN,finalStringbindPW,finalStringbaseDN,finalStringfilter,finalintpageSize)throwsException{finalHashtable<String,String>jndiProperties=newHashtable<>(10);jndiProperties.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory");jndiProperties.put(Context.PROVIDER_URL,"ldap://"+serverAddress+':'+serverPort+'/');jndiProperties.put(Context.SECURITY_PRINCIPAL,bindDN);jndiProperties.put(Context.SECURITY_CREDENTIALS,bindPW);finalLdapContextctx=newInitialLdapContext(jndiProperties,null);try{finalPagedResultsControlinitialPagedResultsControl=newPagedResultsControl(pageSize,null,true);ctx.setRequestControls(newControl[]{initialPagedResultsControl});finalSearchControlssearchControls=newSearchControls(SearchControls.SUBTREE_SCOPE,0,0,null,false,false);intnumPages=0;inttotalEntries=0;finallongstartTime=System.currentTimeMillis();while(true){finalNamingEnumeration<SearchResult>results=ctx.search(baseDN,filter,searchControls);while(results.hasMore()){results.next();totalEntries++;}numPages++;finalControl[]responseControls=ctx.getResponseControls();if(responseControls!=null){byte[]cookie=null;for(finalControlresponseControl:responseControls){if(responseControlinstanceofPagedResultsResponseControl){finalPagedResultsResponseControlpagedResultsResponseControl=(PagedResultsResponseControl)responseControl;cookie=pagedResultsResponseControl.getCookie();break;}}if((cookie==null)||(cookie.length==0)){break;}else{finalPagedResultsControlnextPagedResultsControl=newPagedResultsControl(pageSize,cookie,true);ctx.setRequestControls(newControl[]{nextPagedResultsControl});}}}finallongelapsedTimeMillis=System.currentTimeMillis()-startTime;System.out.println("Retrieved "+totalEntries+" entries across "+numPages+" pages in "+elapsedTimeMillis+"ms with JNDI.");}finally{ctx.close();}}}
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi Guys,
We are migrating to UnboundID LDAP SK as we were facing some performance issues with sun java / jndi based LDAP operations.
As part o fthis migrating, I have created a method to search groups from AD and with paged control search it is taking more then a minuet to fetch 11000 groups.
However with regular JNDI search it was taking lest then 30 seconds. IT seems the paged searches are taking lot of time, any ideas how to increase the performance, I am using following code to do the search:
try {
final LDAPConnection conn = new LDAPConnection(serverAddress, serverPort,
bindDN, bindPW);
final SearchRequest searchRequest =
new SearchRequest(baseDN, scope, filter);
searchRequest.setControls(new SimplePagedResultsControl(pageSize, true));
int iterationNumber = 1;
while (true)
{
final SearchResult searchResult = conn.search(searchRequest);
System.out.println("Iteration " + (iterationNumber++) + " returned " +
searchResult.getEntryCount() + " entries");
final SimplePagedResultsControl responseControl =
(SimplePagedResultsControl) searchResult.getResponseControl(
SimplePagedResultsControl.PAGED_RESULTS_OID);
final ASN1OctetString cookie = responseControl.getCookie();
if ((cookie == null) || (cookie.getValueLength() == 0))
{
System.out.println("There are no more entries to return.");
break;
}
searchRequest.setControls(
new SimplePagedResultsControl(pageSize, cookie, true));
}
conn.close();
} catch (LDAPSearchException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (LDAPException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
I wrote some simple test code to compare the difference in performing a subtree search to retrieve all entries in a server using the simple paged results control using the UnboundID LDAP SDK for Java and JNDI. I tested with a directory containing one million entries using a filter of “(objectClass=*)” to retrieve all entries from the server using pages of 100 entries. In my testing, I saw a performance difference of less than 10% when using the UnboundID LDAP SDK and JNDI, which is nothing like the >100% difference you’re reporting. Are you sure that the code you have using JNDI and the code you have using the UnboundID LDAP SDK do the same thing?
The code I used to test the UnboundID LDAP SDK was:
And the code I used to test JNDI was: