Skip to content

Getting started with CQL

Pierre Laporte edited this page Jul 12, 2018 · 2 revisions

Simple DSE simulation

Your simulation will need to contain three different sections: 1. open a connection to your DSE cluster 2. define your workload like you would in any other Gatling scenario 3. instruct Gatling to close the connection once the scenario is done

Here is a complete Gatling simulation that sends CQL queries during 10 seconds.

import com.datastax.driver.core.PreparedStatement
import com.datastax.driver.dse.{DseCluster, DseSession}
import com.datastax.gatling.plugin.DsePredef._ //(1)
import io.gatling.core.Predef._
import io.gatling.core.scenario.Simulation

import scala.concurrent.duration._

class SimpleDseSimulation extends Simulation {
  private val cluster: DseCluster = DseCluster //(2)
    .builder()
    .addContactPoint("127.0.0.1")
    .build()
  private val session: DseSession = cluster.connect()
  private val statement: PreparedStatement =
    session.prepare("SELECT now() from system.local") //(3)

  val scn = scenario("CQL")
    .exec(cql("Select date").executeNamed(statement)) //(4)

  setUp(scn.inject(constantUsersPerSec(1).during(10 seconds)) //(5)
    .protocols(dseProtocolBuilder.session(session)))

  after(cluster.close()) //(6)
}
  1. Import predefined functions that extend Gatling DSL for CQL queries

  2. Connect to the DSE cluster like in any application

  3. Prepare a CQL statement

  4. Define the user workload as a single execution of the prepared statement

  5. Configure throughput like in any other Gatling test

  6. Instruct Gatling to close the connection when it completes

CQL simulation without prepared statements

One of the performance best practices is to always use prepared statements. The previous example used that kind of statements.

However, in rare cases, you may want to use raw CQL string statements. These are supported by the plugin DSL just like prepared statement. Simply replace the workload definition block by the following:

  val scn = scenario("CQL")
    .exec(cql("Select date")
      .executeStatement("SELECT now() from system.local"))

Alternatively, you can explicitly instantiate a SimpleStatement.

  private val statement = new SimpleStatement("SELECT now() from system.local")

  val scn = scenario("CQL")
    .exec(cql("Select date").executeStatement(statement))

CQL simulation with parameters

The previous examples covered queries without any parameter. In most cases, there will be at least one parameter. The value for that parameter will be generated by a feeder. It will be different for each query.

In this case, use a feeder that holds values for each parameter. Note that the parameter names must match exactly what is used in the query. When this is the case, using executeNamed() as before is the way to go.

import com.datastax.driver.core.PreparedStatement
import com.datastax.driver.dse.{DseCluster, DseSession}
import com.datastax.gatling.plugin.DsePredef._
import io.gatling.core.Predef._
import io.gatling.core.scenario.Simulation

import scala.concurrent.duration._

class SimpleDseSimulation extends Simulation {
  private val cluster: DseCluster = DseCluster
    .builder()
    .addContactPoint("127.0.0.1")
    .build()
  private val session: DseSession = cluster.connect()
  private val statement: PreparedStatement = session.prepare(
    "SELECT * FROM ks1.table1 WHERE foo=:foo AND bar=:bar")

  val feeder = csv("foo.csv")

  val scn = scenario("CQL")
    .feed(feeder)
    .exec(cql("Select peer").executeNamed(statement))

  setUp(scn.inject(constantUsersPerSec(1).during(10 seconds))
    .protocols(dseProtocolBuilder.session(session)))

  after(cluster.close())
}

CQL simulations with batch statements

In some cases, you may want to benchmark DSE with batch statements. In the DSE plugin, a batch statement is simply a list of prepared statements. Just like regular prepared statements, you may use named parameters.

Keep in mind that values from feeders will be pulled only once per batch. It is useful if a parameter like customerId is used in several queries.

Note
Misused batch statements are one of the most common C* anti-patterns. You may want to verify that your use is valid.
import com.datastax.driver.core.PreparedStatement
import com.datastax.driver.dse.{DseCluster, DseSession}
import com.datastax.gatling.plugin.DsePredef._
import io.gatling.core.Predef._
import io.gatling.core.scenario.Simulation

import scala.concurrent.duration._

class SimpleDseSimulation extends Simulation {
  private val cluster: DseCluster = DseCluster
    .builder()
    .addContactPoint("127.0.0.1")
    .build()
  private val session: DseSession = cluster.connect()
  private val statement1: PreparedStatement = ???
  private val statement2: PreparedStatement = ???
  private val statement3: PreparedStatement = ???

  val feeder = ???

  val scn = scenario("CQL")
    .feed(feeder)
    .exec(cql("Run batch statement")
      .executePreparedBatch(Array(statement1, statement2, statement3)))

  setUp(scn.inject(constantUsersPerSec(1).during(10 seconds))
    .protocols(dseProtocolBuilder.session(session)))

  after(cluster.close())
}