GithubHelp home page GithubHelp logo

kallaspriit / cassandra-php-client-library Goto Github PK

View Code? Open in Web Editor NEW
103.0 16.0 25.0 1.25 MB

Cassandra PHP-based client library for managing and querying your Cassandra cluster

Home Page: http://cassandra-php-client-library.com

PHP 54.23% Racket 5.26% JavaScript 1.57% Awk 0.20% Shell 36.13% C 0.13% C++ 2.40% Objective-C 0.08%

cassandra-php-client-library's Introduction

Cassandra PHP Client Library

Cassandra PHP Client Library logo

Cassandra PHP Client Library or CPCL for short allows for managing and querying your Cassandra cluster. It's a high-level library performing all the rather complex low-level heavy lifting and provides a simple to learn and use interface.

Features

  • simple and intuitive interface
  • well covered with unit tests (> 90%)
  • support for multiple server pools using named singletons
  • requires including a single file
  • uses reasonable defaults through-out
  • powerful syntax for querying data
  • enables managing keyspaces and column-families
  • automatic packing of datatypes using column metadata
  • retries failed queries using back-off strategy
  • built with performance in mind (caches schema description etc)
  • well documented API and a working example

Class diagram

CPCL class diagram

The library uses the very permissive MIT licence which means you can do pretty much anything you like with it.

Example

The following example covers most of what you need to know to use this library. It should work out-of-box on a machine with default cassandra setup running. The example file is contained in the download.

Click here for prettier code.

<?php

// show all the errors
error_reporting(E_ALL);

// the only file that needs including into your project
require_once 'Cassandra.php';

// list of seed servers to randomly connect to
// all the parameters are optional and default to given values
$servers = array(
	array(
		'host' => '127.0.0.1',
		'port' => 9160,
		'use-framed-transport' => true,
		'send-timeout-ms' => 1000,
		'receive-timeout-ms' => 1000
	)
);

// create a named singleton, the second parameter name defaults to "main"
// you can have several named singletons with different server pools
$cassandra = Cassandra::createInstance($servers);

// at any point in code, you can get the named singleton instance, the name
// again defaults to "main" so no need to define it if using single instance
$cassandra2 = Cassandra::getInstance();

// drop the example keyspace and ignore errors should it not exist
try {
	$cassandra->dropKeyspace('CassandraExample');
} catch (Exception $e) {}


// create a new keyspace, accepts extra parameters for replication options
// normally you don't do it every time
$cassandra->createKeyspace('CassandraExample');

// start using the created keyspace
$cassandra->useKeyspace('CassandraExample');

// if a request fails, it will be retried for this many times, each time backing
// down for a bit longer period to prevent floods; defaults to 5
$cassandra->setMaxCallRetries(5);

// create a standard column family with given column metadata
$cassandra->createStandardColumnFamily(
	'CassandraExample', // keyspace name
	'user',             // the column-family name
	array(              // list of columns with metadata
		array(
			'name' => 'name',
			'type' => Cassandra::TYPE_UTF8,
			'index-type' => Cassandra::INDEX_KEYS, // create secondary index
			'index-name' => 'NameIdx'
		),
		array(
			'name' => 'email',
			'type' => Cassandra::TYPE_UTF8
		),
		array(
			'name' => 'age',
			'type' => Cassandra::TYPE_INTEGER,
			'index-type' => Cassandra::INDEX_KEYS,
			'index-name' => 'AgeIdx'
		)
	)
	// actually accepts more parameters with reasonable defaults
);

// create a super column family
$cassandra->createSuperColumnFamily(
	'CassandraExample',
	'cities',
	array(
		array(
			'name' => 'population',
			'type' => Cassandra::TYPE_INTEGER
		),
		array(
			'name' => 'comment',
			'type' => Cassandra::TYPE_UTF8
		)
	),
	// see the definition for these additional optional parameters
	Cassandra::TYPE_UTF8,
	Cassandra::TYPE_UTF8,
	Cassandra::TYPE_UTF8,
	'Capitals supercolumn test',
	1000,
	1000,
	0.5
);

// lets fetch and display the schema of created keyspace
$schema = $cassandra->getKeyspaceSchema('CassandraExample');
echo 'Schema: <pre>'.print_r($schema, true).'</pre><hr/>';
/*
// should we need to, we can access the low-level client directly
$version = $cassandra->getConnection()->getClient()->describe_version();
echo 'Version directly: <pre>'.print_r($version, true).'</pre><hr/>';
*/
// if implemented, use the wrapped methods as these are smarter - can retry etc
$version = $cassandra->getVersion();
echo 'Version through wrapper: <pre>'.print_r($version, true).'</pre><hr/>';

// cluster is a pool of connections
$cluster = $cassandra->getCluster();
echo 'Cluster: <pre>'.print_r($cluster, true).'</pre><hr/>';

