Author: chetanm
Date: Thu Dec 24 05:25:34 2015
New Revision: 1721597
URL: http://svn.apache.org/viewvc?rev=1721597&view=rev
Log:
OAK-3806 - Collect and expose statistics related to BlobStore operations
Expose BlobStore stats from DocumentNodeStore when BlobStore instances are
created implicitly
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentMK.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreService.java
jackrabbit/oak/trunk/oak-pojosr/src/test/groovy/org/apache/jackrabbit/oak/run/osgi/DocumentNodeStoreConfigTest.groovy
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentMK.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentMK.java?rev=1721597&r1=1721596&r2=1721597&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentMK.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentMK.java
Thu Dec 24 05:25:34 2015
@@ -25,6 +25,7 @@ import java.util.Set;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
+import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.sql.DataSource;
@@ -45,6 +46,7 @@ import org.apache.jackrabbit.oak.commons
import org.apache.jackrabbit.oak.commons.json.JsopStream;
import org.apache.jackrabbit.oak.commons.json.JsopTokenizer;
import org.apache.jackrabbit.oak.json.JsopDiff;
+import org.apache.jackrabbit.oak.plugins.blob.BlobStoreStats;
import org.apache.jackrabbit.oak.plugins.blob.ReferencedBlob;
import org.apache.jackrabbit.oak.plugins.document.DocumentNodeState.Children;
import org.apache.jackrabbit.oak.plugins.document.cache.NodeDocumentCache;
@@ -64,10 +66,12 @@ import org.apache.jackrabbit.oak.plugins
import org.apache.jackrabbit.oak.plugins.document.util.MongoConnection;
import org.apache.jackrabbit.oak.plugins.document.util.RevisionsKey;
import org.apache.jackrabbit.oak.plugins.document.util.StringValue;
+import org.apache.jackrabbit.oak.spi.blob.AbstractBlobStore;
import org.apache.jackrabbit.oak.spi.blob.BlobStore;
import org.apache.jackrabbit.oak.spi.blob.GarbageCollectableBlobStore;
import org.apache.jackrabbit.oak.spi.blob.MemoryBlobStore;
import org.apache.jackrabbit.oak.stats.Clock;
+import org.apache.jackrabbit.oak.stats.StatisticsProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -512,6 +516,8 @@ public class DocumentMK {
private String persistentCacheURI = DEFAULT_PERSISTENT_CACHE_URI;
private PersistentCache persistentCache;
private LeaseFailureHandler leaseFailureHandler;
+ private StatisticsProvider statisticsProvider =
StatisticsProvider.NOOP;
+ private BlobStoreStats blobStoreStats;
public Builder() {
}
@@ -562,6 +568,7 @@ public class DocumentMK {
if (this.blobStore == null) {
GarbageCollectableBlobStore s = new MongoBlobStore(db,
blobCacheSizeMB * 1024 * 1024L);
+ configureStatsCollector(s);
PersistentCache p = getPersistentCache();
if (p != null) {
s = p.wrapBlobStore(s);
@@ -591,6 +598,7 @@ public class DocumentMK {
this.documentStore = new RDBDocumentStore(ds, this);
if(this.blobStore == null) {
this.blobStore = new RDBBlobStore(ds);
+ configureStatsCollector(blobStore);
}
return this;
}
@@ -605,6 +613,7 @@ public class DocumentMK {
this.documentStore = new RDBDocumentStore(ds, this, options);
if(this.blobStore == null) {
this.blobStore = new RDBBlobStore(ds, options);
+ configureStatsCollector(blobStore);
}
return this;
}
@@ -628,6 +637,7 @@ public class DocumentMK {
public Builder setRDBConnection(DataSource documentStoreDataSource,
DataSource blobStoreDataSource) {
this.documentStore = new RDBDocumentStore(documentStoreDataSource,
this);
this.blobStore = new RDBBlobStore(blobStoreDataSource);
+ configureStatsCollector(blobStore);
return this;
}
@@ -724,6 +734,7 @@ public class DocumentMK {
public BlobStore getBlobStore() {
if (blobStore == null) {
blobStore = new MemoryBlobStore();
+ configureStatsCollector(blobStore);
}
return blobStore;
}
@@ -856,6 +867,16 @@ public class DocumentMK {
return this;
}
+ public Builder setStatisticsProvider(StatisticsProvider
statisticsProvider){
+ this.statisticsProvider = statisticsProvider;
+ return this;
+ }
+
+ @CheckForNull
+ public BlobStoreStats getBlobStoreStats() {
+ return blobStoreStats;
+ }
+
public Clock getClock() {
return clock;
}
@@ -1016,6 +1037,13 @@ public class DocumentMK {
build();
}
+ private void configureStatsCollector(BlobStore blobStore) {
+ if (blobStore instanceof AbstractBlobStore){
+ this.blobStoreStats = new BlobStoreStats(statisticsProvider);
+ ((AbstractBlobStore)
blobStore).setStatsCollector(blobStoreStats);
+ }
+ }
+
}
}
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreService.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreService.java?rev=1721597&r1=1721596&r2=1721597&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreService.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreService.java
Thu Dec 24 05:25:34 2015
@@ -63,6 +63,7 @@ import org.apache.jackrabbit.oak.osgi.Os
import org.apache.jackrabbit.oak.plugins.blob.BlobGC;
import org.apache.jackrabbit.oak.plugins.blob.BlobGCMBean;
import org.apache.jackrabbit.oak.plugins.blob.BlobGarbageCollector;
+import org.apache.jackrabbit.oak.plugins.blob.BlobStoreStats;
import org.apache.jackrabbit.oak.plugins.blob.SharedDataStore;
import org.apache.jackrabbit.oak.plugins.blob.datastore.SharedDataStoreUtils;
import org.apache.jackrabbit.oak.plugins.document.util.MongoConnection;
@@ -70,6 +71,7 @@ import org.apache.jackrabbit.oak.plugins
import org.apache.jackrabbit.oak.spi.blob.BlobStore;
import org.apache.jackrabbit.oak.spi.blob.BlobStoreWrapper;
import org.apache.jackrabbit.oak.spi.blob.GarbageCollectableBlobStore;
+import org.apache.jackrabbit.oak.spi.blob.stats.BlobStoreStatsMBean;
import org.apache.jackrabbit.oak.spi.state.Clusterable;
import org.apache.jackrabbit.oak.spi.state.NodeStore;
import org.apache.jackrabbit.oak.spi.state.RevisionGC;
@@ -78,6 +80,7 @@ import org.apache.jackrabbit.oak.spi.whi
import org.apache.jackrabbit.oak.spi.whiteboard.Whiteboard;
import org.apache.jackrabbit.oak.spi.whiteboard.WhiteboardExecutor;
import org.apache.jackrabbit.oak.spi.whiteboard.WhiteboardUtils;
+import org.apache.jackrabbit.oak.stats.StatisticsProvider;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleException;
import org.osgi.framework.Constants;
@@ -310,6 +313,9 @@ public class DocumentNodeStoreService {
public static final String PROP_DS_TYPE = "documentStoreType";
private DocumentStoreType documentStoreType;
+ @Reference
+ private StatisticsProvider statisticsProvider;
+
private boolean customBlobStore;
@Activate
@@ -355,9 +361,9 @@ public class DocumentNodeStoreService {
String persistentCache =
PropertiesUtil.toString(prop(PROP_PERSISTENT_CACHE), DEFAULT_PERSISTENT_CACHE);
int cacheSegmentCount = toInteger(prop(PROP_CACHE_SEGMENT_COUNT),
DEFAULT_CACHE_SEGMENT_COUNT);
int cacheStackMoveDistance =
toInteger(prop(PROP_CACHE_STACK_MOVE_DISTANCE),
DEFAULT_CACHE_STACK_MOVE_DISTANCE);
-
DocumentMK.Builder mkBuilder =
new DocumentMK.Builder().
+ setStatisticsProvider(statisticsProvider).
memoryCacheSize(cacheSize * MB).
memoryCacheDistribution(
nodeCachePercentage,
@@ -453,7 +459,7 @@ public class DocumentNodeStoreService {
}
}
- registerJMXBeans(mk.getNodeStore());
+ registerJMXBeans(mk.getNodeStore(), mkBuilder);
registerLastRevRecoveryJob(mk.getNodeStore());
registerJournalGC(mk.getNodeStore());
@@ -570,7 +576,8 @@ public class DocumentNodeStoreService {
}
}
- private void registerJMXBeans(final DocumentNodeStore store) throws
IOException {
+ private void registerJMXBeans(final DocumentNodeStore store,
DocumentMK.Builder mkBuilder) throws
+ IOException {
registrations.add(
registerMBean(whiteboard,
CacheStatsMBean.class,
@@ -647,6 +654,14 @@ public class DocumentNodeStoreService {
registrations.add(registerMBean(whiteboard, RevisionGCMBean.class,
revisionGC,
RevisionGCMBean.TYPE, "Document node store revision garbage
collection"));
+ BlobStoreStats blobStoreStats = mkBuilder.getBlobStoreStats();
+ if (!customBlobStore && blobStoreStats != null) {
+ registrations.add(registerMBean(whiteboard,
+ BlobStoreStatsMBean.class,
+ blobStoreStats,
+ BlobStoreStatsMBean.TYPE,
+ ds.getClass().getSimpleName()));
+ }
//TODO Register JMX bean for Off Heap Cache stats
}
Modified:
jackrabbit/oak/trunk/oak-pojosr/src/test/groovy/org/apache/jackrabbit/oak/run/osgi/DocumentNodeStoreConfigTest.groovy
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-pojosr/src/test/groovy/org/apache/jackrabbit/oak/run/osgi/DocumentNodeStoreConfigTest.groovy?rev=1721597&r1=1721596&r2=1721597&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-pojosr/src/test/groovy/org/apache/jackrabbit/oak/run/osgi/DocumentNodeStoreConfigTest.groovy
(original)
+++
jackrabbit/oak/trunk/oak-pojosr/src/test/groovy/org/apache/jackrabbit/oak/run/osgi/DocumentNodeStoreConfigTest.groovy
Thu Dec 24 05:25:34 2015
@@ -20,11 +20,14 @@
package org.apache.jackrabbit.oak.run.osgi
import org.apache.felix.connect.launch.PojoServiceRegistry
+import org.apache.jackrabbit.oak.api.Blob
import org.apache.jackrabbit.oak.plugins.document.DocumentNodeStore
import org.apache.jackrabbit.oak.plugins.document.mongo.MongoBlobStore
import org.apache.jackrabbit.oak.plugins.document.util.MongoConnection
import org.apache.jackrabbit.oak.spi.blob.BlobStore
+import org.apache.jackrabbit.oak.spi.blob.GarbageCollectableBlobStore
import org.apache.jackrabbit.oak.spi.blob.MemoryBlobStore
+import org.apache.jackrabbit.oak.spi.blob.stats.BlobStoreStatsMBean
import org.apache.jackrabbit.oak.spi.state.NodeStore
import org.h2.jdbcx.JdbcDataSource
import org.junit.After
@@ -64,6 +67,7 @@ class DocumentNodeStoreConfigTest extend
//4. Check that only one cluster node was instantiated
assert getIdsOfClusterNodes(ds).size() == 1
+ testBlobStoreStats(ns)
}
@Test
@@ -221,6 +225,8 @@ class DocumentNodeStoreConfigTest extend
Collection<String> colNames = getCollectionNames()
assert colNames.containsAll(['NODES'])
assert !colNames.contains(['BLOBS'])
+ assert registry.getServiceReference(BlobStoreStatsMBean.class.name) ==
null : "BlobStoreStatsMBean should " +
+ "*NOT* be registered by DocumentNodeStoreService in case
custom blobStore used"
}
@Test
@@ -232,7 +238,7 @@ class DocumentNodeStoreConfigTest extend
'org.apache.jackrabbit.oak.plugins.document.DocumentNodeStoreService': [
mongouri: MongoUtils.mongoURI,
db : MongoUtils.mongoDB,
- blobCacheSize : 1024,
+ blobCacheSize : 1,
]
])
@@ -241,7 +247,29 @@ class DocumentNodeStoreConfigTest extend
Collection<String> colNames = getCollectionNames()
assert colNames.containsAll(['NODES', "BLOBS"])
- assert 1024*1024*1024 == ((MongoBlobStore)ns.blobStore).blobCacheSize
+ assert 1*1024*1024 == ((MongoBlobStore)ns.blobStore).blobCacheSize
+ assert getService(BlobStoreStatsMBean.class) : "BlobStoreStatsMBean
should " +
+ "be registered by DocumentNodeStoreService in default
blobStore used"
+
+ testBlobStoreStats(ns)
+ }
+
+
+ public void testBlobStoreStats(DocumentNodeStore nodeStore) throws
Exception{
+ int size = 1024 * 1024 * 5
+ Blob blob = nodeStore.createBlob(testStream(size));
+ BlobStoreStatsMBean stats = getService(BlobStoreStatsMBean.class)
+ assert stats.getUploadTotalSize() == size
+ assert stats.uploadCount > 0
+
+ BlobStore bs = nodeStore.blobStore;
+ assert bs instanceof GarbageCollectableBlobStore
+ bs.clearCache()
+
+ assert size == blob.newStream.getBytes().length
+
+ assert stats.downloadCount > 0
+ assert stats.downloadTotalSize > 0
}
@Override
@@ -299,4 +327,11 @@ class DocumentNodeStoreConfigTest extend
ds.url = url
return ds
}
+
+ private InputStream testStream(int size) {
+ //Cannot use NullInputStream as it throws exception upon EOF
+ byte[] data = new byte[size];
+ new Random().nextBytes(data);
+ return new ByteArrayInputStream(data);
+ }
}