The native protocol defines the format of the binary messages exchanged between the driver and Cassandra over TCP. As a driver user, you don't need to know the fine details (although the protocol spec is in the Cassandra codebase if you're curious); the most visible aspect is that some features are only available with specific protocol versions.
By default, the protocol version is negotiated between the driver and Cassandra when the first connection is established. Both sides are backward-compatible with older versions:
Cassandra: 1.2.x (DSE 3.2) | 2.0.x (DSE 4.0 to 4.6) | 2.1.x (DSE 4.7) | 2.2.x | 3.0.x | |
Driver: 1.0.x | v1 | v1 | v1 | v1 | Unsupported (1) |
2.0.x to 2.1.1 | v1 | v2 | v2 | v2 | Unsupported (1) |
2.1.2 to 2.1.x | v1 | v2 | v3 | v3 | Unsupported (2) |
3.x | v1 | v2 | v3 | v4 | v4 |
(1) Cassandra 3.0 does not support protocol versions v1 and v2
(2) There is a matching protocol version (v3), but the driver 2.1.x can't read the new system table format of Cassandra 3.0
For example, if you use version 2.1.5 of the driver to connect to Cassandra 2.0.9, the maximum version you can use (and the one you'll get by default) is protocol v2 (third row, second column). If you use the same version to connect to Cassandra 2.1.4, you can use protocol v3.
To find out which version you're currently using, use ProtocolOptions#getProtocolVersion():
ProtocolVersion myCurrentVersion = cluster.getConfiguration()
.getProtocolOptions()
.getProtocolVersion();
The protocol version can not be changed at runtime. However, you can force a given version at initialization:
Cluster cluster = Cluster.builder()
.addContactPoint("127.0.0.1")
.withProtocolVersion(ProtocolVersion.V2)
.build();
If you specify a version that is not compatible with your current driver/Cassandra combination, you'll get an error:
Exception in thread "main" com.datastax.driver.core.exceptions.NoHostAvailableException:
All host(s) tried for query failed
(tried: /127.0.0.1:9042 (com.datastax.driver.core.UnsupportedProtocolVersionException:
[/127.0.0.1:9042] Host /127.0.0.1:9042 does not support protocol version V3 but V2))
If you have a cluster with mixed versions (for example, while doing a rolling upgrade of Cassandra), note that the protocol version will be negotiated with the first host the driver connects to.
This could lead to the following situation (assuming you use driver 2.1.2+):
- the first contact point is a 2.1 host, so the driver negotiates protocol v3;
- while connecting to the rest of the cluster, the driver contacts a 2.0 host using protocol v3, which fails; an error is logged and this host will be permanently ignored.
To avoid this issue, you can use one the following workarounds:
- always force a protocol version at startup. You keep it at v2 while the rolling upgrade is happening, and only switch to v3 when the whole cluster has switched to Cassandra 2.1;
- ensure that the list of initial contact points only contains hosts with the oldest version (2.0 in this example).
- bound variables in simple statements (Session#execute(String, Object...))
- batch statements
- query paging
- the number of stream ids per connection goes from 128 to 32768 (see Connection pooling)
- serial consistency on batch statements
- client-side timestamps
- query warnings
- allowed unset values in bound statements
- Custom payloads