// you can ask the cluster for a connection to a random seed server from pool
$connection = $cluster->getConnection();
echo 'Connection: <pre>'.print_r($connection, true).'</pre><hr/>';

// access column family, using the singleton syntax
// there is shorter "cf" methid that is an alias to "columnFamily"
$userColumnFamily = Cassandra::getInstance()->columnFamily('user');
echo 'Column family "user": <pre>'.print_r($userColumnFamily, true).'</pre><hr/>';

// lets insert some test data using the convinience method "set" of Cassandra
// the syntax is COLUMN_FAMILY_NAME.KEY_NAME
$cassandra->set(
	'user.john',
	array(
		'email' => '[email protected]',
		'name' => 'John Smith',
		'age' => 34
	)
);

// when inserting data, it's ok if key name contains ".", no need to escape them
$cassandra->set(
	'user.jane.doe',
	array(
		'email' => '[email protected]',
		'name' => 'Jane Doe',
		'age' => 24
	)
);

// longer way of inserting data, first getting the column family
$cassandra->cf('user')->set(
	'chuck', // key name
	array(   // column names and values
		'email' => '[email protected]',
		'name' => 'Chuck Norris',
		'age' => 24
	),
	Cassandra::CONSISTENCY_QUORUM // optional consistency to use
	// also accepts optional custom timestamp and time to live
);

// lets fetch all the information about user john
$john = $cassandra->get('user.john');
echo 'User "john": <pre>'.print_r($john, true).'</pre><hr/>';

// since the jane key "jane.doe" includes a ".", we have to escape it
$jane = $cassandra->get('user.'.Cassandra::escape('jane.doe'));
echo 'User "jane.doe": <pre>'.print_r($jane, true).'</pre><hr/>';

// there is some syntatic sugar on the query of Cassandra::get() allowing you
// to fetch specific columns, ranges of them, limit amount etc. for example,
// lets only fetch columns name and age
$chuck = $cassandra->get('user.chuck:name,age');
echo 'User "chuck", name and age: <pre>'.print_r($chuck, true).'</pre><hr/>';

// fetch all solumns from age to name (gets all columns in-between too)
$chuck2 = $cassandra->get('user.chuck:age-name');
echo 'User "chuck", columns ago to name: <pre>'.print_r($chuck2, true).'</pre><hr/>';

// the range columns do not need to exist, we can get character ranges
$chuck3 = $cassandra->get('user.chuck:a-z');
echo 'User "chuck", columns a-z: <pre>'.print_r($chuck3, true).'</pre><hr/>';

// when performing range queries, we can also limit the number of columns
// returned (2); also the method accepts consistency level as second parameter
$chuck4 = $cassandra->get('user.chuck:a-z|2', Cassandra::CONSISTENCY_ALL);
echo 'User "chuck", columns a-z, limited to 2 columns: <pre>'.print_r($chuck4, true).'</pre><hr/>';

// the Cassandra::get() is a convinience method proxying to lower level
// CassandraColumnFamily::get(), no need to worry about escaping with this.
// column family has additional methods getAll(), getColumns(), getColumnRange()
// that all map to lower level get() calls with more appopriate parameters
$jane2 = $cassandra->cf('user')->get('jane.doe');
echo 'User "jane.doe", lower level api: <pre>'.print_r($jane2, true).'</pre><hr/>';

// we defined a secondary index on "age" column of "user" column family so we
// can use CassandraColumnFamily::getWhere() to fetch users of specific age.
// this returns an iterator that you can go over with foreach or use the
// getAll() method that fetches all the data and returns an array
$aged24 = $cassandra->cf('user')->getWhere(array('age' => 24));
echo 'Users at age 24: <pre>'.print_r($aged24->getAll(), true).'</pre><hr/>';

// if we know we are going to need to values of several keys, we can request
// them in a single query for better performance
$chuckAndJohn = $cassandra->cf('user')->getMultiple(array('chuck', 'john'));
echo 'Users "chuck" and "john": <pre>'.print_r($chuckAndJohn, true).'</pre><hr/>';

/* Uncomment this when using order preserving partitioner
// we can fetch a range of keys but this is predictable only if using an
// order preserving partitioner, Cassandra defaults to random one
// again as there may be more results than it's reasonable to fetch in a single
// query, an iterator is returned that can make several smaller range queries
// as the data is iterated
$usersAZ = $cassandra->cf('user')->getKeyRange('a', 'z');
echo 'Users with keys in range a-z: <pre>'.print_r($usersAZ->getAll(), true).'</pre><hr/>';
*/

// find the number of columns a key has, we could also request for ranges
$chuckColumnCount = $cassandra->cf('user')->getColumnCount('chuck');
echo 'User "chuck" column count: <pre>'.print_r($chuckColumnCount, true).'</pre><hr/>';

// we can find column counts for several keys at once
$chuckJaneColumnCounts = $cassandra->cf('user')->getColumnCounts(array('chuck', 'jane.doe'));
echo 'User "chuck" and "jane.doe" column counts: <pre>'.print_r($chuckJaneColumnCounts, true).'</pre><hr/>';

