Oracle Internet Directory Entry Cache

My intention of writing this note is to demonstrate the key benefit of avoiding database calls by virtue of having an entry cache that can cache your entire directory.

Introduction

The Oracle Internet Directory server entry cache enables LDAP entries to be cached on Oracle Internet Directory 'shared memory'. OID, from version 11.1.1.6.0 onwards, has been enhanced to also support entry cache in cluster configuration.

Entry cache now resides in a shared memory, so that multiple OID server instances running on the same host can share the same entry cache. Previous versions of OID, i.e. 11.1.1.5 and lower, only supported an entry cache per OID instance, even though multiple OID instances may have been deployed on the same host for HA or performance reasons.

Key Benefits

One of the key benefit of using an entry cache, irrespective of whether you run one or more instances on the same host and in the same cluster configurations, is that OID evaluates the LDAP query and the filter without making a trip to database and due to this both network and database load is significantly reduced.

The direct benefit due to this is that overall LDAP search operation response time is 3 to 5 times faster. This is usually applicable only when you cache almost entire directory into the entry cache. There is not much sense in having one half of the directory in cache and the remaining half being fetched through database calls when you have resources available on OID to cache the entire directory.

Refer to the following performance benchmark test conducted earlier by Oracle which highlights the same case:

http://www.oracle.com/technetwork/middleware/id-mgmt/overview/oid-11116-exalogic-perf-1534558.pdf

Test Summary

A summary of the entire demonstration is given below. Later in the note, I follow up each step with details.

1. Prepare the OID stack. OID 11.1.1.7.0, Oracle DB EE 11.2.0.3.0, ODSM 11.1.1.7.0, WLS 10.3.6, Oracle HotSpot JDK 1.7.0_51
2. Load 500 news entries in OID
3. Enable Debug on OID to trace SQL executed on DB
4. Enable entry cache in OID and check statistics
5. Execute an ldapseach to load an entry in OID entry cache
6. Check entry cache statistics
7. Identify the SQL statement which was executed on DB from OID logs
8. Identify the last executed SQL statement in database. This SQL and the one in OID logs should match including the execution time
9. Flush the DB shared pool
10. Run a ldapsearch on OID again and check entry cache statistics
11. Check the last executed SQL statement in database and note that the ldapsearch SQL statement hasn't shown up

Test Details

1. Prepare the OID stack. OID 11.1.1.7.0, Oracle DB EE 11.2.0.3.0, ODSM 11.1.1.7.0, WLS 10.3.6, Oracle HotSpot JDK 1.7.0_51

I will not write details on how to install the required stack in this post. Just follow the installation guides to get the stack running. Also, I am presuming that if you are referring to this blog post, probably you already have an environment.

2. Load 500 news entries in OID

Add 500 user entries into your OID. I used the following template file to generate a LDIF with 500 entries and then used 'ldapaddmt' to load the 500 entries into my OID. If you plan to load thousands or millions of users, I suggest take a look at 'bulkload' utility provided by OID.

(a) Template LDIF file: adduser_template.ldif

dn: cn=1000,cn=Users,dc=localdomain
givenname: 1000
objectclass: top
objectclass: person
objectclass: organizationalPerson
objectclass: inetOrgPerson
objectclass: orclUser
objectclass: orclUserV2
uid: 1000
mail: 1000
cn: 1000
description: test user
sn: 1000
userPassword: anypassword

(b) UNIX shell script to generate 500 LDIF file: generate_ldif.sh

uniquevar=1000
counter=1000

while [ $counter -lt 1501 ]
do
 cat adduser_template.ldif | sed s/$uniquevar/$counter/g >> adduser.ldif
 echo "" >> adduser.ldif
 counter=`expr $counter + 1`
done

(c) After executing this script a file called adduser.ldif file will be generated with 500 users (1000 to 1500)

ldapaddmt -h <OID hostname> -p <OID non-ssl port> -D "cn=orcladmin" -q -T 5 -f addusers.ldif

It will ask you for the password once you run the script. You can use a username other than "cn=orcladmin" provided you can update cn=Users,dc=localdomain

3. Enable 'debug' on OID to trace SQL executed on DB

Open ODSM and set the following flag under DN "cn=oid1,cn=osdldapd,cn=subconfigsubentry"

orcldebugflag to 491520
orcldebugop
to 511

