Bringing together the Apache Cassandra experts from the community and DataStax.

Want to learn? Have a question? Want to share your expertise? You are in the right place!

Not sure where to begin? Getting Started

 

question

cassandrauser avatar image
cassandrauser asked Erick Ramirez answered

Why does Java driver 4.4.0 open connections to all nodes and not close them when app is idle?

After upgrading the application to use cassandra-client-driver 4.4.0 (from 3.X) , we are seeing the following differences

a) Application connects to all the cassandra nodes and driver establishes connections to all cassandra nodes

b) These established connections are not closed when the application is idle. If there are 6 cassandra nodes in the ring, application holds connection to all the 6 cassandra nodes and those 6 connections are not closed even when the application fires only one or two cassandra-queries per second.

Behavior -(b) was different in 3.x where connections are teared down except for one or two connections to subset of cassandra nodes. We are worried behavior-(b) would end up creating too many connections when there are 30 nodes in cassandra ring and application creating 30 connections and holding on to it redundantly.

Here is the builder settings used in 4.4.0:

ProgrammaticDriverConfigLoaderBuilder builder = DriverConfigLoader.programmaticBuilder()
.withString(PROTOCOL_VERSION, ProtocolVersion.V3.name());
builder = builder.withInt(CONNECTION_POOL_LOCAL_SIZE, 1);
builder.withDuration(10000, Duration.ofMillis(connectionTimeoutMillis));
builder.withDuration(10000, Duration.ofMillis(readTimeoutMillis));
builder.withBoolean(SOCKET_KEEP_ALIVE, true);
builder.withClass(LOAD_BALANCING_POLICY_CLASS, DefaultLoadBalancingPolicy.class);
builder.withBoolean(REQUEST_DEFAULT_IDEMPOTENCE, true);
builder.withClass(RETRY_POLICY_CLASS, DefaultRetryPolicy.class);
builder.withString(REQUEST_CONSISTENCY, ConsistencyLevel.LOCAL_QUORUM.name());

Is there any property to set the idle timeout to close the unused connections

java driver
10 |1000 characters needed characters left characters exceeded

Up to 8 attachments (including images) can be used with a maximum of 1.0 MiB each and 10.0 MiB total.

1 Answer

Erick Ramirez avatar image
Erick Ramirez answered

By design, the Java driver opens one connection to nodes that are alive so the connections you refer to are intentional. It is possible to increase the connection pool but 1 is sufficient in almost all cases and it isn't necessary to tune it.

When the application is idle and not sending requests, the driver sends keepalive packets (heartbeats) to connected nodes to prevent network devices such as firewalls from dropping the connection and closing sockets. If the connection does get terminated, the driver will trash it and open a new connection to the node.

These connections are not redundant. They are necessary for the performance of your application and keeping connections alive does not cause significant overhead. On the contrary, having to open a connection when a request is received will cause significant latency while the connection is being established.

For details, see the Java driver Connection Pooling document.

As a side note, I noted that you've configured the driver to use native protocol V3 which indicates that you're connecting to a Cassandra 2.1 cluster. If this isn't correct, you should instead use protocol V4 which is the right choice for C* 2.2 to 4.0.

Also, if you're upgrading from Java driver v3.x then it doesn't make sense to upgrade to v4.4.0 because it's quite old. It was released in January 2020 and there have been significant bug fixes added since so we recommend upgrading to the latest which currently is Java driver 4.13.0. Cheers!

Share
10 |1000 characters needed characters left characters exceeded

Up to 8 attachments (including images) can be used with a maximum of 1.0 MiB each and 10.0 MiB total.