You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@cassandra.apache.org by "Charulata Sharma (charshar)" <ch...@cisco.com> on 2017/10/02 23:44:00 UTC

Async queries

Hi ,


We are observing some performance issues when executing a large number of read/write queries.
We use executeAsync query for most of our read and write requests and then future.getUninterruptibly() methods before returning to the client application.


Code snippet is:  (In the bind portion we have some GSON object conversions.

     List<ResultSetFuture> futures = new ArrayList<>();

      BoundStatement bind ;
      For(loop condition) {
        bind =PreparedStatement.bind(….) //The PreparedStatement is prepared outside the loop.
       resultSetFuture = SESSION.executeAsync(bind);
     futures.add(resultSetFu ture);
  }

for(ResultSetFuture future: futures){
   future.getUninterruptibly();
}


Reading through the documents , I found that although the queries are executed in an async fashion, the future. getUninterruptibly(), is a blocking call.
I am trying to implement a callable future, but wanted to know from the community if there is any better way of doing this and if changing to callable future will help.


Thanks,
Charu

Re: Async queries

Posted by "Charulata Sharma (charshar)" <ch...@cisco.com>.
Thanks Andy for the detailed explanation. I have added the callback feature and am going to test if this helps.

Charu

From: Andy Tolbert <an...@datastax.com>
Reply-To: "user@cassandra.apache.org" <us...@cassandra.apache.org>
Date: Monday, October 2, 2017 at 5:48 PM
To: "user@cassandra.apache.org" <us...@cassandra.apache.org>
Subject: Re: Async queries

Hi Charu,

Since the driver uses Guava futures, you can use some of the methods in Futures<https://google.github.io/guava/releases/19.0/api/docs/com/google/common/util/concurrent/Futures.html> to add listeners, callbacks and transformers that are invoked when the future completes without blocking the calling thread like getUninterruptibly does.  For example, the following registers a callback whose onSuccess or onFailure method is called based on the success of the query.

Futures.addCallback(future, new FutureCallback<ResultSet>() {
    public void onSuccess(ResultSet result) {
        // process result
    }

    public void onFailure(Throwable t) {
        // log exception
    }
});

You can read more about using the driver's async features here<http://docs.datastax.com/en/developer/java-driver/3.3/manual/async/>.

Since executeAsync does not block, you'll want to be careful of is not submitting too many requests at a time as this can degrade performance and may explain what you are observing.  One simple (although somewhat crude) way of handling this is to use a Semaphore with a fixed number of permits.  You would acquire a Semaphore permit before you execute a query, and then release a permit in a callback on completion of the request.  This would cause your calling thread to block whenever you run out of permits, and then continue when a query completes and releases a permit.

The upcoming version (4.0) of the java driver uses CompletionStage/CompletableFuture (java 8 futures), although we'll probably provide a guava extension as well for those who still want to use ListenableFuture.

Thanks,
Andy


On Mon, Oct 2, 2017 at 6:44 PM Charulata Sharma (charshar) <ch...@cisco.com>> wrote:
Hi ,


We are observing some performance issues when executing a large number of read/write queries.
We use executeAsync query for most of our read and write requests and then future.getUninterruptibly() methods before returning to the client application.


Code snippet is:  (In the bind portion we have some GSON object conversions.

     List<ResultSetFuture> futures = new ArrayList<>();

      BoundStatement bind ;
      For(loop condition) {
        bind =PreparedStatement.bind(….) //The PreparedStatement is prepared outside the loop.
       resultSetFuture = SESSION.executeAsync(bind);
     futures.add(resultSetFu ture);
  }

for(ResultSetFuture future: futures){
   future.getUninterruptibly();
}


Reading through the documents , I found that although the queries are executed in an async fashion, the future. getUninterruptibly(), is a blocking call.
I am trying to implement a callable future, but wanted to know from the community if there is any better way of doing this and if changing to callable future will help.


Thanks,
Charu

Re: Async queries

Posted by Andy Tolbert <an...@datastax.com>.
Hi Charu,

Since the driver uses Guava futures, you can use some of the methods in
Futures
<https://google.github.io/guava/releases/19.0/api/docs/com/google/common/util/concurrent/Futures.html>
to
add listeners, callbacks and transformers that are invoked when the future
completes without blocking the calling thread like getUninterruptibly
does.  For example, the following registers a callback whose onSuccess or
onFailure method is called based on the success of the query.

Futures.addCallback(future, new FutureCallback<ResultSet>() {
    public void onSuccess(ResultSet result) {
        // process result
    }

    public void onFailure(Throwable t) {
        // log exception
    }
});

You can read more about using the driver's async features here
<http://docs.datastax.com/en/developer/java-driver/3.3/manual/async/>.

Since executeAsync does not block, you'll want to be careful of is not
submitting too many requests at a time as this can degrade performance and
may explain what you are observing.  One simple (although somewhat crude)
way of handling this is to use a Semaphore with a fixed number of permits.
You would acquire a Semaphore permit before you execute a query, and then
release a permit in a callback on completion of the request.  This would
cause your calling thread to block whenever you run out of permits, and
then continue when a query completes and releases a permit.

The upcoming version (4.0) of the java driver uses
CompletionStage/CompletableFuture (java 8 futures), although we'll probably
provide a guava extension as well for those who still want to use
ListenableFuture.

Thanks,
Andy


On Mon, Oct 2, 2017 at 6:44 PM Charulata Sharma (charshar) <
charshar@cisco.com> wrote:

> Hi ,
>
>
>
>
>
> We are observing some performance issues when executing a large number of
> read/write queries.
>
> We use executeAsync query for most of our read and write requests and then
> future.getUninterruptibly() methods before returning to the client
> application.
>
>
>
>
>
> Code snippet is:  (In the bind portion we have some GSON object
> conversions.
>
>
>
>      List<ResultSetFuture> futures = *new* ArrayList<>();
>
>
>
>       BoundStatement bind ;
>
>       For(loop condition) {
>
>         bind =PreparedStatement.bind(….) //The PreparedStatement is
> prepared outside the loop.
>
>        resultSetFuture = *SESSION*.executeAsync(bind);
>
>
>      futures.add(resultSetFu ture);
>
>   }
>
>
>
> *for*(ResultSetFuture future: futures){
>
>    future.getUninterruptibly();
>
> }
>
>
>
>
>
> Reading through the documents , I found that although the queries are
> executed in an async fashion, the future. getUninterruptibly(), is a
> blocking call.
>
> I am trying to implement a callable future, but wanted to know from the
> community if there is any better way of doing this and if changing to
> callable future will help.
>
>
>
>
>
> Thanks,
>
> Charu
>