[This blog was syndicated from http://nitschinger.at/]
For all users of our Java SDK, we prepared some nice additions for you. This post covers them in detail and shows how you can get more productive
Note that this blog post assumes you are running the 1.2.1 release, because there have been some slight changes between 1.2.0 and 1.2.1 that affect for example the listener support and metrics collection.
Maven Central Distribution
From the 1.2.0 release forward, the Java SDK is distributed directly from Maven Central. This means that you don’t need to include the Couchbase repository anymore. The following maven code is enough to get started (note that the groupId has changed):
<dependency>
<groupId>com.couchbase.client>
<artifactId>couchbase-client>
<version>1.2.1>
>
>
This will automatically load the latest spymemcached dependency in as well (for 1.2.0 it’s 2.10.0). Before we dig into what has changed, here are the release notes for a quick reference.
Listener Support
OperationFuture<Boolean> setFuture = client.set(“key”, “value”);
// block the current thread
Boolean result = setFuture.get();
for (int i = 0; i < 100; i++) {
futures.add(client.set(“key-“ + i, “value”));
}
while (!futures.isEmpty()) {
Iterator<OperationFuture<Boolean>> iter = futures.iterator();
while (iter.hasNext()) {
OperationFuture<Boolean> future = iter.next();
if (future.isDone()) {
iter.remove();
}
}
}
.get()
method on the future will not block anymore because the result is already computed. Whatever you put in the callback method will be executed asynchronously on the thread pool. To see how flexible that approach is, let’s rewrite the example from above waiting until the 100 futures are done.for (int i = 0; i < 100; i++) {
OperationFuture<Boolean> future = client.set(“key-“ + i, “value”);
future.addListener(new OperationCompletionListener() {
@Override
public void onComplete(OperationFuture<?> future) throws Exception {
latch.countDown();
}
});
}
latch.await();
ExecutorService
implementation with a custom one. This may be needed if the default behavior (Basically a upper-bounded cachedThreadPool) does not suite your needs. Also, you should use this approach if you create a bunch of CouchbaseClient
instances so you can share the same service across all of them.CouchbaseConnectionFactoryBuilder builder = new CouchbaseConnectionFactoryBuilder();
// Create a thread pool of 5 fixed threads
ExecutorService service = Executors.newFixedThreadPool(5);
// Set it in the builder
builder.setListenerExecutorService(service);
// Create the instance
CouchbaseClient client = new CouchbaseClient(builder.buildCouchbaseConnection(…));
Enhanced Profiling Capabilities
<groupId>com.codahale.metrics>
<artifactId>metrics-core>
<version>3.0.1>
>
// enable metric collection
builder.setEnableMetrics(MetricType.PERFORMANCE);
MetricType
enumeration you can see that there are three types of values you can choose from: OFF (which keeps metric collection off), PERFORMANCE (which only collects performance-relevant metrics) and DEBUG (which collects all kinds of metrics, including the performance ones). While the metrics library is quite efficient, keep in mind that metric collection takes some resources away from your application.builder.setEnableMetrics(MetricType.PERFORMANCE);
CouchbaseConnectionFactory cf =
builder.buildCouchbaseConnection(Arrays.asList(new URI(“http://127.0.0.1:8091/pools”)), “default”, “”);
CouchbaseClient client = new CouchbaseClient(cf);
while(true) {
client.set(“foo”, “bar”);
Thread.sleep(100);
}
— Histograms ——————————————————————
[MEM] Average Bytes read from OS per read
count = 893
min = 24
max = 24
mean = 24.00
stddev = 0.00
median = 24.00
75% <= 24.00
95% <= 24.00
98% <= 24.00
99% <= 24.00
99.9% <= 24.00
[MEM] Average Bytes written to OS per write
count = 893
min = 38
max = 38
mean = 38.00
stddev = 0.00
median = 38.00
75% <= 38.00
95% <= 38.00
98% <= 38.00
99% <= 38.00
99.9% <= 38.00
[MEM] Average Time on wire for operations (µs)
count = 893
min = 179
max = 1730
mean = 263.80
stddev = 75.43
median = 251.00
75% <= 280.00
95% <= 351.90
98% <= 425.36
99% <= 559.70
99.9% <= 1730.00
— Meters ———————————————————————-
[MEM] Request Rate: All
count = 893
mean rate = 9.92 events/second
1-minute rate = 9.85 events/second
5-minute rate = 9.68 events/second
15-minute rate = 9.63 events/second
[MEM] Response Rate: All (Failure + Success + Retry)
count = 893
mean rate = 9.92 events/second
1-minute rate = 9.85 events/second
5-minute rate = 9.68 events/second
15-minute rate = 9.63 events/second
net.spy.metrics.reporter.type=jmx
. Other possible settings are csv
and slf4j. If you choose a logger that prints out information at a given interval you can change it by setting
net.spy.metrics.reporter.interval to anything else than 30.
before the code shown above, you can open (for example) jConsole and switch to the MBeans tab of the application. You'll see a
metrics subsection exposed that contains the same metrics as they would show up in the logs.
CAS with Expiration
update and set a new expiration at the same time. You had to do a second
touch operation which was not efficient nor atomic. Now, the API exposes a new
cas() method that allows you to pass in the expiration time at the same time. It is easy to use:
Initializing through Properties
object based on system properties. Here is an example:
System.setProperty("cbclient.bucket", "default");
System.setProperty("cbclient.password", "");
CouchbaseConnectionFactoryBuilder builder = new CouchbaseConnectionFactoryBuilder();
CouchbaseConnectionFactory cf = builder.buildCouchbaseConnection();
CouchbaseClient client = new CouchbaseClient(cf);
at com.couchbase.client.CouchbaseConnectionFactory.(CouchbaseConnectionFactory.java:160)
at com.couchbase.client.CouchbaseConnectionFactoryBuilder$2.(CouchbaseConnectionFactoryBuilder.java:318)
at com.couchbase.client.CouchbaseConnectionFactoryBuilder.buildCouchbaseConnection(CouchbaseConnectionFactoryBuilder.java:318)
at Main.main(Main.java:33)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Other Changes
and
PersistTo has been lowered to
10ms to account for performance changes that went into the Couchbase Sever 2.2 release. Also, the client now uses the
CRAM-MD5` authentication mechanism automatically if the server supports it (since 2.2 as well).
[…] Blog post of the week: What’s new in the Couchbase Java SDK 1.2 […]