// setting supercolumn values is similar to normal column families
$cassandra->set(
	'cities.Estonia',
	array(
		'Tallinn' => array(
			'population' => '411980',
			'comment' => 'Capital of Estonia',
			'size' => 'big'
		),
		'Tartu' => array(
			'population' => '98589',
			'comment' => 'City of good thoughts',
			'size' => 'medium'
		)
	)
);

// fetch all columns of Tartu in Estonia of cities
$tartu = $cassandra->cf('cities')->getAll('Estonia', 'Tartu');
echo 'Super-column cities.Estonia.Tartu: <pre>'.print_r($tartu, true).'</pre><hr/>';

// we could also use the higher level Cassandra::get() to fetch supercolumn info
// we can still use the additional filters of columns
$tallinn = $cassandra->get('cities.Estonia.Tallinn:population,size');
echo 'Super-column cities.Estonia.Tallinn: <pre>'.print_r($tallinn, true).'</pre><hr/>';

// you can delete all the data in a column family using "truncate"
$cassandra->truncate('user');

// you may choose to drop an entire keyspace
$cassandra->dropKeyspace('CassandraExample');

cassandra-php-client-library's People

Contributors

kallaspriit avatar madhandennis avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cassandra-php-client-library's Issues

How do I get the row key ?

Hi kallaspriit, I'm using your client ,good work, but I've got a problem, how do I get the row key when I request using getWhere() ?
thanks.

How to use Order preserve partition

Hello,

i have the following code below:

$eight = $cassandra->cf('properties')->getWhere(array(array('price', Cassandra::OP_LT, 500)));
foreach ($eight as $key => $value) {
echo "ID: " . $value['id'];
echo "postcode: " . $value['postcode'];
echo "Price: " . $value['price'];
}
However the only operator which works is OP_EQ...i have researched and apparently it has something to do with order preserve partitioning...I am new to cassandra and any help would be brilliant

Thanks

Cannot getWhere using other Operator, except Equality

Hi, I have an problem when I try to get data by Operator Greater & Less than.

First, I use this code:
$aged24 = $cassandra->cf ( 'user' )->getWhere ( array (
array (
'age',
Cassandra::OP_EQ,
24
)
) );
echo 'Users 24:

' . print_r ( $aged24->getAll(), true ) . '

';

The result OK, it showed:
Array
(
[jane.doe] => Array
(
[age] => 24
[email] => [email protected]
[name] => Jane Doe
)
)

But, when I want get Greater, I changed code to:
$aged20plus = $cassandra->cf ( 'user' )->getWhere ( array (
array (
'age',
Cassandra::OP_GT,
20
)
) );
echo 'Users 20+:

' . print_r ( $aged20plus->getAll(), true ) . '

';

The result have Exception: "Failed calling "get_indexed_slices" the maximum of 5 times"

Please help me solve this problem. Thanks so much ^_^

integer type column - secondary key - Not Working for Integer but Works for Long

    array(
        'name' => 'zipcode',
        'type' => Cassandra::TYPE_LONG,
        'index-type' => Cassandra::INDEX_KEYS 
    ),
    array(
        'name' => 'rating1to10',
        'type' => Cassandra::TYPE_INTEGER,
        'index-type' => Cassandra::INDEX_KEYS
    )

In the above code, when I apply WHERE condition on a SELECT as shown below you can see it returns 0 rows. If I set the secondary key in cqlsh it WORKS.

cqlsh:befit> SELECT * FROM USER WHERE zipcode=75063;

key | email | name | rating1to10 | userid | zipcode
------------+----------------+------------+-------------+--------+---------
0x6a6f686e | [email protected] | John Smith | 34 | john | 75063

(1 rows)

cqlsh:befit> SELECT * FROM USER WHERE rating1to10=34;

(0 rows)

Please advise.
Thank you

No delete available?

I've been using your lib for sometimes now, everything work perfectly, i just can't find a way to use the "del" command available on the CLI.

Is Truncate and Drop the only way to delete stuff?

Thx you for your work

If keyspace exists

