• You are here: 
  • Home
  • Chapter 2 The Cassandra CLI

Creating column familes with the CompositeType comparator

Posted on August 16th, 2011

(The High Performance Cassandra Cookbook was targeted on version 0.7.X, Composite types entered the Cassandra tree in version 0.8.1 and some minor changes were made in Cassandra to accommodate them)
CompositeTypes are an alternative to packing and serializing your own structures into cassandra’s columns. CompositeType allows a user to create a record which is a list of other Cassandra types such as UTF8Type or TimeUUID type. This recipe shows how to use the CompositeType information inside the comparators metadata.

How to do it…

Using the Cassandra CLI create a column family with a comparator specified as CompositeType that has two components which are UTF8 Strings.

[default@edstest] use edstest;
[default@edstest] create column family composite_test with comparator = ‘CompositeType(UTF8Type,UTF8Type)’;

You can insert into the composite type by using a : inside a single quoted string to separate the parts.

[default@edstest] set composite_test['a']['thing1:thing2']= ‘wow’;
Value inserted.
[default@edstest] get composite_test['a'];
=> (column=thing1:thing2, value=776f77, timestamp=1313540404197000)
Returned 1 results.

Create another composite column this time using UTF8Type and IntegerType. Then confirm that you can not insert data of the wrong type.

[default@edstest] create column family composite_test2 with comparator = ‘CompositeType(UTF8Type,IntegerType)’;
[default@edstest] set composite_test2 ['a']['thing:1']=’stuff’;
Value inserted.
[default@edstest] set composite_test2 ['a']['thing:z']=’stuff’;
org.apache.cassandra.db.marshal.MarshalException: unable to make int from ‘z’

[default@edstest] get composite_test2 ['a'];
=> (column=thing:1, value=7374756666, timestamp=1313540630087000)
Returned 1 results.

How it works…

Cassandra stores the CompositeType metadata. This information allows method such as get_slice to return data in a sorted order. This has an advantage over using a serialization method like JSON where Cassandra can only sort on the byte level, because it is unaware of the data’s structure.

There is more…

Composite columns may eventually replace ‘super column families’ in cassandra. This change should be transparent to end users of ‘super column families’ as far as the thrift API is concerned.

Tags: , ,
Filed under Chapter 2 The Cassandra CLI | 46 Comments »

Incrementing and Decrementing Counters from the CLI

Posted on August 7th, 2011

(Because the Cassandra High Performance Cookbook was based on the Cassandra 0.7.X series, counters were still under development as book was being written. )

How to do it…

Create a column family and set its default_validation_class to CounterColumnType. Refer to the chapter 2 recipe, Creating a column family from the CLI for more info.

[default@app] use app;
[default@app] create column family counters with default_validation_class=CounterColumnType and replicate_on_write=true;

Use the incr method increment the value of a column by 1.
[default@app] incr counterCF [ascii('a')][ascii('x')];
Value incremented.
[default@app] incr counterCF [ascii('a')][ascii('x')];
Value incremented.

retrieve the value using the standard get.
[default@app] get counterCF[ascii('a')];
=> (counter=78, value=2)
Returned 1 results.

Use the ‘by’ clause to increment counters by a specific number.
[default@app] incr counterCF [ascii('a')][ascii('x')] by 9;
Value incremented.
[default@app] get counterCF[ascii('a')];
=> (counter=78, value=11)
Returned 1 results.

Decrement the counter using the ‘decr’ statement.

[default@app] decr counterCF [ascii('a')][ascii('x')] ;
Value decremented.
[default@app] get counterCF[ascii('a')];
=> (counter=78, value=10)
Returned 1 results.
[default@app] decr counterCF [ascii('a')][ascii('x')] by 2;
Value decremented.
[default@app] get counterCF[ascii('a')];
=> (counter=78, value=8)
Returned 1 results.

Use a signed integer in the ‘by’ clause.

[default@app] decr counterCF [ascii('a')][ascii('x')] by -2;
Value decremented.
[default@app] get counterCF[ascii('a')];
=> (counter=78, value=10)
Returned 1 results.

How it works…

Counter columns are different then normal columns they can only hold an integer value. This value can be incremented or decremented without having to retrieve it’s current value from the server. This is important because reading before writing is a Cassandra anti-pattern and multiple clients can operate on a counter without having to synchronize externally.

See Also…

In Chapter 5 the CAP chapter the recipe, Demonstrating how consistency is not a
lock or a transaction , shows a situation where counters are needed. In chapter 10 Libraries and Applications the recipe Using Cages to implement an atomic read and set shows how to do counting with an external locking solution.

The Bonus recipe Using counters for real time statistical reporting.

Tags: , , ,
Filed under Chapter 2 The Cassandra CLI | 45 Comments »