Load Test -Couchbase 3.0.5 VS Couchbase 2.7.7 (Java SDK)

Hello Team,

Good day!!

A simple POC done for insert documents and doing load test in the process of migration from 2.7.7. Couchbase to 3.0.5 .for this POC Asynchronous program has been used.

The test follows with 10 instances of client and 1lk records.

3.0.5 inserting 69 records per seconds to insert. (using Whencompleteaysnc)
2.7.7. inserting 180 records per second to insert.(using sync)

Can you please suggest any refactoring can be done in the insert flow to improve scaling. Please find the sample below.
3.7.7 sample code:

			String id = "123"
                            body.put("testing", collection);
                            ar.result().bucket(bucketName).defaultCollection().insert(id, body)
                                    .whenCompleteAsync((insertResult, exception) -> {
                                        if (exception != null) {
                                            logger.error("Error while inserting document", exception.getCause());
                                            resultHandler.handle(Future.failedFuture(exception.getCause()));
                                        }
                                        else {
                                            JsonObject response = JsonObject.fromJson(body.toString());
                                            response.put("_id", id);
                                            logger.info("Document inserted {}", id);
                                            resultHandler.handle(Future.succeededFuture(response));
                                        }
                                    });
                        }

Thanks,
Kamesh.

@kamesh_kumar I’m not seeing anything obviously wrong with that code. 3.x is faster than 2.x in our internal benchmarks so your results are puzzling.

Was your 2.7.7 code also decoding the JSON (e.g. the JsonObject.fromJson)? JSON deserialization is fairly expensive.

@kamesh_kumar please share your 2.7 equivalent code - thanks!

Also, please try sync vs. sync as well. What does the resultHandler do? If you use an async callback, you are on our IO threads. You must not perform any blocking ops in them or you’ll get slowdown.

Thanks Graham for the quick Reply!!

No .decoding was not there in 2x version. But need to print the response to the end user. In 2x different approach used.

Adding to the above logic there is a validation check before insert doc which was added newly .Validating the bucket exist or not before insertion . I am using two async calls in this process. one for bucket validation ,another for insertion.

Code:
try {
cluster.buckets().getBucket(bucketName).whenCompleteAsync((bucketResult, bucketException) -> {
if (bucketException != null) {

                        resultHandler.handle(Future.failedFuture(bucketException.getCause()));
                    }
                    else {
                        try {
                            String id = ""
                            body.put("testing" collection);
                            ar.result().bucket(bucketName).defaultCollection().insert(id, body)
                                    .whenCompleteAsync((insertResult, exception) -> {
                                        if (exception != null) {
                                            resultHandler.handle(Future.failedFuture(exception.getCause()));
                                        }
                                        else {
                                            JsonObject response = JsonObject.fromJson(body.toString());
                                            response.put("_id", id);
                                            response.removeKey(CouchbaseRestClientConstants.COLLECTION_KEY);
                                            logger.info("Document inserted {}", id);
                                            resultHandler.handle(Future.succeededFuture(response));
                                        }
                                    });
                        }
                        catch (Exception ex) {
                           
                            resultHandler.handle(Future.failedFuture(ex));
                        }
                    }
                });
            }

Thanks Daschl for Quick Reply!!

With Sync both version are giving good results. Resulthandler are used to send back the response to end user. I will try to delete that piece of code and give a test.

2x sample code:

try {
String id = dummu134;
vertx. executeBlocking(future -> {
Bucket bucket =cluster.openBucket(bucketName);
body.put(“test”, collection);
JsonDocument jsonDocument = JsonDocument.create(id, body);
JsonDocument resDoc = bucket.insert(jsonDocument);
future.complete(resDoc);
}, res -> {
if (res.failed()) {
logger.error(“Error while inserting document”, res.cause());
resultHandler.handle(Future.failedFuture(res.cause()));
}
else {
JsonObject response = res.result().content();
response.put("_id", id);
logger.info(“Document inserted {}”, id);
resultHandler.handle(Future.succeededFuture(response));
}
});
}
catch (Exception ex) {

                resultHandler.handle(Future.failedFuture(ex));
            }