Hi,
I've tried to check if keyspace exists, but I was getting errors. Checked few times, and problem is in getKeyspaceSchema/describeKeyspace(which I wanted to test against null). App showing the problem:
$cassandra = Cassandra::createInstance($servers); $cassandra->createKeyspace("psycho_key"); $schema=$cassandra->getKeyspaceSchema("psycho_key"); print "check_1:<br>"; var_dump($schema); $cassandra->dropKeyspace("psycho_key"); print "<br>dropped"; $schema=$cassandra->getKeyspaceSchema("psycho_key"); print "<br>checked_2:"; var_dump($schema); ,
and the output is:
check_1: array(5) { ["name"]=> string(10) "psycho_key" ["placement-strategy"]=> string(43) "org.apache.cassandra.locator.SimpleStrategy" ["placement-strategy-options"]=> NULL ["replication-factor"]=> int(1) ["column-families"]=> array(0) { } } dropped Fatal error: Uncaught exception 'cassandra_NotFoundException' in C:\Users\Maciekp\Documents\Programming\web\mine\SDKs\cassandra_php\thrift\Thrift.php:574 Stack trace: #0 C:\Users\Maciekp\Documents\Programming\web\mine\SDKs\cassandra_php\thrift\packages\cassandra\Cassandra.php(3380): TBase->_read('Cassandra_descr...', Array, Object(TBinaryProtocolAccelerated)) #1 C:\Users\Maciekp\Documents\Programming\web\mine\SDKs\cassandra_php\thrift\packages\cassandra\Cassandra.php(1235): cassandra_Cassandra_describe_keyspace_result->read(Object(TBinaryProtocolAccelerated)) #2 C:\Users\Maciekp\Documents\Programming\web\mine\SDKs\cassandra_php\thrift\packages\cassandra\Cassandra.php(1196): CassandraClient->recv_describe_keyspace() #3 [internal function]: CassandraClient->describe_keyspace('psycho_key') #4 C:\Users\Maciekp\Documents\Programming\web\mine\SDKs\cassandra_php\Cassandra.php(968): call_user_func_array(Array, Array) #5 C:\Users\Maciekp\Documents\Programming\web\mine\SDKs\cassandra_php\Cassandra.php(1001): Cassandra->call('descri in C:\Users\Maciekp\Documents\Programming\web\mine\SDKs\cassandra_php\Cassandra.php on line 976

CassandraDataIterator error when lots of empty rows

In the function CassandraDataIterator::next(), the next() function is recursivly called until it find a valid value.

Depending on the data this function can pass the maximum nesting level throwing this error:

Fatal error: Maximum function nesting level of '100' reached, aborting!

I coded this fix :

public function next() {
    $value = null;
    $beyondLastRow = false;

    if (!empty($this->buffer)) {
        $this->nextStartKey = key($this->buffer);

        $value = next($this->buffer);

        if (count(current($this->buffer)) == 0) {
            $value = $this->findNextValidValue();
        } 

        $key = key($this->buffer);
        if (isset($key)) {
            $this->rowsSeen++;

            if (
                $this->rowCountLimit !== null
                && $this->rowsSeen > $this->rowCountLimit
            ) {
                $this->isValid = false;

                return null;
            }
        } else {
            $beyondLastRow = true;
        }           
    } else {
        $beyondLastRow = true;
    }

    if ($beyondLastRow) {
        if ($this->currentPageSize < $this->expectedPageSize) {
            $this->isValid = false;
        } else {
            $this->updateBuffer();

            if (count($this->buffer) == 1) {
                $this->isValid = false;
            } else {
                $this->next();
            }
        }
    }

    return $value;
}

private function findNextValidValue(){
    $value = next($this->buffer);
    while (count(current($this->buffer)) == 0) {
        $value = next($this->buffer);
    }
    return $value;
}

Getting 'TTransportException'

Hi,

Am getting this error -

PHP Fatal error: Uncaught exception 'TTransportException' with message 'TSocket: timed out writing 54 bytes from 68.67.157.167:9160' in /var/www/html/Cassandra-PHP-Client-Library/thrift/transport/TSocket.php:299
Stack trace:
#0 /var/www/html/Cassandra-PHP-Client-Library/thrift/transport/TFramedTransport.php(175): TSocket->write('???2????????set...')
#1 /var/www/html/Cassandra-PHP-Client-Library/thrift/packages/cassandra/Cassandra.php(131): TFramedTransport->flush()
#2 /var/www/html/Cassandra-PHP-Client-Library/thrift/packages/cassandra/Cassandra.php(113): cassandra_CassandraClient->send_set_keyspace('DemdexProdKeysp...')
#3 /var/www/html/Cassandra-PHP-Client-Library/Cassandra.php(248): cassandra_CassandraClient->set_keyspace('DemdexProdKeysp...')
#4 /var/www/html/Cassandra-PHP-Client-Library/Cassandra.php(445): CassandraConnection->useKeyspace('DemdexProdKeysp...', NULL, NULL)
#5 /var/www/html/Cassandra-PHP-Client-Library/Cassandra.php(869): CassandraCluster->useKeyspace('DemdexProdKeysp...', NULL, NULL)
#6 /var/www/html/sari in /var/www/html/Cassandra-PHP-Client-Library/thrift/transport/TSocket.php on line 299

getTimestamp not static

It seems the CassandraUtil::getTimestamp() function is used in many places in Cassandra.php but that function is not static within CassandraUtil:

public function getTimestamp()

unpackInteger() fails for negative Integers

Hello,

the unpackInteger() function uses

unpack('N', $value);

