Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simplest way to insert data into a fresh Cassandra database using the Hector API?

I've followed numerous examples on inserting data into a Cassandra database and every time I get an exception about unconfigured column families.

Exception in thread "main" me.prettyprint.hector.api.exceptions.HInvalidRequestException: InvalidRequestException(why:unconfigured columnfamily TestColumnFamily)
    at me.prettyprint.cassandra.service.ExceptionsTranslatorImpl.translate(ExceptionsTranslatorImpl.java:45)
    at me.prettyprint.cassandra.connection.HConnectionManager.operateWithFailover(HConnectionManager.java:252)
    at me.prettyprint.cassandra.model.ExecutingKeyspace.doExecuteOperation(ExecutingKeyspace.java:97)
    at me.prettyprint.cassandra.model.MutatorImpl.execute(MutatorImpl.java:243)
    at me.prettyprint.cassandra.model.MutatorImpl.insert(MutatorImpl.java:69)
    at CassandraInterface.main(CassandraInterface.java:101)
Caused by: InvalidRequestException(why:unconfigured columnfamily TestColumnFamily)
    at org.apache.cassandra.thrift.Cassandra$batch_mutate_result.read(Cassandra.java:19477)
    at org.apache.cassandra.thrift.Cassandra$Client.recv_batch_mutate(Cassandra.java:1035)
    at org.apache.cassandra.thrift.Cassandra$Client.batch_mutate(Cassandra.java:1009)
    at me.prettyprint.cassandra.model.MutatorImpl$3.execute(MutatorImpl.java:246)
    at me.prettyprint.cassandra.model.MutatorImpl$3.execute(MutatorImpl.java:243)
    at me.prettyprint.cassandra.service.Operation.executeAndSetResult(Operation.java:103)
    at me.prettyprint.cassandra.connection.HConnectionManager.operateWithFailover(HConnectionManager.java:246)
    ... 4 more

So I looked up how to configure them and found

    BasicColumnFamilyDefinition cfdef = new BasicColumnFamilyDefinition();
    cfdef.setKeyspaceName(keyspaceName);
    cfdef.setName(columnFamilyName);
    cfdef.setKeyValidationClass(ComparatorType.UTF8TYPE.getClassName());
    cfdef.setComparatorType(ComparatorType.UTF8TYPE);

That didn't configure the column family.

All of the examples I have found are fragments without any context, so I don't know what to import or set up. In addition, some examples appear to mix the Hector API v2 and the original Hector API, so when I use them, I get "class not found" or "function not found" compiler errors.

like image 998
user1258361 Avatar asked Oct 08 '22 03:10

user1258361


2 Answers

Hopefully you've been able to do this by now but this is how I've done it.

I have a cassandra install (using 1.1.4) and assuming you have all the necessary directories created:

/var/lib/cassandra
/var/lib/casandra/data
/var/lib/cassnadra/commitlogs
/var/lib/cassandra/saved_caches

I start it using:

bin/cassandra -f

I create a simple script called schema_create.txt:

CREATE KEYSPACE TEST
WITH strategy_class = 'org.apache.cassandra.locator.SimpleStrategy' AND strategy_options:replication_factor='1'; use TEST; CREATE COLUMNFAMILY TestColumnFamily( userid varchar, firstname varchar, lastname varchar, PRIMARY KEY (userid));

Then from the command line you can run this script using the new CQL tool that comes with cassandra as follows:

bin/cqlsh --cql3 < schema_createt.txt

This will install a keyspace named test with a column family named testcolumnfamily into cassandra.

Now from within your java application you can simply create a test class that has a main method (i will assume your development environment has all necessary dependencies if using maven):

try{ Mutator mutator = HFactory.createMutator(kweyspace, stringSerializer.get()); mutator.addInsertion("iamauser", "tescolumnfamily", HFactory.createStringColumn("firstname", "John")); mutator.addInsertion("iamauser", "testcolumnfamily", HFactory.createStringColumn("lastname", "Smith")); mutator.execute(); } catch(HectorException Hex){ Hex.printStackTrace(); } finally{ cluster.getConnectionManger().shutdown(); }

Now go back to the command line and enter into cassandra using:

$bin/cqlsh --cql3
use test;
select * from testcolumnfamily;

This will insert a row of data into your cassandra db with the key iamauser, and name as John Smith and you can verify as shown above using the cqlsh tool.

Hope this helps.

like image 37
Azkuma Avatar answered Oct 13 '22 11:10

Azkuma


Hector CassandraClusterTest.java

 @Test
 public void testAddDropColumnFamily() throws Exception {
      ColumnFamilyDefinition cfDef = HFactory.createColumnFamilyDefinition("Keyspace1", "DynCf");
      cassandraCluster.addColumnFamily(cfDef);
      String cfid2 = cassandraCluster.dropColumnFamily("Keyspace1", "DynCf");
      assertNotNull(cfid2);

      // Let's wait for agreement
      cassandraCluster.addColumnFamily(cfDef, true);
      cfid2 = cassandraCluster.dropColumnFamily("Keyspace1", "DynCf", true);
      assertNotNull(cfid2);
 }

Long story short, keyspace and column family need to exist before you try and insert data into them. You can either manage this in your code, to check to see if they exist, using the example above as a nice reference -- or modify via the command line interface (cassandra-cli)

Hector Unit Tests

like image 186
sdolgy Avatar answered Oct 13 '22 10:10

sdolgy