Sunday, January 20, 2013

Couchbase support in Jamm!Memory

New storage

Jamm!Memory, PHP library with universal interface for best cachers (Redis, APC, Memcached), now have object for work with Couchbase - CouchbaseObject.
All features of this library are implemented in this class: tags, dog-pile and race-conditions protection, lock/acquire and others.
All code is test-covered, tested and even benchmarked. CouchbaseObject is not yet used in production, but I'm going to (see below).

Main feature of this storage is a fault-tolerance, of course.
While working on this code and testing it, I built cluster from few nodes and it was really simple. Server GUI is super user-friendly, has lot of monitoring things and control of nodes. Add new node in cluster is just  2 minutes (maybe less) plus time for rebalancing (it's going automatically and all data is available).

And next branch

Age of Jamm!Memory API is more than 2 years already. So I made branch 1.0, where currently placed all code of library, tested by unit-tests and by heavy usage in production for 2 years.
In next branch, 2.0, I will write refactored version of Jamm!Memory. API will be changed, all features will be saved, new features will be added. Some other storages maybe will be added (Riak, Cassandra).

Plans

I want to create another library, dedicated to Redis Cluster. It's in active development still, but it's time to write clients already :) It will be only key-value storage, but I hope it will as fast as existing Redis. I don't like that "Redis cluster sacrifices fault tolerance for consistence", but maybe it's just me and I don't understand something.

Also I hope Couchbase will have ability to turn off permanent writes to disk and will be able to copy data in background, so all writes and reads of data will be in memory. 
Please, support this idea by posting in forum thread.

In their forums I've created few themes and accidentally (I swear) whole column "last post" had become filled with my nickname :)

Also, I'm going to use Couchbase in production as a storage for cache, logs, sessions. This DB could be perfect for analytics (because of Map/Reduce), but it will require to write some GUI to show all these results. Currently used tool works only with RDBMS by ODBC. 

Saturday, January 19, 2013

Installing Couchbase PHP SDK for PHP 5.4 + Couchbase Server 2.0

  1. Couchbase Server doesn't have repositories (at this moment). That's not cool, of course. Forget about apt-get update.
  2. Precompiled SDK package for PHP is not compatible with PHP 5.4 API. So don't waste your time and compile it from sources. And, of course, forget about apt-get update. Very "enterprise" way, what can I say...
  3. Couchbase Server GUI looks very attractive. Has email alerts and lot of graphics for monitoring.
  4. No hot-fixes for Community version.
If in this article you are looking instructions "how to install", then just open pages with instructions:

Server:
Couchbase Server Manual - Installation
Don't forget to configure server in web-interface.

Client:
Install PHP SDK for Couchbase
At the moment of writing this article, precompiled PHP SDK package is not compatible with PHP 5.4, so use sources (link "Source archive."). 
Before compilation, install packages php5-dev and php-pear. 
Then download, unzip, go to unzipped folder and run 
phpize
./configure
make
sudo make install
and copy path of generated module from output. You need to add it into php.ini
For php5-fpm it will be:
sudo nano /etc/php5/fpm/conf.d/couchbase.ini
and add line (use generated path + "couchbase.so").
extension=/usr/lib/php5/20100525+lfs/couchbase.so
Now restart php
sudo /etc/init.d/php5-fpm restart 
And check it:
php -m | grep couchbase 
In output you should see "couchbase". Also, in phpinfo() you will see something like
Now you can write your genius code :)
For auto-completion in IDE you can use https://github.com/couchbase/php-ext-couchbase/blob/master/example/couchbase-api.php

Friday, January 18, 2013

Reading Couchbase documentation

In this post I want just highlight some wondering lines from Couchbase documentation

Couchbase

"All Couchbase SDKs automatically read and write data to the right node in a cluster. If database topology changes, the SDK responds automatically and correctly distribute read/write requests to the right cluster nodes. Similarly, if your cluster experiences server failure, SDKs will automatically direct requests to still-functioning nodes."

"For optimal performance and speed, stores most frequently used data in RAM. Persistent storage also provided to survive system downtime and for re-population of RAM."

"For example, a player making 10 game state mutations in 5 seconds, such as planting 10 flowers in 5 seconds, will be compressed by Couchbase automatically into just one queued disk mutation."

"To extend our application with new user attributes, we simply start storing additional fields at the document level. Unlike traditional relational databases, there is no need for us to have server downtime, or database migration to a new schema."


"You may wonder how effective it is to run query your view if Couchbase Server will run it on every persisted document in the database. But Couchbase Server is designed to avoid duplicate work. It will run the function on all documents once, when you first query the view. For subsequent queries on the view Couchbase Server will recompute the keys and values only for documents that have changed."

Impression

Finally I've read that Couchbase Developer's Guide 2.0
Very good example of documentation. Not the best, but very good. Many DB sites can learn from Couchbase how to write good documentation.

In some articles too many words and trivial examples (even with pictures), but sometimes amount of examples in live code is just not enough. For examples, after reading whole manual, I still don't know how to create "view" and how send it to server. Some file saving... But I know how to write functions in view and even best practices about it :)

Of course, I'm very impressed about Couchbase at all.
Ability to write map/reduce functions in JavaScript is amazing.
Auto-updating results of view is awesome.
Finally I know how my idea about select via callback function should be named - "map function" - I knew I'm reinventing the wheel :)

Tomorrow

I'm planing to add support of Couchbase to Jamm!Memory, I'm planing create there branch 2.0 (for "cas" and some other things in all cachers and to rename some methods to more familiar get/set).

I'm going to learn Ruby and try to write project in Ruby. Examples in Couchebase documentation shows that Ruby can be readable even easily than PHP.

I really think that Couchbase is the best in the NoSQL world at this moment. But maybe I just don't know all of them :)