which parses $value as unsigned 32bit Big Endian Integer, although 32bit Integers in Cassandra are always signed. This breaks reading negative Integers from Cassandra.
Unfortunately PHP's unpack function seems to lack a mode for 32bit signed Big Endian. If your PHP-Code is running on a Little Endian plattform you can use

unpack('l', strrev($value));

to fix this. Another (endian safe) possible solution is to check if the returned value is >= 2^31 and substract 2^32 in this case.

how to insert longType key?

i created column family like as:
create column family question with
comparator=UTF8Type
and default_validation_class=UTF8Type
and key_validation_class= LongType
and column_metadata=[{
column_name: userID,
validation_class: UTF8Type,
index_name:qestionUserID_idx,
index_type:0}];

inserting is ok at cassandra-cli .
set question[1]['userID']='user 001';

inserting is failed at PHP script:
$cassandra->set(
'question.'.1,
array(
'userID' => $_REQUEST['userID'],
'question' => $_REQUEST['question'],
'addedLocalTime' => $_REQUEST['questionDateTime'],
'added' =>$timestamp
)
);
or
$cassandra->cf('question')->set(
222 ,
array(
'userID' => $_REQUEST['userID'],
'question' => $_REQUEST['question'],
'addedLocalTime' => $_REQUEST['questionDateTime'],
'added' =>$timestamp
),
Cassandra::CONSISTENCY_QUORUM
);

I don't know what is not correct.

Integer columns

If columns in CF are of integer type get method incorrectly returns wrong keys. I believe that problem is in method CassandraColumnFamily::parseSliceResponse where response if joined using array_merge which reindex array if keys are integers (+ should be used instead).

Regards
Ales

Unusable RowKey after $cassandra->set()

After calling set() I get a RowKey name that is useless! Adding more columns in the same manner adds them to the same row so I'm thinking this must be an encoding problem, but who's?

    $cassandra->set(
        'SomeColumnFamily.ColAssetMetricGUID',
        array(
            'localhost::cpu_sys' => $myhost.'::localhost::cpu_sys'
        )
    );

[default@MyApp] list SomeColumnFamily;
Using default limit of 100

Using default column limit of 100

RowKey: 436f6c41737365744d657472696347554944
=> (column=localhost::cpu_sys, value=hostname::localhost::cpu_sys, timestamp=1346448764354892)

1 Row Returned.
Elapsed time: 2 msec(s).

Unpack string

Hi,

I've a problem with some char like 'è' or 'ù' when I read data from cassandra. The code that unpacks the string is the follow:


public static function unpackString($value, $length)  {
        $unpacked = unpack('c'.$length.'chars', $value);
        $out = '';
        
        foreach($unpacked as $element) {
            if($element > 0) {
                $out .= chr($element);
            }
        }
        
        return $out;
}

If I replace 'c' with 'C' (unsigned char), this solve the problem.

I'd to like to know which is the sense to split a string into characters and then join characters into a string.

Thanks in advance
Mario

Cannot create keyspace

Hello!

I'm using Cassandra 1.1.0 installed from deb package (under Ubuntu 12), and I noticed that in the example.php the line

$cassandra->createKeyspace('CassandraExample')" 

isnt working, giving me the following stack trace (after ~10 sec.):

PHP Fatal error:  Uncaught exception 'cassandra_InvalidRequestException' in /home/jeff/Documents/projects/Cassandra-PHP-Client-Library/thrift/packages/cassandra/Cassandra.php:7863
Stack trace:
#0 /home/jeff/Documents/projects/Cassandra-PHP-Client-Library/thrift/packages/cassandra/Cassandra.php(1586): cassandra_Cassandra_system_add_keyspace_result->read(Object(TBinaryProtocolAccelerated))
#1 /home/jeff/Documents/projects/Cassandra-PHP-Client-Library/thrift/packages/cassandra/Cassandra.php(1547): cassandra_CassandraClient->recv_system_add_keyspace()
#2 [internal function]: cassandra_CassandraClient->system_add_keyspace(Object(cassandra_KsDef))
#3 /home/jeff/Documents/projects/Cassandra-PHP-Client-Library/Cassandra.php(971): call_user_func_array(Array, Array)
#4 /home/jeff/Documents/projects/Cassandra-PHP-Client-Library/Cassandra.php(1256): Cassandra->call('system_add_keys...', Object(cassandra_KsDef))
#5 /home/jeff/Documents/projects/Cassandra-PHP-Client-Library/test.php(37): Cassandra->createKeyspace('CassandraExampl...')
#6 {m in /home/jeff/Documents/projects/Cassandra-PHP-Client-Library/Cassandra.php on line 979

*When I create the keyspace manually from cassandra-cli, and after I run the example with commenting the drop-create line, everything works fine, columns family are correctly created into my keyspace, and the rest of the methods seems to work perfectly!

Thanks!

(intentional?) memory leak

