Three simple rules for coding with the driver
When writing code that uses the driver, there are three simple rules that you should follow that make your code efficient:
- Only use one
Client
instance per keyspace or use a single Client and explicitly specify the keyspace in your queries and reuse it in across your modules in the application lifetime. - If you execute a statement more than once, use a prepared statement.
- You can reduce the number of network roundtrips and also have atomic operations by using batches.
Client
The Client
instance allows you to configure different important aspects of the way connections and queries are
handled. At this level, you can configure everything from contact points (address of the nodes to be contacted initially
before the driver performs node discovery), the request routing policy, retry and reconnection policies, and so on.
Generally such settings are set once at the application level.
const cassandra = require('cassandra-driver');
const DCAwareRoundRobinPolicy = cassandra.policies.loadBalancing.DCAwareRoundRobinPolicy;
const client = new cassandra.Client({
contactPoints: ['10.1.1.3', '10.1.1.4', '10.1.1.5'],
policies: {
loadBalancing: new DCAwareRoundRobinPolicy('US_EAST');
}
});
A Client
instance is a long-lived object, and it should not be used in a request-response, short-lived fashion.
Your code should share the same Client
instance across your application.
Prepared statements
Using prepared statements provides multiple benefits. A prepared statement is parsed and prepared on the Cassandra nodes and is ready for future execution. When binding parameters, only they (and the query id) are sent over the wire. These performance gains add up when using the same queries (with different parameters) repeatedly. Additionally, when preparing, the driver retrieves information about the parameter types which allows an accurate mapping between a JavaScript type and a CQL type.
Preparing and executing statements in the driver does not require two chained asynchronous calls. You can set the
prepare
flag in the query options and the driver handles the rest.
const query = 'SELECT id, name FROM users WHERE id = ?';
client.execute(query, [ id ], { prepare: true }, callback);
Batch statements
The batch statement combines multiple data modification statements (INSERT
, UPDATE
, or DELETE
) into a single logical
operation that is sent to the server in a single request. Batching together multiple operations also ensures that they
are executed in an atomic way, (that is, either all succeed or none). To make the best use of batch()
, read about
atomic batches in Cassandra 1.2 and static columns
and batching of conditional updates.
Starting with Cassandra 2.0, prepared statements can be used in batch operations.
const queries = [
{ query: 'UPDATE user_profiles SET email=? WHERE key=?',
params: [emailAddress, 'hendrix']},
{ query: 'INSERT INTO user_track (key, text, date) VALUES (?, ?, ?)',
params: ['hendrix', 'Changed email', new Date()]}
];
const queryOptions = { prepare: true, consistency: cassandra.types.consistencies.quorum };
client.batch(queries, queryOptions, function(err) {
assert.ifError(err);
console.log('Data updated on cluster');
});