Dear wiki user, You have subscribed to a wiki page "Cassandra Wiki" for change notification.
The page ClientExamples has been reverted to revision 38 by gdusbabek. The comment on this change is: Python and Ruby examples were borked.. http://wiki.apache.org/cassandra/ClientExamples?action=diff&rev1=39&rev2=40 -------------------------------------------------- High level clients are available. Use one of these if you can. See the individual clients for documentation. - * Ruby: * http://github.com/fauna/cassandra/tree/master * http://github.com/NZKoz/cassandra_object/tree/master (for Rails) @@ -22, +21 @@ These examples are for Cassandra trunk, which will become 0.4. See ClientExamples03 for examples fitting the 03 API. == PHP == + Before working with Cassandra and PHP make sure that your [[http://us.php.net/manual/en/function.phpinfo.php|PHP installation]] has [[http://us.php.net/apc/|APC]] enabled. If it does not please re-compile [[http://us.php.net/manual/en/install.php|PHP]] and then recompile [[http://incubator.apache.org/thrift/|Thrift]]. [[http://us.php.net/apc/|APC]] drastically increases the performance of [[http://incubator.apache.org/thrift/|Thrift Interface]]. To create Cassandra.php and cassandra_types.php you must use thrift -gen php interface/cassandra.thrift of the cassandra package the rest of these files come from the main thrift package. - {{{ <?php $GLOBALS['THRIFT_ROOT'] = '/usr/share/php/Thrift'; @@ -43, +42 @@ $protocol = new TBinaryProtocol($transport); $client = new CassandraClient($protocol); $transport->open(); - - + + /* Insert some data into the Standard1 column family from the default config */ - + // Keyspace specified in storage=conf.xml $keyspace = 'Keyspace1'; - + // reference to specific User id $keyUserId = "1"; - + // Constructing the column path that we are adding information into. $columnPath = new cassandra_ColumnPath(); $columnPath->column_family = 'Standard1'; $columnPath->super_column = null; $columnPath->column = 'email'; - + // Timestamp for update $timestamp = time(); - + // We want the consistency level to be ZERO which means async operations on 1 node $consistency_level = cassandra_ConsistencyLevel::ZERO; - + - // Add the value to be written to the table, User Key, and path. + // Add the value to be written to the table, User Key, and path. $value = "[email protected]"; $client->insert($keyspace, $keyUserId, $columnPath, $value, $timestamp, $consistency_level); - // Add a new column path to be altered. + // Add a new column path to be altered. $columnPath->column = 'age'; //Get a current timestamp $timestamp = time(); @@ -77, +76 @@ $value = "24"; $client->insert($keyspace, $keyUserId, $columnPath, $value, $timestamp, $consistency_level); - /* + /* * use batch_insert to insert a supercolumn and its children using the standard config * builds the structure - * + * * Super1 : { * KeyName : { - * SuperColumnName : { + * SuperColumnName : { - * foo : fooey value + * foo : fooey value - * bar : bar like thing + * bar : bar like thing * } - * } + * } * } */ @@ -106, +105 @@ $super_column = new cassandra_SuperColumn(); $super_column->name = 'SuperColumnName'; $super_column->columns = array($column1, $column2); - + // create columnorsupercolumn holder class that batch_insert uses $c_or_sc = new cassandra_ColumnOrSuperColumn(); $c_or_sc->super_column = $super_column; - + - // create the mutation (a map of ColumnFamily names to lists ColumnsOrSuperColumns objects + // create the mutation (a map of ColumnFamily names to lists ColumnsOrSuperColumns objects $mutation['Super1'] = array($c_or_sc); $client->batch_insert($keyspace, 'KeyName', $mutation, $consistency_level); - + /* Query for data */ // Specify what Column Family to query against. @@ -142, +141 @@ print_r($result); $transport->close(); - + } catch (TException $tx) { print 'TException: '.$tx->why. ' Error: '.$tx->getMessage() . "\n"; } ?> }}} + == Java == {{{ import java.util.List; @@ -206, +206 @@ } } }}} - Alternatively, there is a Java "Fat Client" that can be used to bring up a node in client-only mode. A client node may participate in reads or writes and has the added benefit of avoid thrift-related overhead. The following example comes from /contrib/client_only: - - Writing - {{{ - StorageService.instance().initClient(); - // sleep for a bit so that gossip can do its thing. - try - { - Thread.sleep(10000L); - } - catch (Exception ex) - { - } - - // do some writing. - for (int i = 0; i < 100; i++) - { - RowMutation change = new RowMutation("Keyspace1", "key" + i); - ColumnPath cp = new ColumnPath("Standard1", null, ("colb").getBytes()); - change.add(new QueryPath(cp), ("value" + i).getBytes(), 0); - - // don't call change.apply(). The reason is that is makes a static call into Table, which will perform - // local storage initialization, which creates local directories. - // change.apply(); - - StorageProxy.insert(change); - try - { - Thread.sleep(50L); - } - catch (Exception ex) - { - } - System.out.println("wrote key" + i); - } - System.out.println("Done writing."); - StorageService.instance().stopClient(); - }}} - - Reading - {{{ - StorageService.instance().initClient(); - // sleep for a bit so that gossip can do its thing. - try - { - Thread.sleep(10000L); - } - catch (Exception ex) - { - } - - // do some queries. - Collection<byte[]> cols = new ArrayList<byte[]>() - {{ - add("colb".getBytes()); - }}; - for (int i = 0; i < 100; i++) - { - List<ReadCommand> commands = new ArrayList<ReadCommand>(); - SliceByNamesReadCommand readCommand = new SliceByNamesReadCommand("Keyspace1", "key" + i, new QueryPath("Standard1", null, null), cols); - readCommand.setDigestQuery(false); - commands.add(readCommand); - try - { - List<Row> rows = StorageProxy.readProtocol(commands, ConsistencyLevel.ONE); - assert rows.size() == 1; - Row row = rows.get(0); - ColumnFamily cf = row.cf; - if (cf != null) - { - for (IColumn col : cf.getSortedColumns()) - { - System.out.println(new String(col.name()) + ", " + new String(col.value())); - } - } - else - System.err.println("This output indicates that nothing was read."); - } - catch (UnavailableException e) - { - throw new RuntimeException(e); - } - catch (TimedOutException e) - { - throw new RuntimeException(e); - } - - } - - // no need to do this: - // StorageService.instance().decommission(); - // do this instead: - StorageService.instance().stopClient(); - }}} - A caveat of doing things this way is that a client cannot go up and down, and then up again without shutting down the entire VM. I.e., you can't initClient(), stopClient() and then initClient() again. == Ruby == + Install the Thrift gem that will take advantage of the native libraries (previously installed. Reference [[http://chrischandler.name/ruby/using-cassandras-thrift-interface-with-ruby/|Using Cassandra's Thrift Interface with Ruby]]) `shell> sudo gem install thrift` @@ -311, +217 @@ `shell> thrift --gen rb:new_style cassandra.thrift` - {{{#!/usr/bin/env ruby require './cassandra' require './cassandra_constants' require './cassandra_types' require 'pp' + {{{ + #!/usr/bin/env ruby + require './cassandra' + require './cassandra_constants' + require './cassandra_types' + require 'pp' - transport = Thrift::BufferedTransport.new(Thrift::Socket.new("localhost", "9160")) transport.open + transport = Thrift::BufferedTransport.new(Thrift::Socket.new("localhost", "9160")) + transport.open client = CassandraThrift::Cassandra::Client.new(Thrift::BinaryProtocol.new(transport)) - keyspace = "Keyspace1" key = "dude_login" columnPath = CassandraThrift::ColumnPath.new(:column_family => "Standard1", :column => "email") value = " [email protected] " t = Time.now timestamp = t.to_i * 1_000_000 + t.usec + keyspace = "Keyspace1" + key = "dude_login" + columnPath = CassandraThrift::ColumnPath.new(:column_family => "Standard1", :column => "email") + value = "[email protected]" + t = Time.now + timestamp = t.to_i * 1_000_000 + t.usec client.insert(keyspace, key ,columnPath, value, timestamp, CassandraThrift::ConsistencyLevel::ZERO) begin - - . pp client.get(keyspace, key, columnPath, CassandraThrift::ConsistencyLevel::ONE) + pp client.get(keyspace, key, columnPath, CassandraThrift::ConsistencyLevel::ONE) - rescue CassandraThrift::NotFoundException => e - - . puts "Key not found." + puts "Key not found." - - end }}} + end + }}} == Python == - {{{#!/usr/bin/env python # encoding: utf-8 """ Sample Cassandra Client + {{{ + #!/usr/bin/env python + # encoding: utf-8 + """ + Sample Cassandra Client - Created by Chris Goffinet on 2009-08-26. """ from thrift import Thrift from thrift.transport import TTransport from thrift.transport import TSocket from thrift.protocol.TBinaryProtocol import TBinaryProtocolAccelerated from cassandra import Cassandra from cassandra.ttypes import * import time, pprint + Created by Chris Goffinet on 2009-08-26. + """ + from thrift import Thrift + from thrift.transport import TTransport + from thrift.transport import TSocket + from thrift.protocol.TBinaryProtocol import TBinaryProtocolAccelerated + from cassandra import Cassandra + from cassandra.ttypes import * + import time, pprint def main(): + socket = TSocket.TSocket("localhost", 9160) + transport = TTransport.TBufferedTransport(socket) + protocol = TBinaryProtocol.TBinaryProtocolAccelerated(transport) + client = Cassandra.Client(protocol) + pp = pprint.PrettyPrinter(indent = 2) - . socket = TSocket.TSocket("localhost", 9160) transport = TTransport.TBufferedTransport(socket) protocol = TBinaryProtocol.TBinaryProtocolAccelerated(transport) client = Cassandra.Client(protocol) - pp = pprint.PrettyPrinter(indent = 2) keyspace = "Keyspace1" - column_path = ColumnPath(column_family="Standard1",column="email") key = "1" value = " [email protected] " timestamp = time.time() try: + keyspace = "Keyspace1" + column_path = ColumnPath(column_family="Standard1",column="email") + key = "1" + value = "[email protected]" + timestamp = time.time() + + try: + transport.open() - . transport.open() """ Insert the data into Keyspace 1 """ + """ Insert the data into Keyspace 1 """ - client.insert(keyspace, key, column_path, value, timestamp, ConsistencyLevel.ZERO); """" Query for data """ + client.insert(keyspace, key, column_path, value, timestamp, ConsistencyLevel.ZERO); - column_parent = ColumnParent(column_family="Standard1") slice_range = SliceRange(start="", finish="") predicate = SlicePredicate(slice_range=slice_range) + + """" Query for data """ + column_parent = ColumnParent(column_family="Standard1") + slice_range = SliceRange(start="", finish="") + predicate = SlicePredicate(slice_range=slice_range) + - result = client.get_slice(keyspace, key, column_parent, predicate, ConsistencyLevel.ONE); pp.pprint(result) + result = client.get_slice(keyspace, key, column_parent, predicate, ConsistencyLevel.ONE); + pp.pprint(result) + - . except Thrift.TException, tx: + except Thrift.TException, tx: - . print 'Thrift: %s' % tx.message + print 'Thrift: %s' % tx.message - . finally: + finally: - . transport.close() + transport.close() if __name__ == '__main__': - - . main() + main() - }}} == C# == @@ -375, +316 @@ TTransport transport = new TSocket("localhost", 9160); TProtocol protocol = new TBinaryProtocol(transport); Cassandra.Client client = new Cassandra.Client(protocol); - + Console.WriteLine("Opening connection"); transport.Open(); System.Text.Encoding utf8Encoding = System.Text.Encoding.UTF8; long timeStamp = DateTime.Now.Millisecond; - ColumnPath nameColumnPath = new ColumnPath() + ColumnPath nameColumnPath = new ColumnPath() - { + { - Column_family = "Standard1", + Column_family = "Standard1", Column = utf8Encoding.GetBytes("name") }; @@ -419, +360 @@ Slice_range = new SliceRange() { //Start and Finish cannot be null - Start = new byte[0], + Start = new byte[0], Finish = new byte[0], Count = 10, Reversed = false @@ -427, +368 @@ }; ColumnParent parent = new ColumnParent() { Column_family = "Standard1" }; - Dictionary<string , List<ColumnOrSuperColumn>> results = client.multiget_slice("Keyspace1", + Dictionary<string , List<ColumnOrSuperColumn>> results = client.multiget_slice("Keyspace1", - new List<string>() { "1", "2"}, + new List<string>() { "1", "2"}, - parent, + parent, - predicate, + predicate, ConsistencyLevel.ONE); foreach (KeyValuePair<string, List<ColumnOrSuperColumn>> resultPair in results) @@ -450, +391 @@ } } }}} + == Notes == + The Cassandra.Client object is always sending its request to the same Cassandra node in the cluster. The server then determines if and where the request should be routed to (Server-based routing). DNS Round Robin or a Cassandra.Client object pool connected to several servers in the cluster can be used to get higher throughput and availability. The get_string_property() method can be used to retrieve the active node list: - {{{ String jsonServerList = client.get_string_property("token map") }}} + The Cassandra.Client object cannot be used concurrently by multiple threads (not thread safe). Each thread must use their own Cassandra.Client object.
