Permalink
Browse files

HHH-7640 Improve single node Infinispan 2LC performance

* Use an Infinispan cache to maintain pending puts, which avoids
the need to control it's memory consumption in the critical path
of putFromLoad.
* This cache is shared by all regions, and it's configured with
aggressive expiration settings to avoid piling up pending put
operations.
* Added a 2LC stress test that tests behaivour and performance
of 2LC under multiple situations, such as entity inserts, updates,
find via PK, find via query and deletes.
* Some other minor performance enhancements, such as avoiding
classloader aware cache wrapper if using 2LC locally.
* Remove cache adapter to reduce construction of useless objects.
* Cache flagged caches in order to avoid recomputing decorated
caches all the time, which reduces memory consumption.
* Skip locking for timestamp updates and separate timestamp region
implementations for local vs clustered scenarios.
  • Loading branch information...
1 parent aeb48af commit e5d3b2b34ccc173e758fc952cf6cdbd6c325f6de @galderz galderz committed Sep 25, 2012
Showing with 2,293 additions and 1,418 deletions.
  1. +7 −0 .gitignore
  2. +3 −1 hibernate-core/src/main/java/org/hibernate/cache/internal/StandardQueryCache.java
  3. +5 −1 hibernate-core/src/main/java/org/hibernate/engine/internal/StatefulPersistenceContext.java
  4. +4 −1 hibernate-core/src/main/java/org/hibernate/internal/SessionImpl.java
  5. +14 −0 hibernate-infinispan/hibernate-infinispan.gradle
  6. +62 −36 hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/InfinispanRegionFactory.java
  7. +22 −194 hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/access/PutFromLoadValidator.java
  8. +24 −20 ...e-infinispan/src/main/java/org/hibernate/cache/infinispan/access/TransactionalAccessDelegate.java
  9. +6 −7 ...nate-infinispan/src/main/java/org/hibernate/cache/infinispan/collection/CollectionRegionImpl.java
  10. +6 −7 hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/entity/EntityRegionImpl.java
  11. +12 −7 hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/impl/BaseGeneralDataRegion.java
  12. +47 −75 hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/impl/BaseRegion.java
  13. +4 −11 ...ate-infinispan/src/main/java/org/hibernate/cache/infinispan/impl/BaseTransactionalDataRegion.java
  14. +12 −9 hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/naturalid/NaturalIdRegionImpl.java
  15. +24 −21 hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/query/QueryResultsRegionImpl.java
  16. +152 −0 ...inispan/src/main/java/org/hibernate/cache/infinispan/timestamp/ClusteredTimestampsRegionImpl.java
  17. +31 −77 ...rnate-infinispan/src/main/java/org/hibernate/cache/infinispan/timestamp/TimestampsRegionImpl.java
  18. +0 −33 hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/util/AddressAdapter.java
  19. +0 −88 hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/util/AddressAdapterImpl.java
  20. +0 −228 hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/util/CacheAdapter.java
  21. +0 −255 hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/util/CacheAdapterImpl.java
  22. +141 −0 hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/util/Caches.java
  23. +0 −69 hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/util/FlagAdapter.java
  24. +3 −3 ...finispan/src/test/java/org/hibernate/test/cache/infinispan/AbstractGeneralDataRegionTestCase.java
  25. +2 −2 ...nate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/AbstractRegionImplTestCase.java
  26. +26 −26 ...infinispan/src/test/java/org/hibernate/test/cache/infinispan/InfinispanRegionFactoryTestCase.java
  27. +8 −9 hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/NodeEnvironment.java
  28. +37 −159 ...an/src/test/java/org/hibernate/test/cache/infinispan/access/PutFromLoadValidatorUnitTestCase.java
  29. +15 −13 ...rg/hibernate/test/cache/infinispan/collection/AbstractCollectionRegionAccessStrategyTestCase.java
  30. +3 −4 ...an/src/test/java/org/hibernate/test/cache/infinispan/collection/CollectionRegionImplTestCase.java
  31. +16 −16 ...t/java/org/hibernate/test/cache/infinispan/entity/AbstractEntityRegionAccessStrategyTestCase.java
  32. +4 −4 ...infinispan/src/test/java/org/hibernate/test/cache/infinispan/entity/EntityRegionImplTestCase.java
  33. +30 −26 ...nispan/util/CacheHelper.java → test/java/org/hibernate/test/cache/infinispan/functional/Age.java}
  34. +7 −8 ...e-infinispan/src/test/java/org/hibernate/test/cache/infinispan/query/QueryRegionImplTestCase.java
  35. +343 −0 ...nfinispan/src/test/java/org/hibernate/test/cache/infinispan/stress/PutFromLoadStressTestCase.java
  36. +626 −0 ...span/src/test/java/org/hibernate/test/cache/infinispan/stress/SecondLevelCacheStressTestCase.java
  37. +216 −0 hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/stress/entities/Address.java
  38. +149 −0 hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/stress/entities/Family.java
  39. +178 −0 hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/stress/entities/Person.java
  40. +4 −6 ...pan/src/test/java/org/hibernate/test/cache/infinispan/timestamp/TimestampsRegionImplTestCase.java
  41. +2 −1 hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/tm/XaTransactionImpl.java
  42. +1 −1 hibernate-infinispan/src/test/resources/log4j.properties
  43. +47 −0 hibernate-infinispan/src/test/resources/stress-local-infinispan.xml
