Checked statistics docs
git-svn-id: https://svn.jboss.org/repos/hibernate/trunk/Hibernate3/doc@5970 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
parent
4b13e3544f
commit
a308fb5153
|
@ -237,9 +237,5 @@ cfg.getSessionEventListenerConfig().setLoadEventListener( new MyLoadListener() )
|
|||
|
||||
</sect1>
|
||||
|
||||
<para>
|
||||
TODO: document statistics
|
||||
</para>
|
||||
|
||||
</chapter>
|
||||
|
||||
|
|
|
@ -1119,129 +1119,154 @@ hibernate.cache.use_structured_entries true]]></programlisting>
|
|||
|
||||
<sect1 id="performance-monitoring" revision="1">
|
||||
<title>Monitoring performance</title>
|
||||
<para>Performance and optimization are nothing without monitoring. Without rational and concrete figures,
|
||||
no good optimization is possible. Hibernate provides a full panel of figures related to Hibernate behaviors.
|
||||
Hibernate statistics are related to a particular session factory. This makes perfect sense if we consider
|
||||
the typical application as being build on top of one database / session factory.</para>
|
||||
<sect2 id="performance-monitoring-sf" revision="1">
|
||||
<title>Monitoring a session factory</title>
|
||||
|
||||
<para>
|
||||
Optimization is not much use without monitoring and access to performance numbers.
|
||||
Hibernate provides a full range of figures about its internal operations.
|
||||
Statistics in Hibernate are available per <literal>SessionFactory</literal>.
|
||||
</para>
|
||||
|
||||
<sect2 id="performance-monitoring-sf" revision="2">
|
||||
<title>Monitoring a SessionFactory</title>
|
||||
|
||||
<para>
|
||||
Session factories publish their metrics through 2 basic ways. The first one use direct access to the
|
||||
<literal>SessionFactory</literal> object. The statistics are attached to a session factory through
|
||||
<literal>Statistics</literal> objects and accessed by <literal>sessionFactory.getStatistics()</literal>.
|
||||
The second way, a bit more standard, use JMX to publish them through the <literal>StatisticsService</literal>
|
||||
either one MBean per session factory, either one MBean for all session factories. Here is a minimalistic
|
||||
code showing both ways (you must have a JMX server available).
|
||||
You can access <literal>SessionFactory</literal> metrics in two ways.
|
||||
Your first option is to call <literal>sessionFactory.getStatistics()</literal> and
|
||||
read or display the <literal>Statistics</literal> yourself.
|
||||
</para>
|
||||
<programlisting><![CDATA[//Register the MBean in your JMX server for a specific session factory
|
||||
|
||||
<para>
|
||||
Hibernate can also use JMX to publish metrics if you enable the
|
||||
<literal>StatisticsService</literal> MBean. You may enable a single MBean for all your
|
||||
<literal>SessionFactory</literal> or one per factory. See the following code for
|
||||
minimalistic configuration examples:
|
||||
</para>
|
||||
|
||||
<programlisting><![CDATA[// MBean service registration for a specific SessionFactory
|
||||
Hashtable tb = new Hashtable();
|
||||
tb.put("type", "statistics");
|
||||
tb.put("sessionFactory", "myFinancialApp");
|
||||
ObjectName on = new ObjectName("hibernate", tb); //the MBean object name
|
||||
StatisticsService stats = new StatisticsService(); //MBean implementation
|
||||
stats.setSessionFactory(sessionFactory); //the awaited session factory
|
||||
server.registerMBean(stats, on); //we register the MBean
|
||||
//And call the MBean the way you want
|
||||
ObjectName on = new ObjectName("hibernate", tb); // MBean object name
|
||||
|
||||
//or
|
||||
StatisticsService stats = new StatisticsService(); // MBean implementation
|
||||
stats.setSessionFactory(sessionFactory); // Bind the stats to a SessionFactory
|
||||
server.registerMBean(stats, on); // Register the Mbean on the server]]></programlisting>
|
||||
|
||||
//Register the MBean in your JMX server with no specific session factory binding
|
||||
|
||||
<programlisting><![CDATA[// MBean service registration for all SessionFactory's
|
||||
Hashtable tb = new Hashtable();
|
||||
tb.put("type", "statistics");
|
||||
tb.put("sessionFactory", "all");
|
||||
ObjectName on = new ObjectName("hibernate", tb); //the object name
|
||||
StatisticsService stats = new StatisticsService(); //the generic StatisticService
|
||||
server.registerMBean(stats, on); //we register the MBean]]></programlisting>
|
||||
ObjectName on = new ObjectName("hibernate", tb); // MBean object name
|
||||
|
||||
StatisticsService stats = new StatisticsService(); // MBean implementation
|
||||
server.registerMBean(stats, on); // Register the MBean on the server]]></programlisting>
|
||||
|
||||
<para>
|
||||
In the first case, we retrieve and use the MBean directly. In the second one, we must give the JNDI name
|
||||
in which the session factory is held before using it. Use
|
||||
TODO: This doesn't make sense. In the first case, we retrieve and use the MBean directly. In the second one, we must give
|
||||
the JNDI name in which the session factory is held before using it. Use
|
||||
<literal>hibernateStatsBean.setSessionFactoryJNDIName("my/JNDI/Name")</literal>
|
||||
</para>
|
||||
<para>
|
||||
A session factory can be monitored or not. You can (de)activate the monitoring
|
||||
You can (de)activate the monitoring for a <literal>SessionFactory</literal>
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
at configuration time: <literal>hibernate.generate_statistics</literal>, default to false
|
||||
at configuration time, set <literal>hibernate.generate_statistics</literal> to <literal>false</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
at runtime time: <literal>sf.getStatistics().setStatisticsEnabled(true)</literal>
|
||||
at runtime: <literal>sf.getStatistics().setStatisticsEnabled(true)</literal>
|
||||
or <literal>hibernateStatsBean.setStatisticsEnabled(true)</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<para>Statistics can be reset programatically using the <literal>clear()</literal> method. A summary
|
||||
can be sent to a logger (info level) using the <literal>logSummary()</literal> method.</para>
|
||||
|
||||
<para>
|
||||
Statistics can be reset programatically using the <literal>clear()</literal> method.
|
||||
A summary can be sent to a logger (info level) using the <literal>logSummary()</literal>
|
||||
method.
|
||||
</para>
|
||||
|
||||
</sect2>
|
||||
|
||||
<sect2 id="performance-monitoring-metrics" revision="1">
|
||||
<title>Metrics</title>
|
||||
|
||||
<para>
|
||||
Hibernate provides a huge number of metrics, from the very basics to the very specialized ones.
|
||||
All available counters are described in the <literal>Statistics</literal> interface API.
|
||||
They are basically split into 3 categories:
|
||||
Hibernate provides a number of metrics, from very basic to the specialized information
|
||||
only relevant in certain scenarios. All available counters are described in the
|
||||
<literal>Statistics</literal> interface API, in three categories:
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
metrics related to the general session usage (number of session open, session close, connections retrieved, ...),
|
||||
Metrics related to the general <literal>Session</literal> usage, such as
|
||||
number of open sessions, retrieved JDBC connections, etc.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
metrics related to the entities, collections, queries, and caches as a whole (aka global metrics),
|
||||
Metrics related to he entities, collections, queries, and caches as a
|
||||
whole (aka global metrics),
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
detailed metrics related to a particular entity, collection, query or cache region.
|
||||
Detailed metrics related to a particular entity, collection, query or
|
||||
cache region.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
||||
<para>
|
||||
You can find (for example) the cache hit, miss and put ratio of entities, collections
|
||||
and queries, the average time of a query, etc... Beware that the number of milliseconds is subject
|
||||
to approximation in Java. Hibernate is tied to the JVM precision: it might lead to a 10 ms approx depending
|
||||
on your platform.
|
||||
For exampl,e you can check the cache hit, miss, and put ratio of entities, collections
|
||||
and queries, and the average time a query needs. Beware that the number of milliseconds
|
||||
is subject to approximation in Java. Hibernate is tied to the JVM precision, on some
|
||||
platforms this might even only be accurate to 10 seconds.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Simple getters are used to access the global metrics (ie not tied to a particular entity, collection,
|
||||
cache region). You access the metrics of a particular entity, collection or cache region through its name,
|
||||
as shown in the above example, and through its HQL or SQL representation for queries. Please refer to the
|
||||
<literal>Statistics</literal>, <literal>EntityStatistics</literal>, <literal>CollectionStatistics</literal>,
|
||||
<literal>SecondLevelCacheStatistics</literal> and <literal>QueryStatistics</literal> API for more informations.
|
||||
Simple getters are used to access the global metrics (i.e. not tied to a particular entity,
|
||||
collection, cache region, etc.). You can access the metrics of a particular entity, collection
|
||||
or cache region through its name, and through its HQL or SQL representation for queries. Please
|
||||
refer to the <literal>Statistics</literal>, <literal>EntityStatistics</literal>,
|
||||
<literal>CollectionStatistics</literal>, <literal>SecondLevelCacheStatistics</literal>,
|
||||
and <literal>QueryStatistics</literal> API Javadoc for more information. The following
|
||||
code shows a simple example:
|
||||
</para>
|
||||
<programlisting><![CDATA[Statistics stats = sf.getStatistics();
|
||||
double hitRatio = (double) stats.getQueryCacheHitCount()
|
||||
/ ( stats.getQueryCacheHitCount() + stats.getQueryCacheMissCount() );
|
||||
log.info("Query Hit ratio:" + hitRatio);
|
||||
EntityStatistics entityStats = stats.getEntityStatistics( Cat.class.getName() );
|
||||
int changes = entityStats.getInsertCount()
|
||||
+ entityStats.getUpdateCount() + entityStats.getDeleteCount();
|
||||
log.info(Cat.class.getName() + " changes:" + changes);]]></programlisting>
|
||||
|
||||
<programlisting><![CDATA[Statistics stats = HibernateUtil.sessionFactory.getStatistics();
|
||||
|
||||
double queryCacheHitCount = stats.getQueryCacheHitCount();
|
||||
double queryCacheMissCount = stats.getQueryCacheMissCount();
|
||||
double queryCacheHitRatio =
|
||||
queryCacheHitCount / (queryCacheHitCount + queryCacheMissCount);
|
||||
|
||||
log.info("Query Hit ratio:" + queryCacheHitRatio);
|
||||
|
||||
EntityStatistics entityStats =
|
||||
stats.getEntityStatistics( Cat.class.getName() );
|
||||
long changes =
|
||||
entityStats.getInsertCount()
|
||||
+ entityStats.getUpdateCount()
|
||||
+ entityStats.getDeleteCount();
|
||||
log.info(Cat.class.getName() + " changed " + changes + "times" );]]></programlisting>
|
||||
|
||||
<para>
|
||||
In order to work on all detailed entities, collections, queries and region caches statistics, you can retrieve
|
||||
the list of names of entities, collections, queries and region caches names having metrics. Use <literal>getQueries()</literal>,
|
||||
<literal>getEntityNames()</literal>, <literal>getCollectionRoleNames()</literal>, or
|
||||
To work on all entities, collections, queries and region caches, you can retrieve
|
||||
the list of names of entities, collections, queries and region caches with the
|
||||
following methods: <literal>getQueries()</literal>, <literal>getEntityNames()</literal>,
|
||||
<literal>getCollectionRoleNames()</literal>, and
|
||||
<literal>getSecondLevelCacheRegionNames()</literal>.
|
||||
</para>
|
||||
|
||||
</sect2>
|
||||
<sect2 id="performance-monitoring-understandingmetrics" revision="1">
|
||||
<title>Understanding metrics</title>
|
||||
<para>
|
||||
You can find interesting informations while looking at metrics. An entity/collection/query with a high cache
|
||||
miss ratio (cache miss greater than cache hit) should not be cached: the benefit of caching is not significant
|
||||
for your application and use case.
|
||||
An entity/collection/query with a cache put much greater than its cache hit should not be cached either: you spend
|
||||
a lot of resources in caching without efficiently use it.
|
||||
A session factory having more open sessions than closed ones shows a session leak which must be addressed.
|
||||
A use case using lots of connections might show a good candidate for a conversion to the session per user
|
||||
transaction pattern.</para>
|
||||
</sect2>
|
||||
|
||||
</sect1>
|
||||
|
||||
</chapter>
|
||||
</chapter>
|
Loading…
Reference in New Issue