The above mentioned values will help you identify the SQL statement which will be executed on the ODS schema when you execute an LDAP search.

4. Enable entry cache in OID and check statistics

To enable entry cache in OID server following parameters should be set under the DN "cn=dsaconfig,cn=configsets,cn=oracle internet directory"

orclecacheenabled - Setting it to 0 (zero) disables it. Setting it to 1 (one) enables it. Default value is 1.

orclecachemaxentries - Setting to an integer enables the cache to store those many entries. Default value is 100000 entries.

orclecachemaxsize - Setting it to an integer sets the cache size in Bytes. Find the size of the LDIF file containing your full directory. Set the value of this parameter to 3 times that value, e.g. if the size of LDIF file is 100MB (Mega Bytes), set the value as 300MB. Default value is equivalent to 200MB.

I have used the default values supplied by the OID as my directory size is much smaller than that. You might have to restart the OID for the above settings to take effect.

Set the following environment variables:

ORACLE_HOME
ORACLE_INSTANCE
INSTANCE_NAME
COMPONENT_NAME

Use the following commands to check the statistics:

$ORACLE_HOME/bin/oidctl connect=<OID_DB_SID> status -diag

Look for the following metrics:

Cache Status                       : ACTIVE
Cache Max Size                     : 209716224
Max Entries configured             : 100000
Max Entries cached                 : 0
Num Entries in Cache               : 0
Num Entries in GC                  : 0
Page size                          : 71152
Entry cache Hit count              : 0
Entry cache Mis count              : 0

Lot of the metric values may say 0 (zero) as you may not have yet executed any ldap searches. 

5. Execute an 'ldapsearch' to load an entry in OID entry cache

Execute an LDAP search command. The following search is an example which returns just a single entry:

ldapsearch -h <OID hostname> -p <OID non-ssl port> -D "<user DN>" -w <user password> -v -b "<OID base>" -s base -z 10000 cn=*

e.g.

ldapsearch -h localhost -p 3060 -D "cn=orcladmin" -w anypassword -v -b "cn=1001, cn=Users,dc=localdomain" -s base -z 10000 cn=*

6. Check entry cache statistics

Now you have executed a LDAP search so the entry cache statistics should get populated. They may look like below

Max Entries cached                 : 1
Num Entries in Cache               : 1
Entry cache Hit count              : 0
Entry cache Mis count              : 1

Note that 'Miss count' says 1 and 'Hit count' says 0 as the first time entry was not found in cache. Note that 'Num Entries in Cache' count has gone up by 1 as OID has put the result in entry cache. Execute 2 more searches and you will see the 'Hit count' getting incremented. This clearly indicates that after the first search, OID has started serving the result from the entry cache.

Max Entries cached                 : 1
Num Entries in Cache               : 1
Entry cache Hit count              : 2
Entry cache Mis count              : 1

7. Identify the SQL statement which was executed on DB from OID logs

Check the OID server logs under the following directory for the SQL executed on the DB.

$ORACLE_INSTANCE/diagnostics/logs/OID/<component_name>/

I found the following query got executed in DB for the LDAP search that I executed:

SELECT /*+ USE_NL(store) USE_NL(dn) INDEX(store EI_ATTRSTORE) INDEX(dn RP_DN) ORDERED */ store.entryid,AttrName,NVL(AttrVal,' '),attrkind,NVL(attrstype, ' '),NVL(AttrVer,' ') FROM CT_DN dn, ds_attrStore store WHERE (dn.rdn = :szCommonName AND dn.parentdn = :szBaseDomain) AND store.entryid = dn.entryid AND attrkind != 't'

8. Identify the last executed SQL statement in database. This SQL and the one in OID logs should have same execution time

Use the following SQL statement to identify the last execution time of the SQL as given above. You may need to modify the statement given below based on the SQL which you identified in the OID debug logs.

SELECT sql_text, elapsed_time, executions, FIRST_LOAD_TIME, LAST_LOAD_TIME, CAST(LAST_ACTIVE_TIME AS TIMESTAMP) LAST_ACTIVE_TIME
FROM
(SELECT sql_text, elapsed_time, executions, FIRST_LOAD_TIME, LAST_LOAD_TIME, CAST(LAST_ACTIVE_TIME AS TIMESTAMP) LAST_ACTIVE_TIME FROM sys.v_$sql s, sys.all_users u WHERE s.parsing_user_id=u.user_id and U.USERNAME='ODS' and SQL_TEXT like '%FROM CT_DN%' ORDER BY 5 asc)
WHERE
ROWNUM<=20
/