Monday, January 14, 2013

Connect to guest OS via SSH in VMWare Player

In VirtualBox it was long and difficult quest just to connect from host OS to guest OS.
In VMWare Player (5.0.1) it's unbelievable simple:

  1. switch network adapter to bridge;
  2. reboot;
  3. run "ifconfig" command in terminal and get "inet addr" of "eth0".

That's all - use this IP to connect via ssh (I use Putty in my Windows 8).
Also you can use it in browser (if some web-server is installed on guest).

All this info is very simple and looks pretty noobish, but I hope it will be useful for somebody :)

Saturday, January 12, 2013

Looking at Cassandra DB


Few days ago I was asked "what do you think about Cassandra?" At that moment I'd read only few short notes about this database, all these notes was pretty old (around year ago) so there was not many useful or attractive information. But I've decide to check what has been changed with this DB. And... it was really interesting.

Already after week I've read book Cassandra: The Definitive Guide and lot of information from StackOverflow, SlideShare and googled articles. Book is very outdated, most of useful information you can find in Datastax's Cassandra documentation. To update your knowledge after reading that book, I recommend to check list of articles at http://www.datastax.com/dev/blog (for example, SuperColumns were replaced by Composite Columns and Thrift was replaced by CQL3 and binary protocol).

And what is so interesting in Cassandra?

First of all - fault tolerance

I'm sure it's very important for clients loyalty to see working service. They shouldn't see "server is down due maintenance" message never - it's unacceptable and it's shame for every service.

Most of web-projects currently use MySQL as database and it's not so easy to achieve real fault tolerance. Master-slave replication is not enough - what will you do when master-node will be rebooted for software/hardware upgrade or will be not available in case of network issues? You will panic and try to switch some slave into master mode or restore master. It's a downtime, in good case - few minutes, in bad - few hours. Users loyalty, reputation of service, money, time, sleepless night...

It's good that we have Galera for MySQL. Update: Don't use Galera, it's painful.
But Amazon Dynamo, Cassandra, Riak were build with idea of decentralization as the main idea so it's not "workaround" for database, it's intended behavior. That's why I personally trust Cassandra's fault tolerance more than MySQL's with Galera.
Just read about all possibilities and settings of replication in Cassandra and you will see that there is a lot of features for great fault tolerance. Cross-datacenter ring native support is awesome.

Second - performance

I spent whole day to find this page with benchmarks graphics of Cassandra, MySQL, Riak, HBase, MongoDB. But here I found very important information - performance of Cassandra is very good, not just "good enough" but exactly very good.

Ready to use

We, modest programmers of high-level web-languages, are always in a dependence of "clients" for compiled software.
It was not surprisingly to find an existing PHP-client for Cassandra, PHPCassa, but I don't like static methods, hardcoding and global variables, so I don't want use code with so ugly lines as "$GLOBALS['\cassandra\E_IndexOperator']" (it's line from PHPCassa code). Other clients have lot of static method also.

I thought there is 2 variants - write own client (as wrapper for Thrift API) or find existing client with most clear code. But... today I found very cool thing - Cassandra PDO driver for PHP! And there is SQL-like syntax (CQL) It's amazing and now I'm deploying few Linode VPS to try Cassandra PDO.

I'm inspired and that's what I wish to you :)

Saturday, July 7, 2012

Incorrect replacement of prepared statements with numeric values in PDO

1. Returned by tester

Found interesting bug yesterday: absolutely correct query show correct result when run it without preparing and incorrect, if use prepared statements.
SELECT `operator`,`region` FROM `phone_code` WHERE `code` = :code AND `from_num` <= :from_num AND `to_num` >= :to_num
Replacement by strtr function shows that all is correct in replacements pairs array. It's unbelievable, but  it's true. Conditions <= and => just doesn't work with prepare.
Thanks to Mikhail Khmelev, tester in our team, he found differences in results (both results looks almost correct in particularly case).

I've tried to change names of statements, change SQL query, and even change spaces in query - I've spent around hour to find reason of this bug.

And, as you read in title, bug is in PHP: PDO numeric values of prepared statements replaces as strings, with quotation:

SELECT `operator`,`region` FROM `phone_code` WHERE `code` = '921' AND `from_num` <= '1234567' AND `to_num` >= '1234567'
So it's became obviously, why this query doesn't work correctly - numeric fields in DB can't be compared with text values by <= or => operators.


2. We have to fix it 

How to fix this behavior of PHP? I don't want to write my own "prepare" function - native should work faster and correctly and test much more heavily. But I have to find workaround, because program should work.

First solution was replace all numeric values of statements by strtr or str_ireplace, but tests shows that names of statements can be replaced incorrectly, when we have :statement and :statement_something_other. So I decide to replace by strtr with replacement pairs array and in add in that array all statements, not only numeric - not numeric statements will be replaced by itself and this replacement will exclude sub-strings replacement.
Final code you can find here: https://github.com/jamm/DataMapper/blob/master/MySQL/Gateway.php#L233 (function getCorrectPreparedQuery).

This bug exists in PHP since 2008: https://bugs.php.net/bug.php?id=44639
Thanks to PHP for this interesting bug and wasted time. Hope it will be fixed in next ten years.

Sunday, July 1, 2012

Love

Love each other.
I know how many hateful words we can find in one or another religions. Christians should hate Muslims, Muslims should hate Buddhists, atheists should hate them all...
But all we should just love each other. Don't listen nobody who told you to hate. Don't argue and don't listen.

Just love each other.
Muslims, Christians, Jews - these religions based on one book, so there's ONE GOD for all these religions. So WHY there's reasons to hate somebody? So many stupid wars.
Even if somebody doesn't call God by that name as you want, is it reason to war?
Only God is love.
Love each other, people. Don't waste your life to hate.