Why should I worry about Cassandra Compaction ?


What is Cassandra Compaction ?

Compaction is a maintenance process which merges multiple SSTables to one new SSTable on disk.Compaction is done for two purposes –

  • Limit the number of SSTables to be looked at at the time of read operations. Cassandra allows multiple versions of a row exists in different SSTables. At read, different versions are read from different SSTables and merged into one. Compaction will reduce number of SSTables to be looked at and therefore improve read performance.
  • reclaim space taken by obsolete data/ Tombstones in SSTable.

It would helpful to understand how Cassandra handles commits to the datastore to understand why compaction is so important for Cassandra’s performance and health.

When writing to Cassandra, the following steps take place:

  1. The commit is logged to disk, in sequential manner, to a commit log entry, and inserted into an in-memory memtable table.
  2. Once the memtable reaches a limit on entries, it is flushed to disk
  3. Entries from the memtable being flushed are appended to a current SSTable for that column family
  4. If compaction thresholds are reached, a compaction is run.

After compaction, the old SSTables will be marked as obsolete. These SSTables are deleted asynchronously when JVM performs a GC, or when Cassandra restarts, whichever happens first. Cassandra may force a deletion if it detects disk space is running low.

Let’s practically understand when actually SSTables would be created and when compaction would be occuring.

  • Create a keyspace Test and a table compaction_test in it.Insert one row in it and update the same row.

cassandra@cqlsh> CREATE KEYSPACE Test WITH REPLICATION = { ‘class’ : ‘SimpleStrategy’, ‘replication_factor’ : 1 };
cassandra@cqlsh> use Test;
cassandra@cqlsh:test> create table compaction_test ( id int PRIMARY KEY,text1 varchar,text2 varchar);

cassandra@cqlsh:test> insert into compaction_test (id,text1,text2) values (1,’Test1′,’Test2′);
cassandra@cqlsh:test> update compaction_test set text2=’Test3′ where id = 1;

Till this point no SSTable would be created in data directory.

  • Now when we will run below command, data from memtable would be flushed to disk in the form of SSTable –

nodetool flush

  • At this point check the SSTable using below command –

sstable2json <data file>

compact4

  • Now again update the same row.

cassandra@cqlsh:test> update compaction_test set text2=’Test4′ where id = 1;

  • And again run the below nodetool command.

nodetool flush

This would create another SSTable. Now introspect this new SSTable using same “sstable2json <data file>” command.

compact5

So if we look carefully at above screenshot it clearly shows that some part of single partition is in 1st SSTable (id and text1 columns with stale value of text2 column) and some part (latest value of text2) in 2nd SSTable.So when read operation would come it will look in both the SSTables to fetch the latest values.

And that’s where Compaction is important in Cassandra.When compaction will run it will consolidate both the SSTables into one.

  • Run the below command to run the compaction manually

nodetool compact

Before compaction

compact9

After compaction

compact8

  • Again analyse the new SSTable created using same “sstable2json <data file>” command.

compact10

Now you will see that data for same partition is in single SSTable which gives two main advantages –

  1. Read operation will be faster, as now it would look in single SSTable.
  2. Disk utilization would be improved (This depends upon Compaction strategy as well, which would be covered in future blog entries).
Advertisements