Simple loop inserting rows with a UTF8 key and 128k of binary data results in memory exhaustion. Loop is calling simply fopen, fread, fclose, and $cassandra->set().

Is there some internal caching going on somewhere that can be turned off? If not, perhaps something in the set() call stack is referencing the data in a static and thus caching it unintentionally.

Cassandra::getWhere causes cassandra_InvalidRequestException

A cassandra_InvalidRequestException occurs in Cassandra::getWhere() when using where array format #2.
Using:
apache-cassandra-1.0.5
Cassandra-PHP-Client-Library (2011-12-04)
PHP 5.3.8

(I'm new to both PHP and Cassandra and so could be overlooking something obvious.)

Except from Cassandra.php:
* The where array can be a mix of two formats:
* 1. For simplest equality comparison - column value must equal something
* exactly, the format array('column-name' => 'required value') can be
* used.
* 2. For any other supported comparison operators, use the slightly longer
* syntax array(array('column-name', Cassandra::OP_LT, 'value')) where
* each component is an array with three values, the first one being the
* column name, second comparison operator and third the value. Use the
* Cassandra::OP_.. constants for operators.
* You can mix the two variants.

Added to example.php (at line 193):
$aged24andOlder = $cassandra->cf('user')->getWhere(
array(array('age', Cassandra::OP_GTE, 24))
);
echo 'Users aged 24+:

'.print_r($aged24andOlder->getAll(), true).'

';

Exception:
Fatal error: Uncaught exception 'cassandra_InvalidRequestException' in /usr/local/php/lib/php/Cassandra/thrift/packages/cassandra/Cassandra.php:4286
Stack trace:
#0 /usr/local/php/lib/php/Cassandra/thrift/packages/cassandra/Cassandra.php(587): cassandra_Cassandra_get_indexed_slices_result->read(Object(TBinaryProtocolAccelerated))
#1 /usr/local/php/lib/php/Cassandra/thrift/packages/cassandra/Cassandra.php(545): cassandra_CassandraClient->recv_get_indexed_slices()
#2 [internal function]: cassandra_CassandraClient->get_indexed_slices(Object(cassandra_ColumnParent), Object(cassandra_IndexClause), Object(cassandra_SlicePredicate), 1)
#3 /usr/local/php/lib/php/Cassandra/Cassandra.php(968): call_user_func_array(Array, Array)
#4 /usr/local/php/lib/php/Cassandra/Cassandra.php(3621): Cassandra->call('get_indexed_sli...', Object(cassandra_ColumnParent), Object(cassandra_IndexClause), Object(cassandra_SlicePredicate), 1)
#5 /usr/local/php/lib/ph in /usr/local/php/lib/php/Cassandra/Cassandra.php on line 976

Batch updating of counters

Hi there,

I'm currently doing a SLOW iteration (it takes 2 seconds+) per update, and I need this to manage real-time counters.

How can I do batch updates of counters with this library ?

Does Cassandra::getWhere() require at least one condition to be equals?

Please let me ask one question (maybe two).

(Since I could not reopen the previous issue #10. I created a new one. Sorry if that is not appropriate.)

For the test cases containing getWhere tests, the where array is either the only condition is an equals comparison ('age' => 34)
or the first condition is as equals comparison ('age', Cassandra::OP_EQ, 34) and the other condition is not ('name', Cassandra::OP_LTE, 'K').

Calling getWhere when the only condition is not an equals expression
or when none of the conditions are an equals expression results in an exception.

In order to do a range comparison a single column it appears a dummy column with a constant value is required so that
the getWhere equal expression requirement can be satisfied. As in:
array(array('one', OP_EQ, 1), array('name', OP_GTE, 'f'))

When using getWhere() is one of the conditions required to be an equals comparison?
If so, could a statement to that effect be added to the comment for the getWhere method?

exception 'CassandraMaxRetriesException' with message 'Failed calling "batch_mutate" the maximum of 5 times'

Hi,

Sometimes, I am getting the following error when inserting data to cassandra using cpcl.
Did i miss any configuration? Thanks for help.

exception 'CassandraMaxRetriesException' with message 'Failed calling "batch_mutate" the maximum of 5 times' in /test/prjcv/htdocs/test/extensions/cpcl684f89b/Cassandra.php:1004
Stack trace:
#0 /test/prjcv/htdocs/test/extensions/cpcl684f89b/Cassandra.php(2561): Cassandra->call('batch_mutate', Array, 1)
#1 /test/prjcv/htdocs/test/extensions/cpcl684f89b/CassandraModel.php(420): CassandraColumnFamily->set('11047793', Array, NULL)
#2 /test/prjcv/htdocs/test/controllers/ErrorController.php(85): CassandraModel->save('11047793')

CompositeType

CompositeType is missing from the compareWith options.
I pretty new to Cassandra, so let me know if this is normal or something that has to be added.

Thanks!

Uncaught Exception

Hi

I got the following after copy/pasting the README code into a test.php page.

Users "chuck" and "john":
Array
(
[chuck] => Array
(
[age] => 24
[email] => [email protected]
[name] => Chuck Norris
)

[john] => Array
    (
        [age] => 34
        [email] => [email protected]
        [name] => John Smith
    )

)


Fatal error: Uncaught exception 'cassandra_InvalidRequestException' with message 'start key's md5 sorts after end key's md5. this is not allowed; you probably should not specify end key at all, under RandomPartitioner' in /var/www/thrift/Thrift.php:574 Stack trace: #0 /var/www/thrift/packages/cassandra/Cassandra.php(2397): TBase->_read('Cassandra_get_r...', Array, Object(TBinaryProtocolAccelerated)) #1 /var/www/thrift/packages/cassandra/Cassandra.php(520): cassandra_Cassandra_get_range_slices_result->read(Object(TBinaryProtocolAccelerated)) #2 /var/www/thrift/packages/cassandra/Cassandra.php(478): CassandraClient->recv_get_range_slices() #3 [internal function]: CassandraClient->get_range_slices(Object(cassandra_ColumnParent), Object(cassandra_SlicePredicate), Object(cassandra_KeyRange), 1) #4 /var/www/Cassandra.php(968): call_user_func_array(Array, Array) #5 /var/www/Cassandra.php(3609): Cassandra->call('get_range_slice...', Object(cassandra_ColumnParent), Object(cassandra_SlicePredicate), Object(cassandra_KeyRange), 1) in /var/www/Cassandra.php on line 976

I'm pretty new to this, so maybe I'm missing some install or lib?

Regards

JP

Solution: Counter support

For those of you looking for counter support in this excellent library, here it is. Add it to CassandraColumnFamily class in the Cassandra.php file and you are good to go.

public function add($key, $column, $value = 1, $superColumn = null, $consistency = null) {
            $columnParent = $this->createColumnParent($superColumn);
            $timestamp = CassandraUtil::getTimestamp();

            $counter = new cassandra_CounterColumn();
            $counter->name = CassandraUtil::pack(
                    $column,
                    $this->getColumnNameType()
            );
            $counter->value = $value;

            $result = $this->cassandra->call(
            'add',
            $key,
            $columnParent,
            $counter,
            $consistency
        );
        }

invoke as

$cassandra->cf('columnfamily')->add('key', 'column') to increment by 1
$cassandra->cf('columnfamily')->add('key', 'column', -1) to decrement by 1
$cassandra->cf('columnfamily')->add('key', 'column', 5) to increment by 5
$cassandra->cf('columnfamily')->add('key', 'column', -5) to decrement by 5

for super column based counter CFs

$cassandra->cf('columnfamily')->add('key', 'column',1 , 'supercol1') to increment by 1
$cassandra->cf('columnfamily')->add('key', 'column', -1, 'supercol1') to decrement by 1
$cassandra->cf('columnfamily')->add('key', 'column', 5, 'supercol1') to increment by 5
$cassandra->cf('columnfamily')->add('key', 'column', -5, 'supercol1') to decrement by 5

Thanks for kallaspriit for such an awesome library!

Cheers

Support increment

It would be great if Cassandra PHP library could support the increment command for distributed counter columns.

Multiple strange issues with long-running scripts

Greetings,

The discussion of my issues would likely be better suited to a mailing list or forum environment, but I can't seem to find any that are associated with the project. If they exist and I've just missed them somehow, please point me in their direction.

I've been converting a server monitoring application to utilize Cassandra, and I've been using the CPCL to bridge the gap between PHP and Cassandra. For the most part, it's been pretty painless, but I've run into some really strange issues that I haven't been able to isolate or correct. I'm still fairly new to Cassandra, so I'm not really certain whether I'm finding bugs somewhere, or whether I'm just "Doing It Wrong (tm)".

The entire application is running in a development environment on a collection of CentOS 5.8 64-bit Xen instances with the php53 (specifically: php53-5.3.3-7.el5_8) RPMs provided by CentOS. The Cassandra cluster started as 8 VMs running on a single hardware node with 2 VCPUs and 2GB RAM each, and has grown to 12 VMs running on three hardware nodes, with 2 VCPUs and 4GB of RAM each. Cassandra is installed via the DataStax RPMs (apache-cassandra1-1.0.9-1 , to be specific). I've done no tweaking to the configuration other than setting the initial tokens and cluster names on each server, and to configure the listen/RPC addresses. I'm using a self-compiled version of the thrift binary library built from the code provided in the CPCL. The CPCL code I'm using seems to correlate to commit 766dc14 from the git repo (retrieved via kallaspriit-Cassandra-PHP-Client-Library-766dc14.zip on 2012/06/04).

My app accesses Cassandra both through short-lived HTTP-based PHP scripts and through long-lived PHP scripts that run via the command line. The problems exist in the latter set of scripts, seemingly after the script has done a good number of large-ish operations from cassandra. By "large-ish", I mean a get or set of a single key with 10,000-30,000 columns or so. These issues all occur within scripts that repeatedly retrieve a bunch of data from Cassandra, process it in some way, then store the processed data back into Cassandra. So far, I'm seeing multiple distinct issues.

  1. At times, the data retrieved from Cassandra is wrong. This scenario seems to occur after the script has been running for a while (an hour or more), and many get/set operations have taken place. The "wrong" data appears in the form of data that was retrieved previously, via a get request for a different key. This problem occurs infrequently and seemingly at random. I've taken good care to make sure the variables I'm fetching data into are sanitized, and I'm catching exceptions and acting accordingly. I've been able to lessen the frequency of this problem by periodically closing the connections to Cassandra, destroying the Cassandra object, and re-initializing it, but that doesn't prevent it completely. It makes me wonder if there is some sort of buffering issue at some level, where a request to that goes to a particular Cassandra node doesn't completely clear out of a buffer, and then is inadvertently re-used later on.

  2. Set operations seem to hang for some unknown reason. This happens after the script has retrieved data, processed it, and is trying to put the results back into Cassandra. The set operation just hangs until one of two things is done: 1) Ctrl-Z the running script to interrupt its execution, then issue the "fg" command to start it back up again. 2) attach to the hung process with strace, which unblocks the script somehow. Without one of these intervening actions, the script will hang indefinitely. It's not something that happens with every set operation (probably with < 5% of set operations), but it happens enough to be very annoying.

  3. lots of seemingly random communications failures that manifest themselves as exceptions like 'Failed calling "describe_keyspace" the maximum of X times' or 'Failed calling "get_slice" the maximum of X times'. I think I was able to correct this issue by reducing I/O contention in the cassandra cluster, but I'm not positive yet. In my initial testing setup, I had 8 Cassandra VMs all on the same hardware node, so I/O contention was pretty high at times. Moving the VMs to different hardware nodes has seemingly fixed this, but I can't say for sure, since a lot of the scripts that suffer the two issues above are the same scripts that have this problem, and they've been shut down for the time being while I try to figure things out.

