Cassandra - Is there a way to limit number of async queries?

I would like to know if there is way to limit the number of queries executed simultaneously by the cassandra java driver ?

Currently, I execute a lot of queries as follows :

... 
PreparedStatement stmt = session.prepare("SELECT * FROM users WHERE id = ?");
BoundStatement boundStatement = new BoundStatement(stmt);
List<ResultSetFuture> futures = Lists.newArrayListWithExpectedSize(list.length);

for(String id : list ) {
     futures.add(session.executeAsync(boundStatement.bind(id)));
}

for (ListenableFuture<ResultSet> future : futures) {
ResultSet rs = future.get();
... // do some stuff
}

Unfortunately, this may lead to NoHostAvailableException.

Thanks you.


Solution 1:

You can use a semaphore to throttle the number of concurrent queries:

final Semaphore semaphore = new Semaphore(numberOfConcurrentQueries);
...
semaphore.acquire();
try {
    ResultSetFuture future = session.executeAsync("...");
    Futures.addCallback(future, new FutureCallback<ResultSet>() {
        @Override
        public void onSuccess(ResultSet result) {
            semaphore.release();
        }

        @Override
        public void onFailure(Throwable t) {
            semaphore.release();
        }
    });
} catch (Exception e) {
    semaphore.release();
}

But at the end of the day it's not so different: instead of getting a NoHostAvailableException when you exceed the capacity, the semaphore will block (or throw if you use a timed version of acquire). So you'll probably want to apply backpressure to the component that triggers these queries as well.

You might also want to tune your connection pools to adjust the capacity, see our docs (that's for 2.1, use the dropdown at the top of the page if you're on 2.0).