You will notice that for count in column "EXECUTIONS" for your LDAP search SQL will not exceed 1. This also clearly indicates that database has executed the query just once.

9. Flush the DB shared pool

Now flush the database Shared Pool and Buffer Cache and execute the same SQL statement as above and you will see no rows are returned and database has flushed out the parsed SQL and its result from the shared pool and buffer cache, respectively.

SQL> alter system flush shared_pool;
System altered.

SQL> alter system flush buffer_cache;
System altered.

SQL> SELECT sql_text, elapsed_time, executions, FIRST_LOAD_TIME, LAST_LOAD_TIME, CAST(LAST_ACTIVE_TIME AS TIMESTAMP) LAST_ACTIVE_TIME
FROM
(SELECT sql_text, elapsed_time, executions, FIRST_LOAD_TIME, LAST_LOAD_TIME, CAST(LAST_ACTIVE_TIME AS TIMESTAMP) LAST_ACTIVE_TIME FROM sys.v_$sql s, sys.all_users u WHERE s.parsing_user_id=u.user_id and U.USERNAME='ODS' and SQL_TEXT like '%FROM CT_DN%' ORDER BY 5 asc)
WHERE
ROWNUM<=20;


no rows selected
SQL> 

10. Run a ldapsearch on OID again and check entry cache statistics

Now run your 'ldapsearch' command given earlier another 10-20 times. Notice that count for 'Hit count' will increment by an equivalent number 

Max Entries cached                 : 1
Num Entries in Cache               : 1
Entry cache Hit count              : 30
Entry cache Mis count              : 1

11. Check the last executed SQL statement in database and note that the ldapsearch SQL statement hasn't shown up

When you try to check the number of executions for the corresponding LDAP search SQL statement on database, there will be no rows returned. 

SQL> SELECT sql_text, elapsed_time, executions, FIRST_LOAD_TIME, LAST_LOAD_TIME, CAST(LAST_ACTIVE_TIME AS TIMESTAMP) LAST_ACTIVE_TIME
FROM
(SELECT sql_text, elapsed_time, executions, FIRST_LOAD_TIME, LAST_LOAD_TIME, CAST(LAST_ACTIVE_TIME AS TIMESTAMP) LAST_ACTIVE_TIME FROM sys.v_$sql s, sys.all_users u WHERE s.parsing_user_id=u.user_id and U.USERNAME='ODS' and SQL_TEXT like '%FROM CT_DN%' ORDER BY 5 asc)
WHERE
ROWNUM<=20;

SQL_TEXT                                                                                             ELAPSED_TIME EXECUTIONS FIRST_LOAD_TIME      LAST_LOAD_TIME       LAST_ACTIVE_TIME

---------------------------------------------------------------------------------------------------- ------------ ---------- -------------------- -------------------- --------------------

SELECT /*+ USE_NL(store) USE_NL(dn) INDEX(store EI_ATTRSTORE) INDEX(dn RP_DN) ORDERED */ store.entry        72736         21 2014-05-06/13:51:04  2014-05-06/14:04:47  06-MAY-14 02.05.08.0
id,AttrName,NVL(AttrVal,' '),attrkind,NVL(attrstype, ' '),NVL(AttrVer,' ') FROM CT_DN dn, ds_attrSto                                                                   00000 PM
re store WHERE (dn.rdn = :szCommonName AND dn.parentdn = :szBaseDomain) AND store.entryid = dn.entry
id AND attrkind IN ('u', 't')

The query in the output above is the one which gets executed when you check the OID entry cache statistics.

Conclusion 

So you clearly see that once OID caches the result in the entry cache, the SQL is not executed on database until you restart either the database or OID which effectively flushes out the entry cache. This conclusively proves that once the result of a LDAP search is stored in OID entry cache, it is served from there for any number of same subsequent LDAP search till the time OID or DB is restarted.


Comments:

Post a Comment:
  • HTML Syntax: NOT allowed
About

Prateek is a technology consultant in Oracle and thorugh this blog he shares his experiences on different features of products that are used by Oracle customers worldwide

Search

Categories
Archives
« May 2015
SunMonTueWedThuFriSat
     
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
      
Today