View
@@ -32,3 +32,10 @@ bin
# Miscellaneous
*.log
.clover
+
+# JBoss Transactions
+ObjectStore
+
+# Profiler and heap dumps
+*.jps
+*.hprof
@@ -61,6 +61,8 @@
StandardQueryCache.class.getName()
);
+ private static final boolean tracing = LOG.isTraceEnabled();
+
private QueryResultsRegion cacheRegion;
private UpdateTimestampsCache updateTimestampsCache;
@@ -241,7 +243,7 @@ private static void logCachedResultRowDetails(Type[] returnTypes, Object result)
}
private static void logCachedResultRowDetails(Type[] returnTypes, Object[] tuple) {
- if ( !LOG.isTraceEnabled() ) {
+ if ( !tracing ) {
return;
}
if ( tuple == null ) {
@@ -94,6 +94,8 @@
private static final CoreMessageLogger LOG = Logger.getMessageLogger( CoreMessageLogger.class, StatefulPersistenceContext.class.getName() );
+ private static final boolean tracing = LOG.isTraceEnabled();
+
public static final Object NO_ROW = new MarkerObject( "NO_ROW" );
private static final int INIT_COLL_SIZE = 8;
@@ -1004,7 +1006,9 @@ public void addNonLazyCollection(PersistentCollection collection) {
@Override
public void initializeNonLazyCollections() throws HibernateException {
if ( loadCounter == 0 ) {
- LOG.debug( "Initializing non-lazy collections" );
+ if (tracing)
+ LOG.trace( "Initializing non-lazy collections" );
+
//do this work only at the very highest level of the load
loadCounter++; //don't let this method be called recursively
try {
@@ -180,6 +180,8 @@
private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, SessionImpl.class.getName());
+ private static final boolean tracing = LOG.isTraceEnabled();
+
private transient long timestamp;
private transient SessionOwner sessionOwner;
@@ -309,7 +311,8 @@ public void afterCompletion(boolean successful, TransactionImplementor transacti
factory.getStatisticsImplementor().openSession();
}
- LOG.debugf( "Opened session at timestamp: %s", timestamp );
+ if (tracing)
+ LOG.tracef( "Opened session at timestamp: %s", timestamp );
}
@Override
@@ -13,6 +13,8 @@ dependencies {
testCompile( libraries.jnp_client )
testCompile( libraries.jnp_server )
testCompile( libraries.rhq )
+
+ testCompile ('mysql:mysql-connector-java:5.1.17')
}
test {
@@ -27,3 +29,15 @@ test {
enabled = true
}
+task packageTests(type: Jar) {
+ from sourceSets.test.output
+ classifier = 'tests'
+}
+
+task sourcesTestJar(type: Jar, dependsOn:classes) {
+ from sourceSets.test.allSource
+ classifier = 'test-sources'
+}
+
+artifacts.archives packageTests
+artifacts.archives sourcesTestJar
@@ -10,15 +10,20 @@
import java.util.Map;
import java.util.Properties;
import java.util.Set;
-import javax.transaction.TransactionManager;
+import java.util.concurrent.TimeUnit;
+import org.hibernate.cache.infinispan.timestamp.ClusteredTimestampsRegionImpl;
+import org.hibernate.cache.infinispan.util.Caches;
import org.infinispan.AdvancedCache;
-import org.infinispan.Cache;
import org.infinispan.commands.module.ModuleCommandFactory;
import org.infinispan.config.Configuration;
+import org.infinispan.configuration.cache.CacheMode;
+import org.infinispan.configuration.cache.ConfigurationBuilder;
import org.infinispan.factories.GlobalComponentRegistry;
import org.infinispan.manager.DefaultCacheManager;
import org.infinispan.manager.EmbeddedCacheManager;
+import org.infinispan.transaction.TransactionMode;
+import org.infinispan.util.concurrent.IsolationLevel;
import org.infinispan.util.logging.Log;
import org.infinispan.util.logging.LogFactory;
@@ -34,8 +39,6 @@
import org.hibernate.cache.infinispan.timestamp.TimestampTypeOverrides;
import org.hibernate.cache.infinispan.timestamp.TimestampsRegionImpl;
import org.hibernate.cache.infinispan.tm.HibernateTransactionManagerLookup;
-import org.hibernate.cache.infinispan.util.CacheAdapter;
-import org.hibernate.cache.infinispan.util.CacheAdapterImpl;
import org.hibernate.cache.spi.CollectionRegion;
import org.hibernate.cache.spi.EntityRegion;
import org.hibernate.cache.spi.NaturalIdRegion;
@@ -166,6 +169,11 @@
*/
public static final boolean DEF_USE_SYNCHRONIZATION = true;
+ /**
+ * Name of the pending puts cache.
+ */
+ public static final String PENDING_PUTS_CACHE_NAME = "pending-puts";
+
private EmbeddedCacheManager manager;
private final Map<String, TypeOverrides> typeOverrides = new HashMap<String, TypeOverrides>();
@@ -174,8 +182,6 @@
private org.infinispan.transaction.lookup.TransactionManagerLookup transactionManagerlookup;
- private TransactionManager transactionManager;
-
private List<String> regionNames = new ArrayList<String>();
/**
@@ -197,8 +203,8 @@ public InfinispanRegionFactory(Properties props) {
public CollectionRegion buildCollectionRegion(String regionName, Properties properties, CacheDataDescription metadata) throws CacheException {
if (log.isDebugEnabled()) log.debug("Building collection cache region [" + regionName + "]");
AdvancedCache cache = getCache(regionName, COLLECTION_KEY, properties);
- CacheAdapter cacheAdapter = CacheAdapterImpl.newInstance(cache);
- CollectionRegionImpl region = new CollectionRegionImpl(cacheAdapter, regionName, metadata, transactionManager, this);
+ CollectionRegionImpl region = new CollectionRegionImpl(
+ cache, regionName, metadata, this);
startRegion(region, regionName);
return region;
}
@@ -207,28 +213,22 @@ public CollectionRegion buildCollectionRegion(String regionName, Properties prop
public EntityRegion buildEntityRegion(String regionName, Properties properties, CacheDataDescription metadata) throws CacheException {
if (log.isDebugEnabled()) log.debug("Building entity cache region [" + regionName + "]");
AdvancedCache cache = getCache(regionName, ENTITY_KEY, properties);
- CacheAdapter cacheAdapter = CacheAdapterImpl.newInstance(cache);
- EntityRegionImpl region = new EntityRegionImpl(cacheAdapter, regionName, metadata, transactionManager, this);
+ EntityRegionImpl region = new EntityRegionImpl(
+ cache, regionName, metadata, this);
startRegion(region, regionName);
return region;
}
@Override
public NaturalIdRegion buildNaturalIdRegion(String regionName, Properties properties, CacheDataDescription metadata)
throws CacheException {
- if ( log.isDebugEnabled() ) {
- log.debug( "Building natural id cache region [" + regionName + "]" );
+ if (log.isDebugEnabled()) {
+ log.debug("Building natural id cache region [" + regionName + "]");
}
- AdvancedCache cache = getCache( regionName, NATURAL_ID_KEY, properties );
- CacheAdapter cacheAdapter = CacheAdapterImpl.newInstance( cache );
+ AdvancedCache cache = getCache(regionName, NATURAL_ID_KEY, properties);
NaturalIdRegionImpl region = new NaturalIdRegionImpl(
- cacheAdapter,
- regionName,
- metadata,
- transactionManager,
- this
- );
- startRegion( region, regionName );
+ cache, regionName, metadata, this);
+ startRegion(region, regionName);
return region;
}
@@ -244,8 +244,8 @@ public QueryResultsRegion buildQueryResultsRegion(String regionName, Properties
cacheName = regionName;
AdvancedCache cache = getCache(cacheName, QUERY_KEY, properties);
- CacheAdapter cacheAdapter = CacheAdapterImpl.newInstance(cache);
- QueryResultsRegionImpl region = new QueryResultsRegionImpl(cacheAdapter, regionName, properties, transactionManager, this);
+ QueryResultsRegionImpl region = new QueryResultsRegionImpl(
+ cache, regionName, this);
startRegion(region, regionName);
return region;
}
@@ -257,14 +257,17 @@ public TimestampsRegion buildTimestampsRegion(String regionName, Properties prop
throws CacheException {
if (log.isDebugEnabled()) log.debug("Building timestamps cache region [" + regionName + "]");
AdvancedCache cache = getCache(regionName, TIMESTAMPS_KEY, properties);
- CacheAdapter cacheAdapter = CacheAdapterImpl.newInstance(cache);
- TimestampsRegionImpl region = createTimestampsRegion(cacheAdapter, regionName);
+ TimestampsRegionImpl region = createTimestampsRegion(cache, regionName);
startRegion(region, regionName);
return region;
}
- protected TimestampsRegionImpl createTimestampsRegion(CacheAdapter cacheAdapter, String regionName) {
- return new TimestampsRegionImpl(cacheAdapter, regionName, transactionManager, this);
+ protected TimestampsRegionImpl createTimestampsRegion(
+ AdvancedCache cache, String regionName) {
+ if (Caches.isClustered(cache))
+ return new ClusteredTimestampsRegionImpl(cache, regionName, this);
+ else
+ return new TimestampsRegionImpl(cache, regionName, this);
}
/**
@@ -301,7 +304,6 @@ public void start(Settings settings, Properties properties) throws CacheExceptio
log.debug("Starting Infinispan region factory");
try {
transactionManagerlookup = createTransactionManagerLookup(settings, properties);
- transactionManager = transactionManagerlookup.getTransactionManager();
manager = createCacheManager(properties);
initGenericDataTypeOverrides();
Enumeration keys = properties.propertyNames();
@@ -313,13 +315,30 @@ public void start(Settings settings, Properties properties) throws CacheExceptio
}
}
defineGenericDataTypeCacheConfigurations(settings, properties);
+ definePendingPutsCache();
} catch (CacheException ce) {
throw ce;
} catch (Throwable t) {
throw new CacheException("Unable to start region factory", t);
}
}
+ private void definePendingPutsCache() {
+ ConfigurationBuilder builder = new ConfigurationBuilder();
+ // A local, lightweight cache for pending puts, which is
+ // non-transactional and has aggressive expiration settings.
+ // Locking is still required since the putFromLoad validator
+ // code uses conditional operations (i.e. putIfAbsent).
+ builder.clustering().cacheMode(CacheMode.LOCAL)
+ .transaction().transactionMode(TransactionMode.NON_TRANSACTIONAL)
+ .expiration().maxIdle(TimeUnit.SECONDS.toMillis(60))
+ .storeAsBinary().enabled(false)
+ .locking().isolationLevel(IsolationLevel.READ_COMMITTED)
+ .jmxStatistics().disable();
+
+ manager.defineConfiguration(PENDING_PUTS_CACHE_NAME, builder.build());
+ }
+
protected org.infinispan.transaction.lookup.TransactionManagerLookup createTransactionManagerLookup(
Settings settings, Properties properties) {
return new HibernateTransactionManagerLookup(settings, properties);
@@ -336,7 +355,8 @@ public void stop() {
protected void stopCacheRegions() {
log.debug("Clear region references");
- getCacheCommandFactory(manager.getCache()).clearRegions(regionNames);
+ getCacheCommandFactory(manager.getCache().getAdvancedCache())
+ .clearRegions(regionNames);
regionNames.clear();
}
@@ -376,8 +396,7 @@ protected EmbeddedCacheManager createCacheManager(Properties properties) throws
private void startRegion(BaseRegion region, String regionName) {
regionNames.add(regionName);
- getCacheCommandFactory(region.getCacheAdapter().getCache())
- .addRegion(regionName, region);
+ getCacheCommandFactory(region.getCache()).addRegion(regionName, region);
}
private Map<String, TypeOverrides> initGenericDataTypeOverrides() {
@@ -487,11 +506,14 @@ private AdvancedCache getCache(String regionName, String typeKey, Properties pro
return createCacheWrapper(cache);
}
- private CacheCommandFactory getCacheCommandFactory(Cache cache) {
- GlobalComponentRegistry globalCr = cache.getAdvancedCache()
- .getComponentRegistry().getGlobalComponentRegistry();
+ private CacheCommandFactory getCacheCommandFactory(AdvancedCache cache) {
+ GlobalComponentRegistry globalCr = cache.getComponentRegistry()
+ .getGlobalComponentRegistry();
+
Map<Byte, ModuleCommandFactory> factories =
- (Map<Byte, ModuleCommandFactory>) globalCr.getComponent("org.infinispan.modules.command.factories");
+ (Map<Byte, ModuleCommandFactory>) globalCr
+ .getComponent("org.infinispan.modules.command.factories");
+
for (ModuleCommandFactory factory : factories.values()) {
if (factory instanceof CacheCommandFactory)
return (CacheCommandFactory) factory;
@@ -503,7 +525,11 @@ private CacheCommandFactory getCacheCommandFactory(Cache cache) {
}
protected AdvancedCache createCacheWrapper(AdvancedCache cache) {
- return new ClassLoaderAwareCache(cache, Thread.currentThread().getContextClassLoader());
+ if (Caches.isClustered(cache))
+ return new ClassLoaderAwareCache(cache,
+ Thread.currentThread().getContextClassLoader());
+
+ return cache;
}
private Configuration configureTransactionManager(Configuration regionOverrides, String templateCacheName, Properties properties) {
Oops, something went wrong.

0 comments on commit e5d3b2b

Please sign in to comment.