Since I'm not seeing any issues whatsoever with the short-lived scripts that run via HTTP requests, my guess is that data objects are becoming "cluttered" over time as the long-running scripts do their thing, and that clutter is somehow causing the issues I'm seeing above. I've tried digging into the various classes involved, but being completely unfamiliar with the Cassandra/thrift binary protocols, I can only dig so far.

I realize I'm laying out some rather ambiguous and ill-defined issues here, so if you need specifics, please let me know what you need. Being fairly new to Cassandra, I wouldn't be at all surprised if I'm just missing something. Any insight is welcome.

Related to thrift_protocol.so?

Been getting this in my apache logs when trying to run some test work...

[Mon Dec 19 19:48:30 2011] [error] [client 170.40.160.26] PHP Fatal error: Uncaught exception 'cassandra_InvalidRequestException' in /var/www/test/thrift/packages/cassandra/Cassandra.php:1571\nStack trace:\n#0 /var/www/test/thrift/packages/cassandra/Cassandra.php(1571): thrift_protocol_read_binary(Object(TBinaryProtocolAccelerated), 'cassandra_Cassa...', false)\n#1 /var/www/test/thrift/packages/cassandra/Cassandra.php(1547): cassandra_CassandraClient->recv_system_add_keyspace()\n#2 [internal function]: cassandra_CassandraClient->system_add_keyspace(Object(cassandra_KsDef))\n#3 /var/www/test/Cassandra.php(968): call_user_func_array(Array, Array)\n#4 /var/www/test/Cassandra.php(1253): Cassandra->call('system_add_keys...', Object(cassandra_KsDef))\n#5 /var/www/test/casstest.php(31): Cassandra->createKeyspace('CassandraTest')\n#6 {main}\n\nNext exception 'CassandraMaxRetriesException' with message 'Failed calling "system_add_keyspace" the maximum of 5 times' in /var/www/test/Cassandra.php:976\nStack trace:\n#0 /var/www/test/Cassandra.php(1253): Cassandra->call('system_add_keys...', Object(cassandra in /var/www/test/Cassandra.php on line 976, referer: http://www/test/test.html

Authentication does not work

HI, i try to do this
$cassandra->useKeyspace('keyspace','username','pass');

but i get InvalidRequestException. I found that there are not defined arrays keys ("username" and "password") of auth. request. After i fixed it, there is another exception in other part of library.
I use Cassandra 1.2.4

Please help me solve this problem. Thanks so much

How to create Composite or Multi Primary key ?

Hi everybody,

I try create new Table / ColumnFamily like this cql:
CREATE TABLE users(uname text,age int, PRIMARY KEY(uname,age));

So, I don't known how to do with this Php-Client-Library to make the Table / ColumnFamily like query above.

Anyone known that, please share to me ! Thanks alot !

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.