Dear Wiki user, You have subscribed to a wiki page or wiki category on "Cassandra Wiki" for change notification.
The "ClientExamples" page has been changed by MichaelPearson. The comment on this change is: Added PHP/Pandra to client examples. http://wiki.apache.org/cassandra/ClientExamples?action=diff&rev1=46&rev2=47 -------------------------------------------------- High level clients are available. These are often more convenient than raw Thrift, which has a certain lowest-common-denominator flavor to it, because that's what it does. But, it's good to understand the Thrift [[API]] to have an idea of what's going on under the hood. See the individual clients for their respective documentation. + * Ruby: * http://github.com/fauna/cassandra/tree/master * http://github.com/NZKoz/cassandra_object/tree/master (for Rails) @@ -16, +17 @@ * http://wiki.github.com/jboner/akka/ (Akka includes a Cassandra client but is more than that) * Java : * http://code.google.com/p/cassandra-java-client + * PHP : + * http://github.com/mjpearson/Pandra/tree/master The rest of this page shows examples of using the low-level [[http://incubator.apache.org/thrift/|Thrift]] interface. 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, +46 @@ $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, +80 @@ $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, +109 @@ $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, +145 @@ print_r($result); $transport->close(); - + } catch (TException $tx) { print 'TException: '.$tx->why. ' Error: '.$tx->getMessage() . "\n"; } ?> }}} - == Java == {{{ import java.util.List; @@ -207, +209 @@ } } }}} - In the trunk, 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. This is due to be released '''after''' version 0.5 (likely 0.9). The following example comes from /contrib/client_only: Writing + {{{ StorageService.instance().initClient(); // sleep for a bit so that gossip can do its thing. @@ -248, +250 @@ System.out.println("Done writing."); StorageService.instance().stopClient(); }}} - Reading + {{{ StorageService.instance().initClient(); // sleep for a bit so that gossip can do its thing. @@ -304, +306 @@ // 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` @@ -317, +317 @@ `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 = Thrift::BufferedTransport.new(Thrift::Socket.new("localhost", "9160")) transport.open - 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() - """ Insert the data into Keyspace 1 """ + . transport.open() """ Insert the data into Keyspace 1 """ + client.insert(keyspace, key, column_path, value, timestamp, ConsistencyLevel.ZERO); """" 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) - client.insert(keyspace, key, column_path, value, timestamp, ConsistencyLevel.ZERO); - - """" 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) - - 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# == @@ -416, +378 @@ 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") }; @@ -460, +422 @@ 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 @@ -468, +430 @@ }; 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) @@ -491, +453 @@ } } }}} - == 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.
