+ All Categories
Home > Documents > Writing a cassandra Client with perl

Writing a cassandra Client with perl

Date post: 01-Jul-2015
Category:
Upload: stefano-rodighiero
View: 1,471 times
Download: 0 times
Share this document with a friend
64
Writing a Cassandra client in Perl
Transcript
Page 1: Writing a cassandra Client with perl

Writing a Cassandra client in Perl

Page 2: Writing a cassandra Client with perl

Stefano [email protected]

Page 3: Writing a cassandra Client with perl

@larsen

Page 4: Writing a cassandra Client with perl

• High Write Throughput

• Large Tables

• Reports

• Analytics

Page 5: Writing a cassandra Client with perl

Cassandra

Page 6: Writing a cassandra Client with perl

Bigtable: A distributed storage system for structured data, 2006

Page 7: Writing a cassandra Client with perl

Dynamo: Amazon's highly available keyvalue

store, 2007

Page 8: Writing a cassandra Client with perl

Dynamo partitioning and

replication

Page 9: Writing a cassandra Client with perl

ColumnFamily data model similar

to Bigtable's

Page 10: Writing a cassandra Client with perl

High availability

Page 11: Writing a cassandra Client with perl

Incremental scalability

Page 12: Writing a cassandra Client with perl

Eventually consistent

Page 13: Writing a cassandra Client with perl

Tunable tradeoffs between consistency

and latency

Page 14: Writing a cassandra Client with perl

Minimal administration

Page 15: Writing a cassandra Client with perl

(not quite so)

Page 16: Writing a cassandra Client with perl

No SPOFp2p distribution model

Page 17: Writing a cassandra Client with perl
Page 18: Writing a cassandra Client with perl
Page 19: Writing a cassandra Client with perl
Page 20: Writing a cassandra Client with perl
Page 21: Writing a cassandra Client with perl

Writing

Page 22: Writing a cassandra Client with perl

Writinginsert(key,  {column_name  =>  value})

Page 23: Writing a cassandra Client with perl

Writing

R

Page 24: Writing a cassandra Client with perl

Writing

R

Page 25: Writing a cassandra Client with perl

Writing

17%

17%

17% 17%R

Page 26: Writing a cassandra Client with perl

Writing

R

Page 27: Writing a cassandra Client with perl

Writing

R

Page 28: Writing a cassandra Client with perl

Writing a Cassandra client in Perl

Page 29: Writing a cassandra Client with perl

Talking with a server

Page 30: Writing a cassandra Client with perl

Cassandra::CassandraClient

Thrift::BinaryProtocol

Thrift::FramedTransport

Thrift::Socket

Page 31: Writing a cassandra Client with perl

Cassandra::CassandraClient

Thrift::BinaryProtocol

Thrift::FramedTransport

Thrift::Socket

Page 32: Writing a cassandra Client with perl

Cassandra::CassandraClient

Thrift::BinaryProtocol

Thrift::FramedTransport

The Transport layer provides a simple abstraction for reading/writing from/to the network. This enables Thrift to decouple the underlying transport from the rest of the system (serialization/deserialization, for instance).

Page 33: Writing a cassandra Client with perl

Cassandra::CassandraClient

Thrift::BinaryProtocolThe Protocol abstraction defines a mechanism to map in-memory data structures to a wire-format. In other words, a protocol specifies how datatypes use the underlying Transport to encode/decode themselves.

Page 34: Writing a cassandra Client with perl

Cassandra::CassandraClient"High level" interface: login, reading & writing data, …

Page 35: Writing a cassandra Client with perl

1) Install Cassandra2) Install Thrift

Page 36: Writing a cassandra Client with perl

thrift  -­‐gen  perl  cassandra.thrift

Page 37: Writing a cassandra Client with perl

Login

Page 38: Writing a cassandra Client with perl

