TokenAware policy Cassandra and several node in one query

Viewed 129

What happens if our query contains several tokens that finally there on different nodes? Are possible that the client runs multiple queries Sync or Async on nodes?

sample:

//Our query
SELECT * FROM keyspace1.standard1 WHERE key = 1 or key = 2 or key = 3;

//Client change our query to multiple queries depends on the token ranges and run them sync or async.
SELECT * FROM keyspace1.standrad1 WHERE key = 1 or key = 3; //Token On node X
SELECT * FROM keyspace1.standard1 WHERE key = 3; //token On node Y

Sample2:

 //Our Query
 SELECT * FROM kspc.standard1;

 //Client Change our query to multiple queries on the token ranges and run them sync or async. 
 SELECT * FROM kspc.standard1 WHERE token(key) > [start range node1] and token(key) < [end range node1]; 
 SELECT * FROM kspc.standard1 WHERE token(key) > [start range node2] and token(key) < [end range node2]; 
 and ...
2 Answers

As Manish mentioned, if query contains several partitions then token aware policy won't select anything and will send query to any node in the cluster (the same behaviour is for unpreparred queries and DDLs). And in general, it's an anti-pattern as it put more load onto the nodes, so it should be avoided. But if you really need, then you can force driver to send query to one of the nodes that owns a specific partition key. In Java driver 3.x there was a function statement.setRoutingKey, for Java driver 4.x should be something similar. For other drivers there should be similar stuff, but maybe not in all.

For second class of queries - it's the same, by default driver can't find to which node to send the query, and routing key should be set explicitly. But in general, full table scan could be tricky as you need to handle conditions on the lower & upper bounds, and you can't expect that token range starts exactly at lower bound - it could be a situations when token range starts near upper bound & ends slightly above the lower bound - and this is a typical error that I have seen regularly. If you interested, I have an example of how to perform full table scan using the Java (it uses the same algorithm as Spark Cassandra Connector and DSBulk) - the main part is this cycle over the available token ranges. But if you're looking into writing full table scan yourself, think about using the DSBulk parts as an SDK - you need to look onto partitioner module that was designed specifically for that.

For Sample 1, just query for single partition and merge results at the client end. This will be much faster. Datastax driver has token aware policy but it will only work when query refers to single partition.

You can refer this link.

For Sample 2, it is an anti pattern query and you cannot expect the client to do all the work for you. If you want to read complete table then you can use spark. Datastax provides spark-cassandra-connector which can provide somewhat same functionality which you have given. Here you can find description of spark-cassandra-connector.

Related