I am trying to experiment with lightweight transactions in Cassandra by using SERIAL consistency. However, trying to set the consistency level in cqlsh results in an error:
cqlsh:learning> CONSISTENCY SERIAL;
Improper CONSISTENCY command.
The WITH CONSISTENCY statement has been removed from CQL and so I cannot use that. Is there a way to enable serial consistency from cqlsh? Or do I have to do it using a driver?
The CONSISTENCY command should still work in cqlsh. But valid values for this setting are:
ANY
ONE
TWO
THREE
QUORUM
ALL
LOCAL_QUORUM
EACH_QUORUM
SERIAL is not in that list, hence the error you are seeing. There is an open Jira ticket to address this: CASSANDRA-8051
This appears to be a consistency level that has some restrictions around it, thus making this difficult to implement. The Consistency Level descriptions indicate that:
You cannot configure this level as a normal consistency level,
configured at the driver level using the consistency level field.
The Java Driver apparently has a specific method to set this consistency level:
The serial consistency level of the query, set with
Statement.setSerialConsistencyLevel(), is similar to the consistency
level, but only used in queries that have conditional updates. That
is, it is only used in queries that have the equivalent of the IF
condition in CQL.
Related
Can someone help me on how to set consistency level separately for read and write in cassandra (cqlsh)
and one more question can we set consistency level for a keyspace?
please explain
Yes, you can set consistency level other then your default consistency level. (which you have defined while building your cluster object).
Here is the example of setting consistency level to your prepared statement.
session.prepare(<Query>).setConsistencyLevel(<consistency_level>)
If you are using JAVA driver, you can explore the enum class ConsistencyLevel defined in the datastax driver library.
import com.datastax.driver.core.ConsistencyLevel.{consistency_level}
This link might help you dmlConfigConsistency
For setting this in cqlsh you need to issue corresponding CONSISTENCY command before executing the specific query, like this:
CONSISTENCY QUORUM;
INSERT INTO ... ;
Setting the consistency level for "class" of queries is impossible in cqlsh...
You can set consistency after login CQLSH like below for read and write.
CONSISTENCY ONE/TWO; etc
https://docs.datastax.com/en/cql/3.3/cql/cql_reference/cqlshConsistency.html
Also,you can refer below for setting a Consistency Level with Prepared Statements
https://datastax.github.io/python-driver/getting_started.html
According to docs from datastax, it's good to use the cqlsh CONSISTENCY command to set the consistency level to ALL. I saw same recommendation from many other places. But why should we do that? Especially, in native protocol specification from apache-cassandra, it seems truncate query would ignore the consistency we set before.
The truncate command requires all nodes up and it will fail preemptively if anything is down regardless of consistency level. You are right that you don't need to do that.
Also CQL truncate no longer uses JMX at all (blurb at bottom), that was from thrift days before cql3 so it might be just old documentation that hasn't been updated.
I have an application that perform only inserts/deletes in cassandra. All write operations (inserts/deletes) application perform using consistency level QUORUM, read operation currently is executed using QUORUM as well, but i`m wondering if in this case (when there is no updates to data) consistency level ONE would give same results as QUORUM.
Not necessarily. It could be that your read request goes to the one node which has not (yet) received/applied the updates. The QUORUM consistency level does allow for some nodes to not have the updated data just yet; by using a consistency level of ONE for your read, you might read stale data. Perhaps your application can deal with this situation -- that's for you to decide. But you should know that a consistency level of ONE for reads may not return the data you expect in your situation.
Hope this helps!
I can not find the documentation for this. I know there is a consistency command in cqlsh, but there is no distinction between read and write consistency. How would I set different consistency levels for read and write?
Furthermore, there is a mention of a "default" consistency level. Where is that default set? and is it for read or write?
How would I set different consistency levels for read and write?
If you just want to change consistency level for your current session, use CONSISTENCY.
If you want to change the consistency level programamtically, use the cassandra driver for your client language.
Since the Consistency Level can be set per-statement, you can either set it on every statement, or use PreparedStatements. If you're using the Java driver, you can configure a global Consistency level for BOTH reads and writes (but not only reads and only writes).
Where is that default [consistency level] set? and is it for read or write?
If you want to set up a different consistency level for reads than writes, you'll have to do it on a per-statement basis. Use QueryOptions().setConsistencyLevel to set a global consistency level (for the Java driver). It is for BOTH reads and writes.
To set the consistency level for your current session, use the CONSISTENCY command
from the cassandra shell (CQLSH).
For example:
Set CONSISTENCY to force the majority of the nodes to respond:
CONSISTENCY QUORUM
To see your current consistency level, just run CONSISTENCY; from the shell:
ty#cqlsh> consistency;
Current consistency level is ONE.
For programming client applications, set the consistency level using an appropriate driver.
To set a per-insert consistency level using the Java driver, for example, call QueryBuilder.insertInto with setConsistencyLevel.
For example:
PreparedStatement pstmt = session.prepare(
"INSERT INTO product (sku, description) VALUES (?, ?)");
pstmt.setConsistencyLevel(ConsistencyLevel.QUORUM);
To set a global consistency level for reads AND writes using the Java driver, do something like:
QueryOptions qo = new QueryOptions().setConsistencyLevel(ConsistencyLevel.ALL);
Since the Java driver only executes CQL statements, which can be either reads or writes to Cassandra, it is not possible to globally configure the Consistency Level for only reads or only writes. To do so, since the Consistency Level can be set per-statement, you can either set it on every statement, or use PreparedStatements. More info in the Queries and Results document.
More resources on read/write consistency levels
How consistency level is configured
The different consistency levels are also explained here ^
Cassandra's Java Driver documentation
See the "Consistency levels" section in configuring consistency with the Java Driver
Other resources on consistency:
You may also want to look into your replica placement strategy and replication factor (which are other forms of consistency).
I included links below for good measure:
Background on data replication in Cassandra
How to update replica strategy and replication factor using CREATE KEYSPACE
How consistency affects performance
By default, the Consistency Level is ONE for all R/W Operations.
Setting CL is done on a per query (read or upsert) basis by adding the CONSISTENCY XXXX syntax on the query as seen here:
https://cassandra.apache.org/doc/latest/cql/dml.html#insert
and
https://cassandra.apache.org/doc/4.0/tools/cqlsh.html
The consistency level is not set anymore with a CQL USING clause. See CASSANDRA-4734 for an explanation.
Instead, with CQLSH, you should use the CONSISTENCY command: see here for details.
Note that the default consistency level changed in all DataStax drivers from ONE to LOCAL_ONE: see the python driver documentation for details - however, in spite of using the python driver behind the scenes, CQLSH still has a default consistency of ONE).
The consisenty level is no longer set using PreparedStatement. That API was changed. Now you have to use BatchStatementBuilder.
Here is sample code that works.
BatchStatementBuilder builder = BatchStatement.builder(DefaultBatchType.UNLOGGED);
builder.setConsistencyLevel(ConsistencyLevel.LOCAL_QUORUM);
PreparedStatement preparedStatement = session.prepare("INSERT INTO \"ScottKeySpace16\".\"Movie\" (title, year, plot) values (:k0, :k1, :k2)");
builder.addStatement(preparedStatement.boundStatementBuilder()
.setString("k0", "Movie44")
.setInt("k1", 2022)
.setString("k2", "This is a very funny movie")
.build());
BatchStatement batchStatement = builder.build();
session.execute(batchStatement);
Default consistency is set in cassandra.conf file . It is for read and write .
You can set consistency per query basis adding USING option in query .
In the earlier beta releases of CQL, there was a command I could use to set the read / write consistency of an individual CQL operation. It looked like this:
SELECT * FROM users WHERE state='TX' USING CONSISTENCY QUORUM;
I use CQL3 regularly and have a use-case where I need to be able to perform a read with a higher consistency level than the rest of our application.
I looked through the CQL3 reference and didn't find any mention of any CQL syntax that allows me to change the consistency settings on a per-query basis, unless I'm using cqlsh (not useful for application development.)
How am I supposed to tune the consistency on a per-request basis using CQL3?
First set the consistency by running command:
CONSISTENCY QUORUM;
and then then run you query:
SELECT * FROM users WHERE state='TX'
At any point you can check the consistency using:
CONSISTENCY;
Aaron, the Consistency Level is not needed to be set on the protocol level - for the reasons explained here: https://issues.apache.org/jira/browse/CASSANDRA-4734
The default consistency level for any query is "ONE". However, one can set the consistency level on query basis as below.
Based on the Replication factor, the location of the partition (nodes list) can be found as below.
nodetool getendpoints Keyspace-name table-name partition-key value
$ nodetool getendpoints stresstest status bill
10.134.38.15
10.134.38.24
10.134.38.26