lemonldap-ng/doc/pages/documentation/current/performances.html
2019-05-12 16:33:56 +02:00

467 lines
30 KiB
HTML

<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8" />
<title>documentation:2.0:performances</title>
<meta name="generator" content="DokuWiki"/>
<meta name="robots" content="index,follow"/>
<meta name="keywords" content="documentation,2.0,performances"/>
<link rel="search" type="application/opensearchdescription+xml" href="lib/exe/opensearch.html" title="LemonLDAP::NG"/>
<link rel="start" href="performances.html"/>
<link rel="contents" href="performances.html" title="Sitemap"/>
<link rel="stylesheet" type="text/css" href="lib/exe/css.php.t.bootstrap3.css"/>
<!-- //if:usedebianlibs
<link rel="stylesheet" type="text/css" href="/javascript/bootstrap/css/bootstrap.min.css" />
//elsif:useexternallibs
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css"></script>
//elsif:cssminified
<link rel="stylesheet" type="text/css" href="/static/bwr/bootstrap/dist/css/bootstrap.min.css" />
//else -->
<link rel="stylesheet" type="text/css" href="/static/bwr/bootstrap/dist/css/bootstrap.css" />
<!-- //endif -->
<script type="text/javascript">/*<![CDATA[*/var NS='documentation:2.0';var JSINFO = {"id":"documentation:2.0:performances","namespace":"documentation:2.0"};
/*!]]>*/</script>
<script type="text/javascript" charset="utf-8" src="lib/exe/js.php.t.bootstrap3.js"></script>
<!-- //if:usedebianlibs
<script type="text/javascript" src="/javascript/jquery/jquery.min.js"></script>
//elsif:useexternallibs
<script type="text/javascript" src="http://code.jquery.com/jquery-2.2.0.min.js"></script>
//elsif:jsminified
<script type="text/javascript" src="/static/bwr/jquery/dist/jquery.min.js"></script>
//else -->
<script type="text/javascript" src="/static/bwr/jquery/dist/jquery.js"></script>
<!-- //endif -->
<!-- //if:usedebianlibs
<script type="text/javascript" src="/javascript/jquery-ui/jquery-ui.min.js"></script>
//elsif:useexternallibs
<script type="text/javascript" src="http://code.jquery.com/ui/1.10.4/jquery-ui.min.js"></script>
//elsif:jsminified
<script type="text/javascript" src="/static/bwr/jquery-ui/jquery-ui.min.js"></script>
//else -->
<script type="text/javascript" src="/static/bwr/jquery-ui/jquery-ui.js"></script>
<!-- //endif -->
</head>
<body>
<div class="dokuwiki export container">
<!-- TOC START -->
<div id="dw__toc">
<h3 class="toggle">Table of Contents</h3>
<div>
<ul class="toc">
<li class="level1"><div class="li"><a href="#global_performance">Global performance</a></div>
<ul class="toc">
<li class="level2"><div class="li"><a href="#cron_optimization">Cron optimization</a></div></li>
</ul>
</li>
<li class="level1"><div class="li"><a href="#handler_performance">Handler performance</a></div>
<ul class="toc">
<li class="level2"><div class="li"><a href="#macros_and_groups">Macros and groups</a></div></li>
<li class="level2"><div class="li"><a href="#local_macros">Local macros</a></div></li>
</ul>
</li>
<li class="level1"><div class="li"><a href="#portal_performances">Portal performances</a></div>
<ul class="toc">
<li class="level2"><div class="li"><a href="#general_performances">General performances</a></div></li>
<li class="level2"><div class="li"><a href="#apachesession_performances">Apache::Session performances</a></div>
<ul class="toc">
<li class="level3"><div class="li"><a href="#replace_mysql_by_apachesessionflex">Replace MySQL by Apache::Session::Flex</a></div></li>
<li class="level3"><div class="li"><a href="#use_apachesessionbrowseable">Use Apache::Session::Browseable</a></div></li>
<li class="level3"><div class="li"><a href="#performance_test">Performance test</a></div></li>
</ul>
</li>
<li class="level2"><div class="li"><a href="#ldap_performances">LDAP performances</a></div></li>
</ul>
</li>
<li class="level1"><div class="li"><a href="#manager_performances">Manager performances</a></div>
<ul class="toc">
<li class="level2"><div class="li"><a href="#disable_unused_modules">Disable unused modules</a></div></li>
<li class="level2"><div class="li"><a href="#use_static_html_files">Use static HTML files</a></div></li>
</ul></li>
</ul>
</div>
</div>
<!-- TOC END -->
<h1 class="sectionedit1" id="performances">Performances</h1>
<div class="level1">
<p>
LemonLDAP::NG is designed to be very performant. Indeed, it uses Apache2 threads capabilities. So to increase performances, prefer using <a href="http://httpd.apache.org/docs/2.2/misc/perf-tuning.html#compiletime" class="urlextern" title="http://httpd.apache.org/docs/2.2/misc/perf-tuning.html#compiletime" rel="nofollow">mpm-worker</a>.
</p>
</div>
<!-- EDIT1 SECTION "Performances" [1-249] -->
<h2 class="sectionedit2" id="global_performance">Global performance</h2>
<div class="level2">
<p>
By default, Linux does not use <abbr title="Domain Name System">DNS</abbr> cache and LemonLDAP::NG portal request <abbr title="Domain Name System">DNS</abbr> for each connexions on LDAP or DB. Under heavy loads, that can generated hundred of <abbr title="Domain Name System">DNS</abbr> queries and many errors on LDAP connexions (timed out) from IO::Socket.
</p>
<p>
To bypass this, you can:
</p>
<ul>
<li class="level1"><div class="li"> Use <abbr title="Internet Protocol">IP</abbr> in configuration to avoid <abbr title="Domain Name System">DNS</abbr> resolution</div>
</li>
<li class="level1"><div class="li"> Install a <abbr title="Domain Name System">DNS</abbr> cache like nscd, netmask or bind</div>
</li>
</ul>
</div>
<!-- EDIT2 SECTION "Global performance" [250-650] -->
<h3 class="sectionedit3" id="cron_optimization">Cron optimization</h3>
<div class="level3">
<p>
LLNG installs its cron files without knowing how many servers are installed. You should optimize this to launch:
</p>
<ul>
<li class="level1"><div class="li"> purgeCentralCache: only 1 time every 10 minutes for the whole system</div>
</li>
<li class="level1"><div class="li"> purgeLocalCache: ~ 1 time per hour on each server</div>
</li>
</ul>
</div>
<!-- EDIT3 SECTION "Cron optimization" [651-920] -->
<h2 class="sectionedit4" id="handler_performance">Handler performance</h2>
<div class="level2">
<p>
For Nginx, you can use another auth server instead of llng-fastcgi-server. See: <a href="psgi.html" class="wikilink1" title="documentation:2.0:psgi">Advanced PSGI usage</a>.
</p>
<p>
To increase handler performance, you can disable “Sessions activity timeout” to prevent it from writing to the session database.
</p>
<p>
Handlers check rights and calculate headers for each HTTP hit. So to improve performances, avoid too complex rules by using macros, groups or local macros.
</p>
</div>
<!-- EDIT4 SECTION "Handler performance" [921-1350] -->
<h3 class="sectionedit5" id="macros_and_groups">Macros and groups</h3>
<div class="level3">
<p>
Macros and groups are calculated during authentication process by the portal:
</p>
<ul>
<li class="level1"><div class="li"> macros are used to extend (or rewrite) <a href="exportedvars.html" class="wikilink1" title="documentation:2.0:exportedvars">exported variables</a>. A macro is stored as attributes: it can contain boolean results or any string</div>
</li>
<li class="level1"><div class="li"> macros can also be used to import environment variables <em>(these variables are in CGI format)</em>. Example: <code>$ENV{HTTP_COOKIE}</code></div>
</li>
<li class="level1"><div class="li"> groups are stored as space-separated strings in the special attribute “groups”: it contains the names of groups whose rules were returned true for the current user</div>
</li>
<li class="level1"><div class="li"> You can also get groups in <code>$hGroups</code> which is a Hash Reference of this form:</div>
</li>
</ul>
<pre class="code perl"><span class="re0">$hGroups</span> <span class="sy0">=</span> <span class="br0">&#123;</span>
<span class="st_h">'group3'</span> <span class="sy0">=&gt;</span> <span class="br0">&#123;</span>
<span class="st_h">'description'</span> <span class="sy0">=&gt;</span> <span class="br0">&#91;</span>
<span class="st_h">'Service 3'</span><span class="sy0">,</span>
<span class="st_h">'Service 3 TEST'</span>
<span class="br0">&#93;</span><span class="sy0">,</span>
<span class="st_h">'cn'</span> <span class="sy0">=&gt;</span> <span class="br0">&#91;</span>
<span class="st_h">'group3'</span>
<span class="br0">&#93;</span><span class="sy0">,</span>
<span class="st_h">'name'</span> <span class="sy0">=&gt;</span> <span class="st_h">'group3'</span>
<span class="br0">&#125;</span><span class="sy0">,</span>
<span class="st_h">'admin'</span> <span class="sy0">=&gt;</span> <span class="br0">&#123;</span>
<span class="st_h">'name'</span> <span class="sy0">=&gt;</span> <span class="st_h">'admin'</span>
<span class="br0">&#125;</span>
<span class="br0">&#125;</span></pre>
<p>
Example for macros:
</p>
<pre class="code perl"><span class="co1"># boolean macro</span>
isAdmin <span class="sy0">-&gt;</span> <span class="re0">$uid</span> <span class="kw1">eq</span> <span class="st_h">'foo'</span> <span class="kw1">or</span> <span class="re0">$uid</span> <span class="kw1">eq</span> <span class="st_h">'bar'</span>
<span class="co1"># other macro </span>
displayName <span class="sy0">-&gt;</span> <span class="re0">$givenName</span><span class="sy0">.</span><span class="st0">&quot; &quot;</span><span class="sy0">.</span><span class="re0">$surName</span>
&nbsp;
<span class="co1"># Use a boolean macro in a rule</span>
<span class="sy0">^/</span>admin <span class="sy0">-&gt;</span> <span class="re0">$isAdmin</span>
<span class="co1"># Use a string macro in a HTTP header</span>
Display<span class="sy0">-</span>Name <span class="sy0">-&gt;</span> <span class="re0">$displayName</span></pre>
<p>
Example for groups:
</p>
<pre class="code perl"><span class="co1"># group</span>
admin <span class="sy0">-&gt;</span> <span class="re0">$uid</span> <span class="kw1">eq</span> <span class="st_h">'foo'</span> <span class="kw1">or</span> <span class="re0">$uid</span> <span class="kw1">eq</span> <span class="st_h">'bar'</span>
&nbsp;
<span class="co1"># Use a group in a rule</span>
<span class="sy0">^/</span>admin <span class="sy0">-&gt;</span> <span class="re0">$groups</span> <span class="sy0">=~</span> <span class="co2">/\badmin\b/</span>
&nbsp;
<span class="co1"># Or with hGroups</span>
<span class="sy0">^/</span>admin <span class="sy0">-&gt;</span> <a href="http://perldoc.perl.org/functions/defined.html"><span class="kw3">defined</span></a> <span class="re0">$hGroups</span><span class="sy0">-&gt;</span><span class="br0">&#123;</span><span class="st_h">'admin'</span><span class="br0">&#125;</span></pre>
<div class="noteclassic">Groups are computed after macros, so a group rule may involve a macro value.
</div><div class="noteimportant">Macros and groups are computed in alphanumeric order, that is, in the order they are displayed in the manager. For example, macro “macro1” will be computed before macro “macro2”: so, expression of macro2 may involve value of macro1. As same for groups: a group rule may involve another, previously computed group.
</div>
</div>
<!-- EDIT5 SECTION "Macros and groups" [1351-3445] -->
<h3 class="sectionedit6" id="local_macros">Local macros</h3>
<div class="level3">
<p>
Macros and groups are stored in session database. Local macros is a special feature of handler that permit one to have macros useable localy only. Those macros are calculated only at the first usage and stored in the local session cache (only for this server) and only if the user access to the related applications. This avoid to have to many datas stored.
</p>
<pre class="code perl"><span class="co1"># rule</span>
admin <span class="sy0">-&gt;</span> <span class="re0">$admin</span> <span class="sy0">||=</span> <span class="br0">&#40;</span><span class="re0">$uid</span> <span class="kw1">eq</span> <span class="st_h">'foo'</span> <span class="kw1">or</span> <span class="re0">$uid</span> <span class="kw1">eq</span> <span class="st_h">'bar'</span><span class="br0">&#41;</span>
<span class="co1"># header</span>
Display<span class="sy0">-</span>Name <span class="sy0">-&gt;</span> <span class="re0">$displayName</span> <span class="sy0">||=</span> <span class="re0">$givenName</span><span class="sy0">.</span><span class="st0">&quot; &quot;</span><span class="sy0">.</span><span class="re0">$surName</span></pre>
<div class="notetip">Note that this feature is interesting only for the Lemonldap::NG systems protecting a high number of applications
</div>
</div>
<!-- EDIT6 SECTION "Local macros" [3446-4107] -->
<h2 class="sectionedit7" id="portal_performances">Portal performances</h2>
<div class="level2">
</div>
<!-- EDIT7 SECTION "Portal performances" [4108-4140] -->
<h3 class="sectionedit8" id="general_performances">General performances</h3>
<div class="level3">
<p>
The portal is the biggest component of Lemonldap::NG. Since version 2.0, portal runs under FastCGI and has been rewritten using plugins, so performance is increased in comparison to earlier versions. You just have to disable unused plugins:
</p>
<ul>
<li class="level1"><div class="li"> disable unused issuer modules</div>
</li>
<li class="level1"><div class="li"> disable notifications if not used</div>
</li>
<li class="level1"><div class="li"> ...</div>
</li>
</ul>
<p>
By default it uses local storage to store its tokens. If you have more than 1 portal and if your load-balancer doesn&#039;t keep state, you have to disable this to use the global session storage <em>(General parameters » portal Parameters » Advanced Parameters » Forms)</em>. Note that this will decrease performances.
</p>
<div class="notetip">In production environment for network performance, prefer using minified versions of javascript and css libs: use <code>make install <strong>PROD=yes</strong></code>. This is done by default in RPM/DEB packages.
</div>
</div>
<!-- EDIT8 SECTION "General performances" [4141-5018] -->
<h3 class="sectionedit9" id="apachesession_performances">Apache::Session performances</h3>
<div class="level3">
<p>
Lemonldap::NG handlers use a local cache to store sessions (for 10 minutes). So Apache::Session module is not a problem for handlers. It can be a brake for the portal:
</p>
<ol>
<li class="level1"><div class="li"> When you use the multiple sessions restriction parameters, sessions are parsed for each authentication unless you use an <a href="https://metacpan.org/module/Apache::Session::Browseable" class="urlextern" title="https://metacpan.org/module/Apache::Session::Browseable" rel="nofollow">Apache::Session::Browseable</a> module.</div>
</li>
<li class="level1"><div class="li"> Since MySQL does not have always transaction feature, Apache::Session::MySQL has been designed to use MySQL locks. Since MySQL performances are very bad using this, if you want to store sessions in a MySQL database, prefer one of the following</div>
</li>
</ol>
<div class="notetip">Since 1.9.6, LLNG portal and handler check if session is valid at each access, so purgeCentralCache cron no longer needs to be launched every 10 minutes: one or two times per day is enough.
</div>
</div>
<h4 id="replace_mysql_by_apachesessionflex">Replace MySQL by Apache::Session::Flex</h4>
<div class="level4">
<p>
In “Apache::Session module” field, set “<a href="https://metacpan.org/module/Apache::Session::Flex" class="urlextern" title="https://metacpan.org/module/Apache::Session::Flex" rel="nofollow">Apache::Session::Flex</a>” and use the following parameters:
</p>
<pre class="code">Store -&gt; MySQL
Lock -&gt; Null
Generate -&gt; MD5
Serialize -&gt; Storable
DataSource -&gt; dbi:mysql:sessions;host=...
UserName -&gt; ...
Password -&gt; ...</pre>
<div class="notetip">Since version 1.90 of Apache::Session, you can use Apache::Session::MySQL::NoLock instead
</div>
</div>
<h4 id="use_apachesessionbrowseable">Use Apache::Session::Browseable</h4>
<div class="level4">
<p>
<a href="https://metacpan.org/module/Apache::Session::Browseable" class="urlextern" title="https://metacpan.org/module/Apache::Session::Browseable" rel="nofollow">Apache::Session::Browseable</a> is a wrapper for other Apache::Session modules that add the capability to manage indexes. Prefer versions ≥ 1.2.5 for better performances in DB cleaning. To use it (with PostgreSQL for example), choose “Apache::Session::Browseable::Postgres” as “Apache::Session module” and use the following parameters:
</p>
<pre class="code">DataSource -&gt; dbi:Pg:database=sessions;host=...
UserName -&gt; user
Password -&gt; password
Index -&gt; ipAddr uid</pre>
<p>
Note that Apache::Session::Browseable::MySQL doesn&#039;t use MySQL locks.
</p>
<p>
Look at <a href="browseablesessionbackend.html" class="wikilink1" title="documentation:2.0:browseablesessionbackend">Browseable session backend</a> to known which index to choose.
</p>
<div class="noteimportant">Some Apache::Session module are not fully usable by Lemonldap::NG such as Apache::Session::Memcached since these modules do not offer capability to browse sessions. They does not allow one to use sessions explorer neither manage one-off sessions.
</div>
</div>
<h4 id="performance_test">Performance test</h4>
<div class="level4">
<div class="notetip">A <a href="https://metacpan.org/module/Apache::Session::Browseable::Redis" class="urlextern" title="https://metacpan.org/module/Apache::Session::Browseable::Redis" rel="nofollow">Apache::Session::Browseable::Redis</a> has been created, it is the fastest (except for session explorer, defeated by Apache::Session::Browseable::<a href="https://metacpan.org/module/Apache::Session::Browseable" class="urlextern" title="https://metacpan.org/module/Apache::Session::Browseable" rel="nofollow">DBI</a>/<a href="https://metacpan.org/module/Apache::Session::Browseable::LDAP" class="urlextern" title="https://metacpan.org/module/Apache::Session::Browseable::LDAP" rel="nofollow">LDAP</a>])
</div>
<p>
This test isn&#039;t an “only-backend” test but embedded some LLNG methods, so real differences between engines are mitigate here.
</p>
<div class="table sectionedit10"><table class="inline table table-bordered table-striped">
<thead>
<tr class="row0 roweven">
<th class="col0 centeralign" colspan="2"> Backend </th><th class="col2 centeralign" colspan="3"> Portal and handlers </th><th class="col5 centeralign" colspan="3"> Session explorer and one-off sessions </th>
</tr>
<tr class="row1 rowodd">
<th class="col0 centeralign"> Name </th><th class="col1 centeralign"> Configuration </th><th class="col2 centeralign"> Insert 1000 </th><th class="col3 centeralign"> Search 1 </th><th class="col4 centeralign"> Purge 500 </th><th class="col5 centeralign"> Parse all </th><th class="col6 centeralign"> Search by substring </th><th class="col7 centeralign"> Search by UID </th>
</tr>
</thead>
<tr class="row2 roweven">
<td class="col0 leftalign"> Apache::Session::<strong>Browseable::LDAP</strong> </td><td class="col1 leftalign"> mdb </td><td class="col2 centeralign"> 159.66 </td><td class="col3 centeralign"> 0.0120 </td><td class="col4 centeralign"> 49.22 </td><td class="col5 centeralign"> 0.1110 </td><td class="col6 centeralign"> 0.0076 </td><td class="col7 centeralign"> 0.0050 </td>
</tr>
<tr class="row3 rowodd">
<td class="col0 leftalign"> Apache::Session::<strong>MySQL</strong> </td><td class="col1"> No lock </td><td class="col2 centeralign"> 87.20 </td><td class="col3 centeralign"> <strong>0.0039</strong> </td><td class="col4 centeralign"> 23.14 </td><td class="col5 centeralign"> 0.0281 </td><td class="col6 centeralign"> 0.0252 </td><td class="col7 centeralign"> 0.0235 </td>
</tr>
<tr class="row4 roweven">
<td class="col0"> Apache::Session::<strong>Browseable::MySQL</strong> </td><td class="col1 leftalign"> </td><td class="col2 centeralign"> 91.79 </td><td class="col3 centeralign"> <strong>0.0039</strong> </td><td class="col4 centeralign"> <strong>0.139</strong> <em>(1)</em> </td><td class="col5 centeralign"> 0.0272 </td><td class="col6 centeralign"> <strong>0.0036</strong> </td><td class="col7 centeralign"> <strong>0.0026</strong> </td>
</tr>
<tr class="row5 rowodd">
<td class="col0"> Apache::Session::<strong>Browseable::MySQLJSON</strong> </td><td class="col1 leftalign"> </td><td class="col2 centeralign"> 86.06 </td><td class="col3 centeralign"> 0.0145 </td><td class="col4 centeralign"> <strong> 0.151</strong> <em>(2)</em> </td><td class="col5 centeralign"> <strong>0.0104</strong> </td><td class="col6 centeralign"> 0.0137 </td><td class="col7 centeralign"> 0.0038 </td>
</tr>
<tr class="row6 roweven">
<td class="col0 leftalign"> Apache::Session::<strong>Postgres</strong> </td><td class="col1 leftalign"> </td><td class="col2 centeralign"> 18.31 </td><td class="col3 centeralign"> 0.0095 </td><td class="col4 centeralign"> 13.40 </td><td class="col5 centeralign"> 0.0323 </td><td class="col6 centeralign"> 0.0277 </td><td class="col7 centeralign"> 0.0264 </td>
</tr>
<tr class="row7 rowodd">
<td class="col0"> Apache::Session::<strong>Postgres</strong> </td><td class="col1"> Unlogged table </td><td class="col2 centeralign"> 9.16 </td><td class="col3 centeralign"> 0.0095 </td><td class="col4 centeralign"> 7.91 </td><td class="col5 centeralign"> 0.0318 </td><td class="col6 centeralign"> 0.0270 </td><td class="col7 centeralign"> 0.0254 </td>
</tr>
<tr class="row8 roweven">
<td class="col0 leftalign"> Apache::Session::<strong>Browseable::Postgres</strong> </td><td class="col1"> Unlogged table with indexes </td><td class="col2 centeralign"> 9.24 </td><td class="col3 centeralign"> 0.0094 </td><td class="col4 centeralign"> <strong>0.103</strong> <em>(1)</em> </td><td class="col5 centeralign"> 0.0301 </td><td class="col6 centeralign"> <strong>0.0036</strong> </td><td class="col7 centeralign"> <strong>0.0028</strong> </td>
</tr>
<tr class="row9 rowodd">
<td class="col0 leftalign"> Apache::Session::<strong>Browseable::PgJSON</strong> </td><td class="col1"> Unlogged table, json field </td><td class="col2 centeralign"> 9.25 </td><td class="col3 centeralign"> 0.0091 </td><td class="col4 centeralign"> <strong>0.108</strong> <em>(1)</em> </td><td class="col5 centeralign"> 0.0247 </td><td class="col6 centeralign"> <strong>0.0035</strong> </td><td class="col7 centeralign"> <strong>0.0029</strong> </td>
</tr>
<tr class="row10 roweven">
<td class="col0 leftalign"> Apache::Session::<strong>Browseable::PgJSON</strong> </td><td class="col1"> Unlogged table, jsonb field </td><td class="col2 centeralign"> 9.25 </td><td class="col3 centeralign"> 0.0091 </td><td class="col4 centeralign"> <strong>0.105</strong> <em>(1)</em> </td><td class="col5 centeralign"> <strong>0.0126</strong> </td><td class="col6 centeralign"> <strong>0.0034</strong> </td><td class="col7 centeralign"> <strong>0.0029</strong> </td>
</tr>
<tr class="row11 rowodd">
<td class="col0 leftalign"> Apache::Session::<strong>Browseable::PgHstore</strong> </td><td class="col1"> Unlogged table, hstore field </td><td class="col2 centeralign"> 9.62 </td><td class="col3 centeralign"> 0.0111 </td><td class="col4 centeralign"> <strong>0.105</strong> <em>(1)</em> </td><td class="col5 centeralign"> <strong>0.0125</strong> </td><td class="col6 centeralign"> <strong>0.0033</strong> </td><td class="col7 centeralign"> <strong>0.0029</strong> </td>
</tr>
<tr class="row12 roweven">
<td class="col0 leftalign"> Apache::Session::<strong>Redis</strong> </td><td class="col1 leftalign"> </td><td class="col2 centeralign"> <strong>2.13</strong> </td><td class="col3 centeralign"> <strong>0.0033</strong> </td><td class="col4 centeralign"> 1.158 </td><td class="col5 centeralign"> 0.0623 </td><td class="col6 centeralign"> 0.0570 </td><td class="col7 centeralign"> 0.0550 </td>
</tr>
<tr class="row13 rowodd">
<td class="col0 leftalign"> Apache::Session::<strong>Browseable::Redis</strong> </td><td class="col1 leftalign"> </td><td class="col2 centeralign"> <strong>2.36</strong> </td><td class="col3 centeralign"> <strong>0.0033</strong> </td><td class="col4 centeralign"> 1.154 </td><td class="col5 centeralign"> 0.0643 </td><td class="col6 centeralign"> 0.1048 </td><td class="col7 centeralign"> <strong>0.0024</strong> </td>
</tr>
<tr class="row14 roweven">
<td class="col0 centeralign" colspan="8"> <em>The source of this test is available in sources: e2e-tests/sbperf.pl</em> </td>
</tr>
</table></div>
<!-- EDIT10 TABLE [7910-9813] --><ul>
<li class="level1"><div class="li"> <em><strong>(1) :</strong> “purge” test is done with Apache::Session::Browseable-1.2.5 and LLG-2.0. Earlier results are not so good.</em></div>
</li>
<li class="level1"><div class="li"> <em><strong>(2) :</strong> “purge” test is done with Apache::Session::Browseable-1.2.6 and LLG-2.0.</em></div>
</li>
</ul>
<p>
Analysis:
</p>
<ul>
<li class="level1"><div class="li"> LDAP servers are “write-once-read-many”, so write performances are very bad. Don&#039;t use this on heavy load if “Session activity timeout” is enabled <em>(if set, handler “write” sessions)</em></div>
</li>
<li class="level1"><div class="li"> MySQL/MariaDB is better to read than to write. Prefer PostgreSQL if you use “Session activity timeout”</div>
</li>
<li class="level1"><div class="li"> Logged tables decrease a lot insert performances with PostgreSQL, so use unlogged tables for sessions except for persistent sessions</div>
</li>
<li class="level1"><div class="li"> Redis is the best for main usage</div>
</li>
<li class="level1"><div class="li"> Browseable::Postgres/PgHstore/PgJSON are the best SQL solutions on average</div>
</li>
</ul>
</div>
<!-- EDIT9 SECTION "Apache::Session performances" [5019-10591] -->
<h3 class="sectionedit11" id="ldap_performances">LDAP performances</h3>
<div class="level3">
<p>
LDAP server can slow you down when you use LDAP groups retrieval. You can avoid this by setting “memberOf” fields in your LDAP scheme:
</p>
<pre class="code ldif"><span class="re0">dn</span>:<span class="re1"> uid=foo,dmdName=people,dc=example,dc=com</span>
...
<span class="re0">memberOf</span>:<span class="re1"> cn=admin,dmdName=groups,dc=example,dc=com</span>
<span class="re0">memberOf</span>:<span class="re1"> cn=su,dmdName=groups,dc=example,dc=com</span></pre>
<p>
So instead of using LDAP groups retrieval, you just have to store “memberOf” field in your exported variables. With OpenLDAP, you can use the <a href="http://www.openldap.org/doc/admin24/overlays.html#Reverse%20Group%20Membership%20Maintenance" class="urlextern" title="http://www.openldap.org/doc/admin24/overlays.html#Reverse%20Group%20Membership%20Maintenance" rel="nofollow">memberof overlay</a> to do it automatically.
</p>
<div class="noteimportant">Don&#039;t forget to create an index on the field used to find users (uid by default)
</div><div class="notetip">To avoid having group dn stored in sessions datas, you can use a macro to rewrite memberOf:<ul>
<li class="level1"><div class="li"> Exported variables</div>
</li>
</ul>
<pre class="code">ldapgroups -&gt; memberOf</pre>
<p>
For now, ldapgroups contains “cn=admin,dmdName=groups,dc=example,dc=com cn=su,dmdName=groups,dc=example,dc=com”
</p>
<ul>
<li class="level1"><div class="li"> A little macro:</div>
</li>
</ul>
<pre class="code perl">ldapgroups <span class="sy0">-&gt;</span> <a href="http://perldoc.perl.org/functions/join.html"><span class="kw3">join</span></a><span class="br0">&#40;</span><span class="st0">&quot; &quot;</span><span class="sy0">,</span><span class="br0">&#40;</span><span class="re0">$ldapgroups</span> <span class="sy0">=~</span> <span class="co2">/cn=(.*?),/g</span><span class="br0">&#41;</span><span class="br0">&#41;</span></pre>
<p>
Now ldapgroups contains “admin su”
</p>
</div>
</div>
<!-- EDIT11 SECTION "LDAP performances" [10592-11726] -->
<h2 class="sectionedit12" id="manager_performances">Manager performances</h2>
<div class="level2">
</div>
<!-- EDIT12 SECTION "Manager performances" [11727-11760] -->
<h3 class="sectionedit13" id="disable_unused_modules">Disable unused modules</h3>
<div class="level3">
<p>
In lemonldap-ng.ini, set only modules that you will use. By default, configuration, sessions explorer, notifications explorer and second factor are enabled. Example:
</p>
<pre class="code ini"><span class="re0"><span class="br0">&#91;</span>manager<span class="br0">&#93;</span></span>
<span class="re1">enabledModules</span> <span class="sy0">=</span><span class="re2"> conf, sessions</span></pre>
</div>
<!-- EDIT13 SECTION "Disable unused modules" [11761-12022] -->
<h3 class="sectionedit14" id="use_static_html_files">Use static HTML files</h3>
<div class="level3">
<p>
Once Manager is installed, browse enabled modules (configuration, sessions, notifications) and save the web pages respectively under <code>manager.html</code>, <code>sessions.html</code> and <code>notifications.html</code> in the <code>DocumentRoot</code> directory. Then replace this in Manager file of Apache configuration:
</p>
<pre class="code apache"><span class="kw1">RewriteRule</span> <span class="st0">&quot;^/$&quot;</span> <span class="st0">&quot;/psgi/manager-server.fcgi&quot;</span> [PT]
<span class="co1"># DirectoryIndex manager.html</span>
<span class="co1"># RewriteCond &quot;%{REQUEST_FILENAME}&quot; &quot;!\.html$&quot;</span>
<span class="kw1">RewriteCond</span> <span class="st0">&quot;%{REQUEST_FILENAME}&quot;</span> <span class="st0">&quot;!^/(?:static|doc|lib).*&quot;</span>
<span class="kw1">RewriteRule</span> <span class="st0">&quot;^/(.+)$&quot;</span> <span class="st0">&quot;/psgi/manager-server.fcgi/$1&quot;</span> [PT]</pre>
<p>
by:
</p>
<pre class="code apache"><span class="co1"># RewriteRule &quot;^/$&quot; &quot;/psgi/manager-server.fcgi&quot; [PT]</span>
<span class="kw1">DirectoryIndex</span> manager.html
<span class="kw1">RewriteCond</span> <span class="st0">&quot;%{REQUEST_FILENAME}&quot;</span> <span class="st0">&quot;!<span class="es0">\.</span>html$&quot;</span>
<span class="kw1">RewriteCond</span> <span class="st0">&quot;%{REQUEST_FILENAME}&quot;</span> <span class="st0">&quot;!^/(?:static|doc|lib).*&quot;</span>
<span class="kw1">RewriteRule</span> <span class="st0">&quot;^/(.+)$&quot;</span> <span class="st0">&quot;/psgi/manager-server.fcgi/$1&quot;</span> [PT]</pre>
<p>
So manager <abbr title="HyperText Markup Language">HTML</abbr> templates will be no more generated by Perl but directly given by the web server.
</p>
</div>
<!-- EDIT14 SECTION "Use static HTML files" [12023-] --></div>
</body>
</html>