Skip to content

Commit b43a084

Browse files
committed
Document socket options.
1 parent 3336a45 commit b43a084

2 files changed

Lines changed: 118 additions & 1 deletion

File tree

manual/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ The other aspects that you can configure on the `Cluster` are:
7474
* [query options][QueryOptions];
7575
* [reconnections](reconnection/);
7676
* [retries](retries/);
77-
* [socket options][SocketOptions];
77+
* [socket options](socket_options/);
7878
* [SSL](ssl/);
7979
* [speculative executions](speculative_execution/);
8080
* [query timestamps](query_timestamps/).

manual/socket_options/README.md

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
## Socket options
2+
3+
[SocketOptions] controls various low-level parameters related to TCP connections between the driver and Cassandra.
4+
5+
You can provide these when initializing the cluster:
6+
7+
```java
8+
Cluster cluster = Cluster.builder()
9+
.addContactPoint("127.0.0.1")
10+
.withSocketOptions(
11+
new SocketOptions()
12+
.setConnectTimeoutMillis(2000))
13+
.build();
14+
```
15+
16+
If you don't, the driver uses a default configuration (see the javadocs of the setter methods of [SocketOptions] for the
17+
default values).
18+
19+
You can retrieve and change the options at runtime:
20+
21+
```java
22+
SocketOptions socketOptions = cluster.getConfiguration().getSocketOptions();
23+
socketOptions.setConnectTimeoutMillis(3000);
24+
```
25+
26+
* changes to the [read timeout](#driver-read-timeout) will be taken into account for future request executions;
27+
* changes to any other option will be taken into account for future connections (connections that were already opened at
28+
the time of the change are unaffected, they keep the old values).
29+
30+
### TCP options
31+
32+
[setConnectTimeoutMillis] defines how long the driver waits to establish a new connection to a Cassandra node before
33+
giving up.
34+
35+
Other options control the usual low-level TCP parameters (refer to their individual javadoc for details):
36+
[setKeepAlive], [setReceiveBufferSize], [setReuseAddress], [setSendBufferSize], [setSoLinger], [setTcpNoDelay]. Most of
37+
these options are not set explicitly by the driver, so they get the default value from the underlying TCP transport.
38+
One exception is `setTcpNoDelay`, which is forced to `true` (meaning that Nagle's algorithm is *disabled* for driver
39+
connections).
40+
41+
### Driver read timeout
42+
43+
[setReadTimeoutMillis] controls how long the driver waits for a response *from a given Cassandra node* before
44+
considering it unresponsive.
45+
46+
Cassandra normally provides a guaranteed response time for each type of query, as shown by these parameters in
47+
`cassandra.yaml` (here with their default values):
48+
49+
```yaml
50+
counter_write_request_timeout_in_ms: 5000
51+
range_request_timeout_in_ms: 10000
52+
read_request_timeout_in_ms: 5000
53+
request_timeout_in_ms: 10000
54+
truncate_request_timeout_in_ms: 60000
55+
write_request_timeout_in_ms: 2000
56+
```
57+
58+
The goal of `setReadTimeoutMillis` is to give up on a node if it took longer than these thresholds to reply, on the
59+
assumption that there's probably something wrong with it. Therefore it should be set **higher than the server-side
60+
timeouts**. The default value is **12 seconds** (lower than `truncate_request_timeout_in_ms`, but we consider `TRUNCATE`
61+
queries as maintenance operations that shouldn't be run from your application). Do not set it too low, or the driver
62+
might give up on requests that had a chance of succeeding.
63+
64+
If the timeout is reached, the driver will receive an `OperationTimedOutException` and retry the query on the next node
65+
in the [query plan](../load_balancing/#query-plan).
66+
67+
#### Limiting overall query time
68+
69+
It should be clear by now that `setReadTimeoutMillis` is *per node*, not per query. If the driver retries on 4 different
70+
nodes, the overall execution time could theoretically be up to 4 times the read timeout. If you want a per query timeout,
71+
use the following pattern:
72+
73+
```java
74+
import com.google.common.base.Throwables;
75+
76+
ResultSet execute(Statement statement, long timeout, TimeUnit unit)
77+
throws InterruptedException, TimeoutException {
78+
ResultSetFuture future = session.executeAsync(statement);
79+
try {
80+
return future.get(timeout, unit);
81+
} catch (ExecutionException e) {
82+
throw Throwables.propagate(e.getCause());
83+
} catch (TimeoutException e) {
84+
future.cancel(true);
85+
throw e;
86+
}
87+
}
88+
```
89+
90+
A complementary approach is to enable [speculative executions](../speculative_execution/), to have the driver query
91+
multiple nodes in parallel. This way you won't have to wait for the full timeout if the first node is unresponsive.
92+
93+
#### Driver read timeout vs. server read timeout
94+
95+
Unfortunately, the term "read timeout" clashes with another concept that is not directly related: a Cassandra node may
96+
reply with a `Read_timeout` error when it didn't hear back from enough replicas during a read query.
97+
98+
To clarify:
99+
100+
* **driver read timeout:** the driver did not receive any response from the current coordinator within
101+
`SocketOptions.setReadTimeoutMillis`. It retries the query on the next node.
102+
* **server read timeout:** the driver *did* receive a response, but that response indicates that the coordinator timed
103+
out while waiting for other replicas. It invokes [onReadTimeout] on the [retry policy](../retries/) to decide what to
104+
do.
105+
106+
We might rename `SocketOptions.setReadTimeoutMillis` in a future version to clear up any confusion.
107+
108+
[SocketOptions]: http://docs.datastax.com/en/drivers/java/2.1/com/datastax/driver/core/SocketOptions.html
109+
[setReadTimeoutMillis]: http://docs.datastax.com/en/drivers/java/2.1/com/datastax/driver/core/SocketOptions.html#setReadTimeoutMillis-int-
110+
[setConnectTimeoutMillis]: http://docs.datastax.com/en/drivers/java/2.1/com/datastax/driver/core/SocketOptions.html#setConnectTimeoutMillis-int-
111+
[setKeepAlive]: http://docs.datastax.com/en/drivers/java/2.1/com/datastax/driver/core/SocketOptions.html#setKeepAlive-boolean-
112+
[setReceiveBufferSize]: http://docs.datastax.com/en/drivers/java/2.1/com/datastax/driver/core/SocketOptions.html#setReceiveBufferSize-int-
113+
[setReuseAddress]: http://docs.datastax.com/en/drivers/java/2.1/com/datastax/driver/core/SocketOptions.html#setReuseAddress-boolean-
114+
[setSendBufferSize]: http://docs.datastax.com/en/drivers/java/2.1/com/datastax/driver/core/SocketOptions.html#setSendBufferSize-int-
115+
[setSoLinger]: http://docs.datastax.com/en/drivers/java/2.1/com/datastax/driver/core/SocketOptions.html#setSoLinger-int-
116+
[setTcpNoDelay]: http://docs.datastax.com/en/drivers/java/2.1/com/datastax/driver/core/SocketOptions.html#setTcpNoDelay-boolean-
117+
[onReadTimeout]: http://docs.datastax.com/en/drivers/java/2.1/com/datastax/driver/core/policies/RetryPolicy.html#onReadTimeout-com.datastax.driver.core.Statement-com.datastax.driver.core.ConsistencyLevel-int-int-boolean-int-

0 commit comments

Comments
 (0)