thriftservice  Cassandra  {    #  auth  methods    void  login(1:  required  AuthenticationRequest  auth_request)  i        throws  (1:AuthenticationException  authnx,                          2:AuthorizationException  authzx),    …

Perl (generated code)package  Cassandra::CassandraClient;…

sub  login{    my  $self  =  shift;    my  $auth_request  =  shift;

   $self-­‐>send_login($auth_request);    $self-­‐>recv_login();}

Page 39: Writing a cassandra Client with perl

thriftservice  Cassandra  {    #  auth  methods    void  login(1:  required  AuthenticationRequest  auth_request)  i        throws  (1:AuthenticationException  authnx,                          2:AuthorizationException  authzx),    …

Perl (generated code)package  Cassandra::CassandraClient;…

sub  login{    my  $self  =  shift;    my  $auth_request  =  shift;

   $self-­‐>send_login($auth_request);    $self-­‐>recv_login();}

thrift

Perl (generated code)

struct  AuthenticationRequest  {        1:  required  map<string,  string>  credentials}

package  Cassandra::AuthenticationRequest;use  base  qw(Class::Accessor);Cassandra::AuthenticationRequest-­‐>mk_accessors(  qw(  credentials  )  );

sub  new  {    …}

Page 40: Writing a cassandra Client with perl

my  $ks  =  'TestIPW';

my  $socket        =  Thrift::Socket-­‐>new($server_name,  $server_port);my  $transport  =  Thrift::FramedTransport-­‐>new($socket,  1024,  1024);my  $protocol    =  Thrift::BinaryProtocol-­‐>new($transport);$client              =  Cassandra::CassandraClient-­‐>new(  $protocol  );

eval  {        $transport-­‐>open;        my  $auth  =  Cassandra::AuthenticationRequest-­‐>new(            {  credentials  =>  {}  }        );        $client-­‐>login($auth);

       $client-­‐>set_keyspace($ks);};if  (  $@  )  {        die  Dumper(  $@  );}

Page 41: Writing a cassandra Client with perl

my  $ks  =  'TestIPW';

my  $socket        =  Thrift::Socket-­‐>new($server_name,  $server_port);my  $transport  =  Thrift::FramedTransport-­‐>new($socket,  1024,  1024);my  $protocol    =  Thrift::BinaryProtocol-­‐>new($transport);$client              =  Cassandra::CassandraClient-­‐>new(  $protocol  );

eval  {        $transport-­‐>open;        my  $auth  =  Cassandra::AuthenticationRequest-­‐>new(            {  credentials  =>  {}  }        );        $client-­‐>login($auth);

       $client-­‐>set_keyspace($ks);};if  (  $@  )  {        die  Dumper(  $@  );}

Cassandra::CassandraClient

Thrift::BinaryProtocol

Thrift::FramedTransport

Thrift::Socket

Page 42: Writing a cassandra Client with perl

my  $ks  =  'TestIPW';

my  $socket        =  Thrift::Socket-­‐>new($server_name,  $server_port);my  $transport  =  Thrift::FramedTransport-­‐>new($socket,  1024,  1024);my  $protocol    =  Thrift::BinaryProtocol-­‐>new($transport);$client              =  Cassandra::CassandraClient-­‐>new(  $protocol  );

eval  {        $transport-­‐>open;        my  $auth  =  Cassandra::AuthenticationRequest-­‐>new(            {  credentials  =>  {}  }        );        $client-­‐>login($auth);

       $client-­‐>set_keyspace($ks);};if  (  $@  )  {        die  Dumper(  $@  );}

thriftservice  Cassandra  {    #  auth  methods    void  login(1:  required  AuthenticationRequest  auth_request)  i        throws  (1:AuthenticationException  authnx,                          2:AuthorizationException  authzx),    …

Page 43: Writing a cassandra Client with perl

Reading

Page 44: Writing a cassandra Client with perl

thriftlist<ColumnOrSuperColumn>  get_slice(    1:required  binary  key,    2:required  ColumnParent  column_parent,    3:required  SlicePredicate  predicate,    4:required  ConsistencyLevel  consistency_level=ConsistencyLevel.ONE)  throws  (1:InvalidRequestException  ire,                    2:UnavailableException  ue,                    3:TimedOutException  te)

Perl (generated code)package  Cassandra::CassandraClient;…sub  get_slice{    my  $self  =  shift;    my  $key  =  shift;    my  $column_parent  =  shift;    my  $predicate  =  shift;    my  $consistency_level  =  shift;

   $self-­‐>send_get_slice($key,  $column_parent,  $predicate,  $consistency_level);    return  $self-­‐>recv_get_slice();}

Page 45: Writing a cassandra Client with perl

thriftlist<ColumnOrSuperColumn>  get_slice(    1:required  binary  key,    2:required  ColumnParent  column_parent,    3:required  SlicePredicate  predicate,    4:required  ConsistencyLevel  consistency_level=ConsistencyLevel.ONE)  throws  (1:InvalidRequestException  ire,                    2:UnavailableException  ue,                    3:TimedOutException  te)

Perl (generated code)package  Cassandra::CassandraClient;…sub  get_slice{    my  $self  =  shift;    my  $key  =  shift;    my  $column_parent  =  shift;    my  $predicate  =  shift;    my  $consistency_level  =  shift;

   $self-­‐>send_get_slice($key,  $column_parent,  $predicate,  $consistency_level);    return  $self-­‐>recv_get_slice();}

thrift

struct  ColumnParent  {        3:  required  string  column_family,        4:  optional  binary  super_column,}

Perl (generated code)

package  Cassandra::ColumnParent;use  base  qw(Class::Accessor);Cassandra::ColumnParent-­‐>mk_accessors(      qw(  column_family  super_column  )  );

Page 46: Writing a cassandra Client with perl

thriftlist<ColumnOrSuperColumn>  get_slice(    1:required  binary  key,    2:required  ColumnParent  column_parent,    3:required  SlicePredicate  predicate,    4:required  ConsistencyLevel  consistency_level=ConsistencyLevel.ONE)  throws  (1:InvalidRequestException  ire,                    2:UnavailableException  ue,                    3:TimedOutException  te)

Perl (generated code)package  Cassandra::CassandraClient;…sub  get_slice{    my  $self  =  shift;    my  $key  =  shift;    my  $column_parent  =  shift;    my  $predicate  =  shift;    my  $consistency_level  =  shift;

   $self-­‐>send_get_slice($key,  $column_parent,  $predicate,  $consistency_level);    return  $self-­‐>recv_get_slice();}

thrift

struct  SlicePredicate  {        1:  optional  list<binary>  column_names,        2:  optional  SliceRange      slice_range,}

Perl (generated code)

package  Cassandra::SlicePredicate;use  base  qw(Class::Accessor);Cassandra::SlicePredicate-­‐>mk_accessors(      qw(  column_names  slice_range  )  );

Page 47: Writing a cassandra Client with perl

thriftlist<ColumnOrSuperColumn>  get_slice(    1:required  binary  key,    2:required  ColumnParent  column_parent,    3:required  SlicePredicate  predicate,    4:required  ConsistencyLevel  consistency_level=ConsistencyLevel.ONE)  throws  (1:InvalidRequestException  ire,                    2:UnavailableException  ue,                    3:TimedOutException  te)

Perl (generated code)package  Cassandra::CassandraClient;…sub  get_slice{    my  $self  =  shift;    my  $key  =  shift;    my  $column_parent  =  shift;    my  $predicate  =  shift;    my  $consistency_level  =  shift;

   $self-­‐>send_get_slice($key,  $column_parent,  $predicate,  $consistency_level);    return  $self-­‐>recv_get_slice();}

thrift

struct  SliceRange  {        1:  required  binary  start,        2:  required  binary  finish,        3:  required  bool  reversed=0,        4:  required  i32  count=100,}

Perl (generated code)

package  Cassandra::SliceRange;use  base  qw(Class::Accessor);Cassandra::SliceRange-­‐>mk_accessors(      qw(  start  finish  reversed  count  )  );

Page 48: Writing a cassandra Client with perl

thriftlist<ColumnOrSuperColumn>  get_slice(    1:required  binary  key,    2:required  ColumnParent  column_parent,    3:required  SlicePredicate  predicate,    4:required  ConsistencyLevel  consistency_level=ConsistencyLevel.ONE)  throws  (1:InvalidRequestException  ire,                    2:UnavailableException  ue,                    3:TimedOutException  te)

Perl (generated code)package  Cassandra::CassandraClient;…sub  get_slice{    my  $self  =  shift;    my  $key  =  shift;    my  $column_parent  =  shift;    my  $predicate  =  shift;    my  $consistency_level  =  shift;

   $self-­‐>send_get_slice($key,  $column_parent,  $predicate,  $consistency_level);    return  $self-­‐>recv_get_slice();}

thriftenum  ConsistencyLevel  {        ONE  =  1,        QUORUM  =  2,        LOCAL_QUORUM  =  3,        EACH_QUORUM  =  4,        ALL  =  5,        ANY  =  6,        TWO  =  7,        THREE  =  8,}

Perl (generated code)

package  Cassandra::ConsistencyLevel;use  constant  ONE                    =>  1;use  constant  QUORUM              =>  2;use  constant  LOCAL_QUORUM  =>  3;use  constant  EACH_QUORUM    =>  4;use  constant  ALL                    =>  5;use  constant  ANY                    =>  6;use  constant  TWO                    =>  7;use  constant  THREE                =>  8;

Page 49: Writing a cassandra Client with perl

package  Cassandra::ConsistencyLevel;use  constant  ONE                    =>  1;use  constant  QUORUM              =>  2;use  constant  LOCAL_QUORUM  =>  3;use  constant  EACH_QUORUM    =>  4;use  constant  ALL                    =>  5;use  constant  ANY                    =>  6;use  constant  TWO                    =>  7;use  constant  THREE                =>  8;

Page 50: Writing a cassandra Client with perl

package  Cassandra::ConsistencyLevel;use  constant  ONE                    =>  1;use  constant  QUORUM              =>  2;use  constant  LOCAL_QUORUM  =>  3;use  constant  EACH_QUORUM    =>  4;use  constant  ALL                    =>  5;use  constant  ANY                    =>  6;use  constant  TWO                    =>  7;use  constant  THREE                =>  8;

Page 51: Writing a cassandra Client with perl

my  $cf  =  '20121011.larsen.tweets';

my  $columnParent  =  Cassandra::ColumnParent-­‐>new({column_family  =>  $cf});my  $sliceRange  =      Cassandra::SliceRange-­‐>new({          start    =>  '',        finish  =>  ''    });

my  $predicate  =      Cassandra::SlicePredicate-­‐>new({        slice_range  =>  $sliceRange    });

$res  =  $client-­‐>get_slice(    $key,      $columnParent,      $predicate,      Cassandra::ConsistencyLevel::ONE);

Page 52: Writing a cassandra Client with perl

my  $cf  =  '20121011.larsen.tweets';

my  $columnParent  =  Cassandra::ColumnParent-­‐>new({column_family  =>  $cf});my  $sliceRange  =      Cassandra::SliceRange-­‐>new({          start    =>  '',        finish  =>  ''    });

my  $predicate  =      Cassandra::SlicePredicate-­‐>new({        slice_range  =>  $sliceRange    });

$res  =  $client-­‐>get_slice(    $key,      $columnParent,      $predicate,      Cassandra::ConsistencyLevel::ONE);

thrift

struct  SliceRange  {        1:  required  binary  start,        2:  required  binary  finish,        3:  required  bool  reversed=0,        4:  required  i32  count=100,}

Page 53: Writing a cassandra Client with perl

my  $cf  =  '20121011.larsen.tweets';

my  $columnParent  =  Cassandra::ColumnParent-­‐>new({column_family  =>  $cf});my  $sliceRange  =      Cassandra::SliceRange-­‐>new({          start    =>  '',        finish  =>  ''    });

my  $predicate  =      Cassandra::SlicePredicate-­‐>new({        slice_range  =>  $sliceRange    });

$res  =  $client-­‐>get_slice(    $key,      $columnParent,      $predicate,      Cassandra::ConsistencyLevel::ONE);

thriftlist<ColumnOrSuperColumn>  get_slice(    1:required  binary  key,    2:required  ColumnParent  column_parent,    3:required  SlicePredicate  predicate,    4:required  ConsistencyLevel  consistency_level=ConsistencyLevel.ONE)  throws  (1:InvalidRequestException  ire,                    2:UnavailableException  ue,                    3:TimedOutException  te)

Page 54: Writing a cassandra Client with perl

Writing

Page 55: Writing a cassandra Client with perl

thrift

void insert(1:required binary key,· 2:required ColumnParent column_parent, 3:required Column column, 4:required ConsistencyLevel consistency_level=ConsistencyLevel.ONE) throws (1:InvalidRequestException ire, 2:UnavailableException ue, 3:TimedOutException te)

Perl (generated code)

sub  insert{    my  $self  =  shift;    my  $key  =  shift;    my  $column_parent  =  shift;    my  $column  =  shift;    my  $consistency_level  =  shift;

   $self-­‐>send_insert(  $key,  $column_parent,  $column,  $consistency_level);    $self-­‐>recv_insert();}

Page 56: Writing a cassandra Client with perl

thrift

void insert(1:required binary key,· 2:required ColumnParent column_parent, 3:required Column column, 4:required ConsistencyLevel consistency_level=ConsistencyLevel.ONE) throws (1:InvalidRequestException ire, 2:UnavailableException ue, 3:TimedOutException te)

Perl (generated code)

sub  insert{    my  $self  =  shift;    my  $key  =  shift;    my  $column_parent  =  shift;    my  $column  =  shift;    my  $consistency_level  =  shift;

   $self-­‐>send_insert(  $key,  $column_parent,  $column,  $consistency_level);    $self-­‐>recv_insert();}

thrift

Perl (generated code)

package  Cassandra::Column;use  base  qw(Class::Accessor);Cassandra::Column-­‐>mk_accessors(  qw(  name  value  timestamp  ttl  )  );

struct  Column  {      1:  required  binary  name,      2:  optional  binary  value,      3:  optional  i64  timestamp,      4:  optional  i32  ttl,}

Page 57: Writing a cassandra Client with perl

eval  {        my  $cf  =  'TestCF';        my  $key  =  'bar';

       my  $columnParent  =  Cassandra::ColumnParent-­‐>new({            column_family  =>  $cf        });

       my  $ts  =  sprintf  "%.6f",  Time::HiRes::time;        $ts  =~  s/\.//;        say  $ts;

       my  $column  =  Cassandra::Column-­‐>new({            name            =>  'test',              value          =>  'a  test  value',              timestamp  =>  $ts        });

       $client-­‐>insert(              $key,  $columnParent,  $column,  Cassandra::ConsistencyLevel::ONE);};if  (  $@  )  {        die  Dumper(  $@  );}

Page 58: Writing a cassandra Client with perl

eval  {        my  $cf  =  'TestCF';        my  $key  =  'bar';

       my  $columnParent  =  Cassandra::ColumnParent-­‐>new({            column_family  =>  $cf        });

       my  $ts  =  sprintf  "%.6f",  Time::HiRes::time;        $ts  =~  s/\.//;        say  $ts;

       my  $column  =  Cassandra::Column-­‐>new({            name            =>  'test',              value          =>  'a  test  value',              timestamp  =>  $ts        });

       $client-­‐>insert(              $key,  $columnParent,  $column,  Cassandra::ConsistencyLevel::ONE);};if  (  $@  )  {        die  Dumper(  $@  );}

thrift

struct  Column  {      1:  required  binary  name,      2:  optional  binary  value,      3:  optional  i64  timestamp,      4:  optional  i32  ttl,}

Page 59: Writing a cassandra Client with perl

CPAN?

Page 60: Writing a cassandra Client with perl

Page 61: Writing a cassandra Client with perl

Net::Cassandra ✘Net::Cassandra::Easy ✘

Cassandra::Lite ✘AnyEvent::Cassandra ✘

Page 62: Writing a cassandra Client with perl

Page 63: Writing a cassandra Client with perl

Questions?


Recommended