SlideShare una empresa de Scribd logo
1 de 49
1
FenixTech System International
http://www.interadictos.es/cassandra-y-php-para-desarrolladores-sql/
Cassandra y PHP para desarrolladores SQL
Normalmente la mayoría de programadores trabajamos con bases de datos relacionales, utilizando
para interactuar con la BD un lenguaje llamado SQL (structured query language) lo que nos facilita
inmensamente la tarea de recuperar registros.
Sin embargo las bases de datos no-sql como Cassandra no disponen de este lenguage y nos vemos
obligados a aprender cómo funcionan. Y el aprendizaje puede ser algo confuso, debido a que estas
bases son bastante diferentes a lo que estamos acostumbrados.
Por eso he creado este tutorial, que te permitirá conocer cómo funciona Cassandra y cómo
interactuar con ella a través de las clases que nos ofrece PHPCassa, para trabajar con PHP
obviamente.
LISTADO DE TEMAS
Cassandra 1.x — PHPCassa 1.0.a.x
1. Instalación
2. El modelo de datos
3. La consola
4. Cassandra Cluster Admin, el phpMyAdmin de Cassandra
5. PHPCassa (I)
6. PHPCassa (II)
7. PHPCassa (III)
8. Clusters
Cassandra 0.8 — PHPCassa 0.8.a.2
1. Instalación
2. El modelo de datos
3. La consola
4. Cassandra Cluster Admin, el phpMyAdmin de Cassandra
5. PHPCassa (I)
6. PHPCassa (II)
7. PHPCassa (III)
8. Clusters
2
Cassandra 1.x y PHP para desarrolladores
SQL: Instalación
La base de datos No-SQLCassandra fue creada por Facebook a causa de la necesidad de disponer
de una base de datos distribuida de alto rendimiento, flexible, tolerante a fallos, escalable y que
fuese capaz de procesar grandes cantidades de datos, más tarde fue liberada bajo licencia Apache y
actualmente es utilizada principalmente por empresas de internet con proyectos con un alto uso de
base de datos como Twitter.
En esta serie de artículos iré desgranando la instalación, funcionamiento y desarrollo de aplicaciones
en PHP con Cassandra, comparando las sentencias utilizadas para insertar, actualizar, etc de SQL
con los métodos a utilizar en Cassandra. Por desgracia al ser algo completamente distinto a
cualquier base de datos SQL tendré que añadir algo de teoría, pero intentaré que os resulte lo más
ameno posible.
Al toro.
REQUISITOS
Para la realización de esta guía se utilizará Debian Squeeze como sistema operativo.
Doy por hecho que ya se dispone de un servidor web Apache con PHP instalado en la máquina de
testeo que se esté usando. Las aplicaciones que se van a instalar han sido probadas en una máquina
virtual Debian utilizando como aplicación de virtualización, VirtualBox instalado en un host
Windows XP SP3.
En un servidor de producción recomiendo que tenga bastante RAM (por encima de 1GB, ya
veremos más adelante el porqué. En la máquina virtual que uso de testeo dispone de 700 MB y
funciona bien, pero en producción no es lo recomendable).
Instalaremos la base de datos Cassandra, el protocolo para conectar con ella y que nos generará el
módulo para poder trabajar desde PHP, y PHPCassa que será la abstracción de la base de datos
donde tenemos los métodos básicos para trabajar con Cassandra: insertar, actualizar, borrar, crear,
etc.
PREPARANDO EL SISTEMA
Antes de empezar a instalar debemos actualizar el sistema operativos de la forma habitual:
apt-get update
apt-get upgrade
Una vez actualizado el sistema empezamos a instalar.
3
INSTALANDO CASSANDRA
Lo primero que necesitamos hacer para instalar Cassandra es editar los repositorios de Debian:
nano /etc/apt/sources.list
Una vez que se abra el editor añadimos las siguientes lineas:
deb http://www.apache.org/dist/cassandra/debian/ 11x main
deb-src http://www.apache.org/dist/cassandra/debian/ 11x main
Como podrás observar después de la ruta del repositorio se ha añadido “11x” esto indica el número
de versión a obtener, en este caso es la versión actual de cassandra al crear este post. No se indica el
número de parche, es decir, actualmente se puede descargar Cassandra 1.1.
Si dentro de unos meses sale la versión “1.2” solo tendrás que cambiar el uno por el dos.
Volvemos a consola y actualizamos los repositorios.
apt-get update
Nos dará un error en las claves gpg. Procedemos a actualizarlas con las siguientes instrucciones:
gpg --keyserver pgp.mit.edu --recv-keys F758CE318D77295D
gpg --export --armor F758CE318D77295D | sudo apt-key add -
Ojo con el guión del final, hay que añadirlo sino dará error.
Con el paquete 0.7.5 nos da otro error de clave gpg así que también instalamos esta de la misma
manera:
gpg --keyserver pgp.mit.edu --recv-keys 2B5C1B00
gpg --export --armor 2B5C1B00 | sudo apt-key add -
Verificamos que tenemos el sistema actualizado.
apt-get update
apt-get upgrade
Actualizamos todos los paquetes que aparezcan.
Procedemos a instalar el paquete de la base de datos NoSQL Cassandra:
apt-get install cassandra
Cassandra necesita a Java para funcionar para ello, una vez instalado Cassandra instalaremos el
paquete sun-java6-jdk de la siguiente manera:
apt-get install sun-java6-jdk
4
En el caso de que no encuentre el paquete verificar que los repositorios de Debian son correctos.
Verifica la versión de Java con:
java -version
Debería aparecer algo así:
java version "1.6.0_20"
Java(TM) SE Runtime Environment (build 1.6.0_20-b02)
Java HotSpot(TM) Client VM (build 16.3-b01, mixed mode, sharing)
Se recomienda usar la versión de Java de Sun (Sun JDK) en vez de Open JDK debido a un bug
encontrado en el mismo.
Si os muestra algo distinto a esto, escribid el siguiente comando:
update-alternatives --config javac
Os mostrará un listado con los diferentes paquetes instalados en el sistema que pueden ser utilizados
para trabajar con Java. Nosotros usaremos el paquete de Sun, así que pulsa el número del paquete
para que Debian lo utilice.
Por último, ejecutamos el siguiente comando para construir las dependencias:
dpkg-buildpackage -uc -us
INSTALANDO THRIFT Y LA EXTENSIÓN PARA PHP
[ci-box type=”info”]PHPCassa ya incluye Thrift en el archivo descargable, con lo que puedes
saltarte esta parte si quieres. En la sección de PHPCassa se trata la creación del archivo .so con los
archivos contenidos en el paquete de PHPCassa[/ci-box]
Thrift es tan solo el protocolo de conexión para poder utilizar Cassandra. Aunque en la extensión
para PHP existen métodos para poder trabajar con cassandra, requieren bastante código por eso
utilizaremos PHPCassa como abstracción de la base de datos.
Primero descargamos Thrift desde su web: http://thrift.apache.org/download/ y descomprimimos
tar -xzvf thrift-0.8.0.tar.gz
Nos colocamos dentro de la carpeta de Thrift.
Antes de hacer nada ahí instalamos algunos paquetes que nos serán necesarios:
apt-get install libboost-dev automake libtool flex bison pkg-config g++
Una vez instalados esos paquetes configuramos y construimos Thrift:
./configure
make
5
Construimos la interfaz de PHP Thrift para Cassandra:
./compiler/cpp/thrift -gen php ../ruta-a-cassandra/interface/cassandra.thrift
Copiamos archivos necesario para que PHPCassa funcione:
mkdir -p /usr/share/php/Thrift
cp -R gen-php/ /usr/share/php/Thrift/packages/
cp -R lib/php/src/* /usr/share/php/Thrift/
Cambiamos al directorio del protocolo de Thrif: ruta-a-thrift/lib/php/src/ext/thrift_protocol.
Instalamos el paquete para construir las extensiones de PHP:
apt-get install php5-dev
Construimos la extensión:
phpize
./configure --enable-thrift_protocol
make
Copiamos la extensión a la siguiente carpeta (cuidado: dependiendo del sistema el nombre de la
carpeta de destino puede variar):
cp modules/thrift_protocol.so /usr/lib/php5/20060613/
Habilitamos el módulo creando el archivo /etc/php5/conf.d/thrift_protocol.ini con el siguiente texto:
extension=thrift_protocol.so
Comprobamos la instalación:
php -i | grep -v "PWD" | grep "thrift_protocol"
Si todo ha ido bien, reiniciamos Apache:
/etc/init.d/apache2 restart
Iniciamos Cassandra:
/opt/cassandra/bin/cassandra
Y probamos la consola para comprobar que todo ha ido correctamente:
/opt/cassandra/bin/cassandra-cli -host localhost -port 9160
Debería indicarte algo así:
Connected to: "Test Cluster" on localhost/9160
6
Welcome to cassandra CLI.
INSTALANDO PHPCassa
Bajamos PHPCassa desde github: https://github.com/thobbs/phpcassa
Descomprimimos a una carpeta dentro del proyecto en el que vayamos a utilizar PHPCassa, para el
tutorial usaré /var/www/prueba_cassandra/phpcassa.
Si aun no has creado el archivo .so para que PHP pueda trabajar con Cassandra, escribe los
siguientes comandos en tu consola:
cd lib/thrift/ext/thrift_protocol
phpize
./configure
make
sudo make install
Una vez finalizados estos pasos edita el archivo php.ini y añade la siguiente línea:
extension=thrift_protocol.so
Con esto finalizamos la instalación de Cassandra para que pueda ser utilizada por PHP.
Cassandra 1.x y PHP para desarrolladores
SQL: El modelo de datos
Si has trabajado con una base de datos relacional tal vez te resulte algo confuso al principio
comprender el modelo de datos que usa Cassandra, intentaré ser lo más claro posible, pero si te
surgen preguntas no dudes en dejarlas en los comentarios.
Columnas
El elemento más básico de la base de datos Cassandra es la columna, se compone de tres elementos:
nombre de la columna, valor y timestamp. Os muestro un ejemplo como un array:
array(
"nombre" => "email",
"valor" => "webmaster@localhost.com",
"timestamp" => time(),
);
7
Super columnas
Es el conjunto de columnas con sus correspondientes valores:
array(
"nombre_superColumna" => array(
"usuario1" => array(
"nombre" => "email",
"valor" => "webmaster@localhost.com",
"timestamp" => time()
),
"usuario2" => array(
"nombre" => "email",
"valor" => "email@email.com",
"timestamp" => time()
),
"usuario3" => array(
"nombre" => "email",
"valor" => "otroemail@otroemail.com",
"timestamp" => time()
),
),
)
Familia de columnas
Es el conjunto de columnas o super columnas. Me explico:
Las column Family o familia de columnas se puede configurar de dos maneras: como Super o como
Standard. Si se elige la opción Standard, en la column family solo se podrán guardar columnas no
super columnas. En cambio si la column family está configurada como Super podrá guardar, además
de las columnas, las super columnas. Esta flexibilidad permite jugar con la base de datos y adaptarla
a nuestras necesidades.
Ejemplo:
array(
"name" => "ColumnFamily",
array( "name" => "SuperColumn",
array( "colums" )
),
)
Keyspace
El keyspace es nuestra base de datos, donde alojaremos todas las columFamilies que necesitemos.
Ejemplo:
array(
"name" => "keyspace",
8
array("name" => "columnFamily",
array(
[...]
),
),
)
Cassandra 1.x y PHP para desarrolladores
SQL: La consola
Cassandra dispone de una herramienta a través de la consola o shell para poder trabajar con ella.
Parecida a la de MySQL.
Para acceder a la consola solo tendremos que escribir lo siguiente:
> cassandra-cli
Si todo va bien nos aparecerá algo parecido al siguiente texto:
Welcome to Cassandra CLI version 1.0.7
Type 'help;' or '?' for help.
Type 'quit;' or 'exit;' to quit.
[default@unknown]
Ahora tenemos que conectar con la base de datos de la siguiente manera:
connect localhost/9160;
Fíjate que al final del comando hay un punto y coma. Hay que añadirlo, como si fuera una sentencia
SQL, sino te aparecerán unos puntos suspensivos para que finalices el comando. Si te ocurre esto
último, pon el punto y coma y pulsa enter. Te debería aparecer algo como lo siguiente:
Connected to: "Test Cluster" on localhost/9160
Hay una forma de resumir los pasos anteriores en una sola linea:
> cassandra-cli -h localhost -p 9160
Ahora vamos a mostrar los keyspaces que tiene la base de datos actualmente:
show keyspaces;
[ci-box type=”warning”]Recuerda poner el punto y coma.[/ci-box]
Este comando te mostrará un listado de los keyspaces y sus column families que se encuentran en la
BD, además de información relevante sobre las propiedades, tanto de los keyspaces como de sus
column families correspondientes.
9
El objetivo de este post no es explicar con detalle cada propiedad de los keyspaces y las column
families (he de admitir que muchas de ellas las desconozco), sino mostrar y enseñar la forma de
trabajar por consola con Cassandra.
Vamos al lío.
CREAR UN KEYSPACE
Tan sencillo como la siguiente sentencia:
create keyspace my_keyspace;
Después de dos o tres segundos te mostrará algo como esto:
b511da50-88c0-11e1-0000-242d50cf1fff
Waiting for schema agreement...
... schemas agree across the cluster
ACCEDER A UN KEYSPACE
Igual de sencillo:
use my_keyspace;
Ahora que ya estamos dentro de nuestro keyspace, toca añadir column families.
CREAR COLUMN FAMILIES
Muy sencillo:
create column family my_column_family;
Añadamos datos.
AÑADIR DATOS A UNA COLUMN FAMILY
En MySQL utilizaríamos una sentencia INSERT para añadir información a una tabla concreta, en la
que anteriormente habremos creado sus columnas. En Cassandra no hay que crearlas con antelación.
(En realidad se puede utilizar un archivo para configurar el esquema del keyspace dando las
10
propiedades adecuadas a cada column family y sus respectivas columnas, pero para iniciarnos en
Cassandra y aprender su funcionamiento no es necesario).
Para no complicarnos mucho primero vamos a configurar la column family.
Las column families disponen de diferentes tipos de codificación de datos para guardar los datos, es
decir, si guardamos información en UTF-8 y nuestra column family está configurada como ASCII o
Bytes nuestros datos se guardarán, sí, pero al recuperarla solo veremos un batiburrillo de número y
letras.
Para evitar esto configuramos la column family para que guarde los datos en UTF-8:
assume my_column_family keys as utf8;
assume my_column_family comparator as utf8;
assume my_column_family validator as utf8;
Ahora ya podemos crear nuestro primer registro:
set my_column_family['1']['nombre'] = 'pepito';
set my_column_family['1']['edad'] = '120';
Si ejecutamos el siguiente comando:
get my_column_family['1'];
Nos devolverá las columnas que tuviese la fila con id = 1, junto con los correspondientes valores de
esas columnas.
Esto es el funcionamiento básico de la consola de Cassandra. Hay muchos más comandos para
obtener información de Cassandra y realizar algunas tareas más, para obtener la ayuda y ver estos
comandos solo tienes que escribir lo siguiente:
help;
¿Fácil verdad? Por último, para salir de la consola:
quit;
Cassandra 1.x y PHP para desarrolladores
SQL: Cassandra Cluster Admin, el
phpMyAdmin de Cassandra
En el anterior post expliqué el funcionamiento de la consola de Cassandra y como trabajar con ella.
En este post explicaré como hacer lo mismo de una forma más rápida y fácil.
11
La razón de que no haya empezado ha explicar como se utiliza Cassandra desde PHP, es que
primero hay que conocer cómo funciona Cassandra, su modelo de datos (que ya hemos visto) y
algunos comandos básicos para ir aprendiendo a guardar y recuperar datos. El próximo post ya
trataré el funcionamiento de PHPCassa y empezaremos a programar.
Este post será bastante ligerito. Explicaré principalmente como hacer lo mismo que hicimos por
consola pero de modo gráfico. CassAdmin, como yo le llamo, tiene más opciones de edición para
los keyspaces y column families de los que vamos a ver (igual que ocurría con la consola), pero solo
tocaremos las opciones más habituales.
INSTALACIÓN
Lo típico en estos casos. Descargar. Descomprimir y ejecutar. Descargamos los archivos desde el
repositorio de git: https://github.com/sebgiroux/Cassandra-Cluster-Admin, o a través de git o como
archivo comprimido. Como más te guste.
Proceso para descargar Cassandra Cluster Admin
12
Página de descargas del administrador
Ahora descomprimimos a una carpeta dentro de nuestro servidor web, ya que trabajamos con una
aplicación programada en PHP.
Si tienes Cassandra instalado en otro equipo que no sea en local, una máquina virtual por ejemplo,
tendrás que cambiar la ip a la que se conecta cassAdmin. Es bastante sencillo. Para ello debes
modificar el archivo includes/config.inc.php y sustituir la ip de localhost (127.0.0.1) por la ip del
equipo en el que tengas instalado Cassandra:
13
Archivo config.inc.php
Comoverásen la captura,yo utilizolaiplocal 192.168.1.10 que pertenece aunamáquinavirtual.Si tuviera
instaladoCassandraen el mismoequipolaipa laque deberíaapuntar sería 127.0.0.1. El puertono lo
modificamos.
Una vez instalado y configurado (si fuese el caso) probamos a acceder desde nuestro navegador.
Debería mostrarte algo como esto:
Página principal de Cassandra Cluster Admin
14
CREAR KEYSPACES
Como has podido ver, en la página principal del administrador ya aparece un keyspace, llamado
system, perteneciente a Cassandra, con lo que lo mantendremos como está.
Justo encima tenemos un botón para crear un nuevo keyspace (Create a new keyspace). Lo
pulsamos.
Formulario para crear un keyspace
Solo nos pide tres parámetros a rellenar:
Keyspace name: El nombre del keyspace a crear.
Replication factor: Es el número de servidores o instancias de Cassandra de los que se debe
guardar un registro u obtener una respuesta al recuperar algún registro.
Strategy: Es la estrategia que seguirá Cassandra para guardar los datos. En el caso de tener varios
servidores o centro de datos diferenciados entre sí, se aplicará una estrategia u otra para que los
datos no se pierdan. Más info: http://answers.oreilly.com/topic/2408-replica-placement-strategies-
when-using-cassandra/
En nuestro caso escribiremos los siguientes valores:
Formulario para crear un keyspace con datos
Pulsamos en Create keyspace y nos llevará a la página principal:
15
Página principal mostrando el keyspace que acabamos de crear
Pulsamos sobre el keyspace que acabamos de crear y nos llevará a la siguiente página:
Página de detalle del keyspace my_keyspace
Aquí podemos ver información relativa al keyspace y al anillo (o cluster) en el que se encuentra
guardado. También nos permite editar el keyspace o eliminarlo, pero la opción más interesante es la
de crear nuevas column families (Create a new column family).
16
CREAR UNA COLUMN FAMILY
Dentro del keyspace pulsamos sobre el botón Create a new column family, nos mostrará lo
siguiente:
Formulario para crear una column family
Primero crearemos una column family standard con los siguientes datos:
17
Datos para crear la primera column family
Para crear una column family solo son necesarios tres parámetros:
Column Family Name: El nombre de la column family que vamos a crear.
Column Type: El tipo de column family que vamos a crear (Standard o Super).
Comparator Type: El comparador principal de las columnas. Es decir, la codificación que tendrán
los datos dentro de la column family.
Pulsamos en Create Column Family y en la página de nuestro keyspace se habrá añadido una nueva
column family:
Detalle de la column family creada
AÑADIR REGISTROS A UNA COLUMN FAMILY STANDARD
Ahora toca guardar registros en la BD.
Como comenté en post anteriores Cassandra no necesita conocer los campos de las tablas (nuestras
column families) ya que los creamos cada vez que añadimos un registro.
Primero en la página principal del keyspace haz click en el nombre de la column family. Te
aparecerá lo siguiente:
18
Detalle de la página principal de la column family creada
En esta página te aparecerá, además de la información referente a la column family, los siguientes
botones:
Browse Data: Para mostrar un listado de los registros que contiene la column family.
Create Secondary Index: Para crear indices secundarios. Parecido a los indices de MySQL.
Get Key: Para buscar una clave o registro concreto.
Insert Row: Para insertar un nuevo registro.
Edit Column Family: Para editar los parámetros de la column family.
Truncate Column Family: Para eliminar los registros de la column family sin eliminar esta.
Drop Column Family: Para eliminar la column family y su contenido.
Pulsamos en Insert Row. Nos aparecerá lo siguiente:
Formulario para insertar registros
Siempre que añadamos un nuevo registro deberemos indicar una key diferente que deberá ser única,
sino cassAdmin pensará que lo que quieres hacer es actualizar ese registro. Añadimos los siguientes
datos al formulario:
19
Formulario para insertar registros con datos
Para añadir otra fila de cuadro de texto solo tienes que pulsar el botón Add…
Volvemos a la página principal de la column family y pulsamos en Browse Data. Aquí veremos un
listado con los registros que hayamos añadido:
Listado de registros
CREAR UNA COLUMN FAMILY SUPER Y AÑADIR REGISTROS
El proceso para crear una column family Super es idéntico a las column family Standard, solo hay
que cambiar un valor a la hora de crearla:
Creación de una column family Super
20
Entramos en la página principal de la nueva column family y pulsamos en Insert Row. Aquí veremos
que el formulario a cambiado un poco, nos aparece un nuevo campo llamado Super Column Name y
un nuevo botón encima del formulario, Add Super Column:
Formulario para insertar registros de una column family super
Las column family Super son como las muñecas matrioskas, esas figuras que si las abrías había otra
igual dentro, y dentro de esa otra más, y otra, etc. Algo parecido sucede con estas column family.
Disponemos de una key (nuestra primera matrioska) que contiene a las super columns (segunda
matrioska), que a su vez contienen las columnas clave:valor.
Añadamos un registro para verlo:
Datos para crear una super column
Si nos vamos a Browse Data:
21
Listado de registros en una column family Super
Como ves, ahora las columns se agruparían dentro de la super column. Añadiré más registros para
que lo veas mejor:
Listado de registros en una column family Super
¿Ves? Las keys agrupan a las super columns y estas a su vez a las columns.
Creo que esto es suficiente para que conozcas el funcionamiento de Cassandra Cluster Admin.
Quedarían algunas cosillas, como editar registros, hacer búsquedas o eliminar registros, pero eso es
bastante sencillo (a excepción de las Secondary Index y las Counter Columns que trataré más
adelante).
Para cualquier duda o problema déjala en los comentarios.
Cassandra 1.x y PHP para desarrolladores
SQL: PHPCassa (I)
22
¡Por fin llego el día! ¡Hoy toca programar!
Para ello vamos a utilizar las clases de abstracción de la base de datos PHPCassa que nos ahorrará
bastante tiempo para trabajar con Cassandra. Puedes descargarlo desde
https://github.com/thobbs/phpcassa.
Ubicamos PHPCassa en una carpeta dentro de nuestro servidor web y creamos dos archivos. Yo los
he llamado test.php y cassandra.php. El segundo será una clase que nos ahorrará algunas lineas de
código con las tareas habituales. El primero lo utilizaré para testear la clase y sus respectivos
métodos.
Bien empecemos.
PRIMEROS PASOS
En primer lugar necesitamos incluir un archivo de PHPCassa en cassandra.php:
Códigofuente
1. <?php
2.
3. // CLASES NECESARIAS PARA CONECTAR CON CASSANDRA
4. require_once('phpcassa/lib/autoload.php');
He inmediatamente llamamos a los namespace mínimos para trabajar con PHPCassa:
Códigofuente
1. <?php
2.
3. use phpcassaConnectionConnectionPool;
4. use phpcassaColumnFamily;
5. use phpcassaSystemManager;
6. use phpcassaSchemaStrategyClass;
Justo debajo creamos la clase:
Códigofuente
1. <?php
2.
3. class cassandra {
4.
23
5. }
CONECTANDO
Para realizar la conexión a la BD, PHPCassa nos pide tan solo un dato obligatorio: el nombre del
keyspace con el que vamos a trabajar. También nos permite añadir las ips de los nodos con los que
queramos trabajar, aunque por defecto su valor es localhost. Por tanto podemos crear un constructor
como el siguiente:
Códigofuente
1. <?php
2.
3. function __construct($keyspace, $nodos = array('localhost')){
4. if (!empty($keyspace)){
5. $this->conexion = new ConnectionPool($keyspace, $nodos);
6. }else{
7. print "El keyspace está vacío";
8. }
9. }
Este constructor nos permite indicarle a la clase el keyspace con el que queremos trabajar y la ip o
nombre de servidor donde se encuentre nuestra instancia de Cassandra. Por defecto el puerto al que
se va a conectar es el 9160. Si hubieses configurado Cassandra para escuchar en otro puerto deberás
especificarlo: localhost:9160.
Este código nos crea una variable llamada conexion que será una instancia del objeto
ConnectionPool, necesario para todas las consultas a la BD
GUARDANDO REGISTROS
Ahora procedemos a crear el método que guardará los registros. Para ello primero crearemos un
objeto ColumnFamily al que le pasaremos el nombre de la column family en la que queremos
trabajar:
Códigofuente
1. <?php
2.
3. public function guardar($name_columnFamily, $key, $data = array()){
4. try {
5. $column_family = new ColumnFamily($this->conexion,
$name_columnFamily);
6. $column_family->insert($key, $data);
7. return true;
24
8. }catch(Exception $e){
9. return false;
10. }
11. }
Este método nos devolverá true si se ha guardado correctamente el registro, o false en caso de error.
Como puedes ver, al objeto ColumnFamily se le pasa como primer parámetro el objeto
ConnectionPool que creamos en el constructor, después se le pasa el nombre de la column family.
Una vez creado el objeto ColumnFamily ya podemos utilizar el método insert para guardar el
registro pasándole como parámetros la key y un array con las columnas y sus respectivos valores.
RECUPERANDO REGISTROS
Recuperar registros de Cassandra es algo más complejo que guardarlos:
Primero debemos añadir un nuevo namespace que nos permitirá usar una clase que nos será muy
útil. El listado de namespaces nos quedaría así:
Códigofuente
1. <?php
2.
3. use phpcassaConnectionConnectionPool;
4. use phpcassaColumnFamily;
5. use phpcassaColumnSlice;
6. use phpcassaSystemManager;
7. use phpcassaSchemaStrategyClass;
A continuación creamos el método en nuestro archivo cassandra.php:
Códigofuente
1. <?php
2.
3. public function obtener($name_columnFamily, $key, $column_names= NULL,
$range_start = "", $range_end = "", $column_count = 100,
$invertir_orden=false){
4.
5. try{
6. $column_slices = new ColumnSlice($range_start, $range_end,
$column_count, $invertir_orden);
7. $column_family = new ColumnFamily($this->conexion,
$name_columnFamily);
8. $result = $column_family->get($key, $column_slices, $column_names);
9. }catch(Exception $e){
10. return false;
25
11. }
12.
13. return $result;
14.
15. }
Este método tiene algunos parámetros más que al guardar, pero tienen su razón de ser:
$columnFamily: Nombre de la column family donde buscar.
$key: Clave del registro donde buscar.
$columns: Columnas a buscar. No es obligatorio. Por defecto NULL.
$range_start: Key por la que Cassandra debe empezar a recuperar registros. No es obligatorio. Por
defecto “”.$range_end: Key por la que Cassandra dejará de recuperar registros. No es obligatorio.
Por defecto “”.
$column_count: Número de registros a obtener, Por defecto 100.
$invertir_orden: Invierte el orden en el que se recuperar los registros. De mayor a menor o
viceversa, de la A-Z o viceversa, etc.
Como ves tienes bastantes opciones para recuperar registros. Este método devuelve un array con los
registros.
PROBANDO LA CLASE
Vamos a probar el código a ver que tal funciona. Nos vamos al archivo test.php y escribimos el
siguiente código:
Códigofuente
1. <?php
2.
3. include_once "cassandra.php";
4.
5. $cass = new cassandra('my_keyspace', array('192.168.1.10'));
6.
7. $data = array(
8. 'nombre' => 'pepito',
9. 'ciudad' => 'Madrid',
10. 'vehiculo' => 'coche',
11. );
12.
13. if ( $cass->guardar('my_column_family_standard', $key=1, $data)){
14. print "El registro se ha guardado correctamente<br />";
15. }else{
16. print "Error al guardar el registro<br />";
17. }
18.
19. $result = $cass->obtener('my_column_family_standard', $key=1);
26
20.
21. print_r($result);
22. ?>
Explico un poco el código anterior:
1. Incluimoslaclase enel archivo.
2. Creamosel objetoindicándole el keyspaceconel que trabajar(my_keyspace),ydentrode un array,
la ipdonde se encuentraennodode Cassandra.Si tuviesesCassandrainstaladoenlocalhostno
sería necesarioindicarel segundoparámetro.
3. Creamosel array que contendrálosdatosa guardar.
4. Creamosun condicional que guardarálosdatosenCassandray nos indicarási se han guardado
correctamente oha habidoalgúnerror.
5. Guardamosen unavariable ($result) losregistrosque recuperamosatravésdel método obtenerdel
objeto$cass.A este métodole indicamoslacolumn family a buscar y lakey a obtener.
6. Mostramos losregistros.
Si todo ha salido correctamente verás un texto como el siguiente cuando ejecutes el script:
El registro se ha guardado correctamente
Array ( [ciudad] => Madrid [nombre] => pepito [vehiculo] => coche )
Si te aparecen más registros es posible que no vaciases las column family con la que trabajas.
Simplemente ves a Cassandra Cluster Admin, entra en la column family y pulsa en Truncate Column
Family. Así eliminarás todos los datos de la column family.
ACTUALIZAR UN REGISTRO
Ahora que ya funciona nuestra clase podemos ampliarla con nuevas características.
Aunque pienses que para actualizar un registro es necesario un nuevo método, en Cassandra no es
necesario, simplemente utilizaremos el método guardar indicandole la key a modificar y el array con
los datos a guardar.
Justo debajo del código que ya tenemos en el archivo test.php escribimos lo siguiente:
Códigofuente
1. <?php
2.
3. $data = array(
4. 'ciudad' => 'Barcelona',
5. );
6.
7. if ( $cass->guardar('my_column_family_standard', $key=1, $data)){
8. print "El registro se ha guardado correctamente<br />";
9. }else{
10. print "Error al guardar el registro<br />";
11. }
27
12.
13. $result = $cass->obtener('my_column_family_standard', $key=1);
14.
15. print_r($result);
Como observarás el array no tiene todos los datos de la key que vamos a modificar, ya que no es
necesario, tan solo pasaremos los datos que queremos actualizar. El resultado de este código es el
siguiente:
El registro se ha guardado correctamente
Array ( [ciudad] => Madrid [nombre] => pepito [vehiculo] => coche )
El registro se ha guardado correctamente
Array ( [ciudad] => Barcelona [nombre] => pepito [vehiculo] => coche )
La columna ciudad a cambiado, el resto sigue igual, la razón está en que cuando le pasas a
Cassandra una key que ya existe, lo que hace es actualizar las columnas que se correspondan con las
keys del array. Si en ese array hubiera keys que no existen como columnas en el registro, Cassandra
simplemente las crearía nuevas.
GUARDANDO UNA SUPER COLUMN
Aquí tampoco nos hace falta crear un nuevo método ya que nos sirve perfectamente el método
guardar, pero deberemos hacerle algunas modificaciones.
En primer lugar, para trabajar con column families super es necesario añadir una llamada al
namespace concreto. La lista de namespaces quedaría de la siguiente manera:
Códigofuente
1. <?php
2.
3. use phpcassaConnectionConnectionPool;
4. use phpcassaColumnFamily;
5. use phpcassaSuperColumnFamily;
6. use phpcassaColumnSlice;
7. use phpcassaSystemManager;
8. use phpcassaSchemaStrategyClass;
Ahora debemos modificar el método guardar y añadirle el parámetro $is_super_column, que nos
permitirá crear un objeto SuperColumnFamily o ColumnFamily según corresponda. El método nos
quedaría así:
Códigofuente
1. <?php
2.
28
3. public function guardar($name_columnFamily, $key, $data = array(),
$is_super_column = false){
4.
5. try {
6. if ($is_super_column){
7. $column_family = new SuperColumnFamily($this->conexion,
$name_columnFamily);
8. }
9. else{
10. $column_family = new ColumnFamily($this->conexion,
$name_columnFamily);
11. }
12.
13. $column_family->insert($key, $data);
14. return true;
15. }catch(Exception $e){
16. return false;
17. }
18. }
Como ambas clases comparten el método insert no nos hace falta incluir esa linea dentro del
condicional.
A continuación modificamos el método obtener con el mismo parámetro y utilizando el mismo
sistema para crear el objeto correspondiente:
Códigofuente
1. <?php
2.
3. public function obtener($name_columnFamily, $key,
$is_super_column=false, $column_names= NULL, $range_start = "", $range_end
= "", $column_count = 100, $invertir_orden=false){
4.
5. try{
6. if ($is_super_column){
7. $column_family = new SuperColumnFamily($this->conexion,
$name_columnFamily);
8. }
9. else{
10. $column_family = new ColumnFamily($this->conexion,
$name_columnFamily);
11. }
12. $column_slices = new ColumnSlice($range_start, $range_end,
$column_count, $invertir_orden);
13. $result = $column_family->get($key, $column_slices, $column_names);
14. }catch(Exception $e){
15. return false;
16. }
17.
18. return $result;
19.
20. }
Ahora podemos añadir el siguiente código a nuestro archivo test.php:
29
Códigofuente
1. <?php
2.
3. $data = array('vecino_1' => array(
4. 'nombre' => 'pepito',
5. 'ciudad' => 'Madrid',
6. 'vehiculo' => 'coche',
7. ));
8.
9. if ( $cass->guardar('my_column_family_super', $key=1, $data,
$is_super_column=true)){
10. print "El registro se ha guardado correctamente<br />";
11. }else{
12. print "Error al guardar el registro<br />";
13. }
14.
15. $result = $cass->obtener('my_column_family_super', $key=1,
$is_super_column=true);
16.
17. print_r($result);
El único cambio además del nombre de la column family donde vamos a guardar el registro, se
encuentra en el array con los datos. Este tiene un elemento que es la key de la super column, y como
valor, el array de las columns a guardar.
Si ejecutamos el código anterior nos devolverá lo siguiente:
El registro se ha guardado correctamente
Array ( [vecino_1] => Array ( [ciudad] => Madrid [nombre] => pepito [vehiculo]
=> coche ) )
[ci-box type=”warning”]Al probar el código, PHP me devolvió el siguiente aviso:
Strict Standards: Declaration of phpcassaSuperColumnFamily::add() should be compatible with
that of phpcassaColumnFamily::add()
in /var/www/prueba_cassandra/phpcassa/lib/phpcassa/SuperColumnFamily.php on line 491.
No te preocupes no afecta ni a los ejemplos ni a la clase que funcionan correctamente.[/ci-box]
ACTUALIZANDO UNA SUPER COLUMN
La actualización de una super column se limita a las columnas que contienen los valores del registro
no a su key. Si modificáramos la key , lo que en realidad estaríamos haciendo sería crear una nueva
super column. Añadimos el siguiente código a nuestro archivo test.php:
Códigofuente
1. <?php
2.
3. $data = array('vecino_1' => array(
30
4. 'nombre' => 'pepito',
5. 'ciudad' => 'Barcelona',
6. 'vehiculo' => 'coche',
7. ));
8.
9. if ( $cass->guardar('my_column_family_super', $key1, $data,
$is_super_column=true)){
10. print "El registro se ha guardado correctamente<br />";
11. }else{
12. print "Error al guardar el registro<br />";
13. }
14.
15. $result = $cass->obtener('my_column_family_super', $key=1,
$is_super_column=true);
16.
17. print_r($result);
Y el resultado es:
El registro se ha guardado correctamente
Array ( [vecino_1] => Array ( [ciudad] => Barcelona [nombre] => pepito
[vehiculo] => coche ) )
ELIMINAR REGISTROS
Sí, aquí toca crear un nuevo método para nuestra clase en cassandra.php, aunque tampoco nos
vamos a matar programando:
Códigofuente
1. <?php
2.
3. public function eliminar($name_columnFamily, $key, $is_super_column =
false){
4.
5. try{
6. if ($is_super_column){
7. $column_family = new SuperColumnFamily($this->conexion,
$name_columnFamily);
8. }
9. else{
10. $column_family = new ColumnFamily($this->conexion,
$name_columnFamily);
11. }
12. $column_family->remove($key);
13. return true;
14. }catch(Exception $e){
15. return false;
16. }
31
17. }
El método es bastante sencillo: se le pasan tres parámetros que ya conocemos.
Dentro del método se crea un objeto ColumnFamily y se utiliza el método remove para eliminar el
registro pasándole la key correspondiente, y si fuese una super column, la key de este.
El método remove tiene un segundo parámetro que por defecto tiene un valor null, en él se pueden
añadir como array los nombres de las columnas a eliminar. Como no es habitual ese proceso he
creído adecuado no utilizarlo.
Una vez añadido esté método a nuestra clase modificamos el archivo test.php con el siguiente
código:
Códigofuente
1. <?php
2.
3. if ( $cass->eliminar('my_column_family_standard', $key=1)){
4. print "El registro se ha eliminado correctamente<br />";
5. }else{
6. print "Error al eliminar el registro<br />";
7. }
8.
9. $result = $cass->obtener('my_column_family_standard', $key=1);
10.
11. print_r($result);
Y el resultado es:
El registro se ha eliminado correctamente
De momento con esto es suficiente, dejo en tus manos estos métodos para que juegues con ellos
todo lo que quieras y te familiarices con PHPCassa.
En el próximo post trataré las Counter Columns que nos servirán para contar registros, los
Secondary Index que nos permitirán realizar búsquedas por columnas concretas, y algunas cosas
más.
Cassandra 1.x y PHP para desarrolladores
SQL: phpCassa (II)
32
En el anterior post traté las acciones habituales que realizamos con Cassandra: guardar, actualizar y
eliminar. Sin embargo aun quedan dos acciones muy útiles por tratar: los contadores y los indices
secundarios.
CONTADORES
Los contadores son en realidad un tipo especial de validador de Column Family.
CREAR UN CONTADOR
Para crearla procedemos de la siguiente manera:
– Accedemos a Cassandra Cluster Admin:
Página principal de Cassandra Cluster Admin
– Entramos en el keyspace con el que estamos trabajando:
33
Detalle del keyspace my_keyspace
– Pulsamos en Create New Column Family y escribimos los siguientes datos:
Datos para crear una Column Family con contadores
– En Default Validation Class el texto completo a escribir es:
34
org.apache.cassandra.db.marshal.CounterColumnType
– Y pulsamos el botón Create Column Family.
Varias cosas sobre los CounterColumn:
– Para crear los CounterColumns es obligatorio indicar en Default Validation Class la clase de
validador correcto. Indicado más arriba.
– Los contadores puedes tener números positivos o negativos.
– Los CounterColumns no son un sustituto de el autoincrement de las bases relacionales.
Ahora que ya está creada la Column Family es hora de programar.
GUARDAR Y/O ACTUALIZAR UN CONTADOR
En nuestra clase en cassandra.php creamos el siguiente método:
Códigofuente
1. <?php
2.
3. public function guardarContador($name_columnFamily, $key, $column,
$value=1, $super_column=NULL){
4.
5. try {
6. if (!is_null($super_column)){
7. $column_family = new SuperColumnFamily($this->conexion,
$name_columnFamily);
8. $column_family->add($key, $super_column, $column, $value);
9. }
10. else{
11. $column_family = new ColumnFamily($this->conexion,
$name_columnFamily);
12. $column_family->add($key, $column, $value);
13. }
14. return true;
15. }
16. catch(Exception $e){
17. return false;
18. }
19. }
Con este método podremos incrementar o disminuir el contador.
$name_columnFamily: Es el nombre de la column family donde se encuentra el contador a
modificar.
35
$key: Clave del registro donde se encuentra el contador.
$column: Nombre del contador.
$value: Valor a añadir al contador.
$super_column: Clave de la super column donde se encuentra el contador.
Añadimos el siguiente código a nuestro archivo test.php:
Códigofuente
1. <?php
2.
3. if ( $cass->guardarContador('column_family_counter', 'post',
'num_total_post', 1)){
4. print "El contador se ha actualizado correctamente<br />";
5. }else{
6. print "Error al actualizar el contador<br />";
7. }
8.
9. $result = $cass->obtener('column_family_counter', 'post');
10.
11. print_r($result);
Como ves, para recuperar un contador se utiliza el mismo método que para obtener cualquier otro
registro. El resultado de este código sería:
El contador se ha actualizado correctamente
Array ( [num_total_post] => 1 )
PONER A CERO EL CONTADOR
Para poner a cero un contador hay que restarle el valor que tenga en ese momento el contador. En
test.php escribiríamos lo siguiente:
Códigofuente
1. <?php
2.
3. if ( $cass->guardarContador('column_family_counter', 'post',
'num_total_post', ($result['num_total_post']*-1))){
4. print "El contador se ha actualizado correctamente<br />";
5. }else{
6. print "Error al actualizar el contador<br />";
7. }
8.
9. $result = $cass->obtener('column_family_counter', 'post');
10.
11. print_r($result);
36
Y el resultado:
El contador se ha actualizado correctamente
Array ( [num_total_post] => 0 )
INDICES SECUNDARIOS
Los indices secundarios son un objeto especial en Cassandra que nos permite realizar búsquedas por
columnas concretas.
Estos índices solo funcionan en las column family standard, con lo que su uso se ve bastante
limitado.
CREAR UN INDICE SECUNDARIO
Para ello vamos a nuestro Cassandra Cluster Admin y en la column family
my_column_family_standard pulsamos en Create Secondary Index:
Detalle de la ubicación del botón Create Secondary Index
– Nos aparecerá el siguiente formulario:
Detalle del formulario para crear un índice secundario
– Para nuestro cometido vamos a crear el siguiente índice secundario:
37
Formulario con los datos para el ejemplo
– Pulsamos en Add Secondary Index.
REALIZAR UNA CONSULTA CON UN INDICE SECUNDARIO
Nos vamos a nuestro archivo cassandra.php y añadimos el siguiente método:
Códigofuente
1. <?php
2.
3. private function getIndexOperator($value){
4. switch ($value){
5. case '=':
6. $operator = 'EQ';
7. break;
8. case '>=':
9. $operator = 'GTE';
10. break;
11. case '>':
12. $operator = 'GT';
13. break;
14. case '<=':
15. $operator = 'LTE';
16. break;
17. case '<':
18. $operator = 'LT';
19. break;
20. default:
21. $operator = 'EQ';
22. break;
23. }
24.
25. return $operator;
26. }
Este método nos permitirá trabajar con operadores diferentes a la igualdad, pudiendo utilizar
>,<,>=,<=.
38
Pero para poder trabajar con índices es necesario incluir en nuestro listado de namespaces dos
nuevas clases, tal y como se muestra en el siguiente código:
Códigofuente
1. <?php
2.
3. use phpcassaConnectionConnectionPool;
4. use phpcassaColumnFamily;
5. use phpcassaSuperColumnFamily;
6. use phpcassaColumnSlice;
7. use phpcassaSystemManager;
8. use phpcassaSchemaStrategyClass;
9. use phpcassaIndexIndexExpression;
10. use phpcassaIndexIndexClause;
A continuación creamos el método que generará la consulta con los índices secundarios.
Códigofuente
1. <?php
2.
3. public function obtenerPorIndices($name_columnFamily,
$arrayColumnsValues, $range_start = "", $range_end = '', $column_count =
100, $invertir_orden = false){
4.
5. try{
6. // Creamos el objeto
7. $column_family = new ColumnFamily($this->conexion,
$name_columnFamily);
8.
9. // Inicializamos las variables
10. $index_exp = array();
11. $registros = array();
12.
13. // Creamos un array de index_expression
14. foreach($arrayColumnsValues as $key => $value){
15. if (array_key_exists('operator', $value)){
16. $op = $this->getIndexOperator($value['operator']);
17. }
18. else{
19. $this->getIndexOperator('=');
20. }
21.
22. $column = $value['values'];
23. $key_column = key($column);
24.
25. $index_exp[] = new IndexExpression($key_column,
$column[$key_column], $op);
26. }
27.
28. // Creamos la index_clause
29. $index_clause = new IndexClause($index_exp, $range_start,
$column_count);
39
30.
31. // Creamos la column_slice
32. $column_slice = new ColumnSlice($range_start, $range_end,
$column_count, $invertir_orden);
33.
34. // Recuperamos los registros
35. $rows = $column_family->get_indexed_slices($index_clause,
$column_slice);
36.
37. foreach($rows as $key => $columns){
38. if (!array_key_exists($key, $registros)){ $registros[$key] =
null; }
39. $registros[$key] = $columns;
40. }
41. return $registros;
42. }catch (Exception $e){
43. return false;
44. }
45. }
Con este método podremos buscar registros con varios índices secundarios.
Lo primero que hacemos en este método es crear el objeto ColumnFamily que nos proveerá de los
métodos para hacer la consulta con indices secundarios. A continuación inicializamos varias
variables necesarias para el método.
Dentro de un bucle creamos un array de IndexExpression(). Este objeto le indicará a Cassandra qué
indices, con qué valores y qué operador se deben buscar los registros.
Seguidamente creamos la iIndexClause(), que nos permite indicarle la key desde la que comenzará a
recuperar registros y el número de registros a obtener.
Por último recuperamos los registros utilizando el método get_indexed_slices().
Para probar el método vamos a crear datos de prueba en test.php y haremos la consulta:
Códigofuente
1. <?php
2.
3. $data[] = array(
4. 'title' => 'Apache Cassandra',
5. 'license' => 'Open Source',
6. 'category' => 'no-sql',
7. );
8.
9. $data[] = array(
10. 'title' => 'MongoDB',
11. 'license' => 'Open Source',
12. 'category' => 'no-sql',
40
13. );
14.
15. $data[] = array(
16. 'title' => 'MySQL',
17. 'license' => 'Open Source',
18. 'category' => 'sql',
19. );
20.
21. foreach($data as $key => $value){
22. $cass->guardar('my_column_family_standard', $key, $value);
23. }
24.
25. $arrayColumnsValues[] = array(
26. 'values' => array(
27. 'category' => 'no-sql'
28. ),
29. 'operator' => '='
30. );
31.
32. $result = $cass->obtenerPorIndices('my_column_family_standard',
$arrayColumnsValues);
33.
34. print_r($result);
Si ejecutamos el código anterior Cassandra nos devolverá:
Array ( [0] => Array ( [title] => Apache Cassandra [license] => Open Source
[category] => no-sql ) [1] => Array ( [title] => MongoDB [license] => Open
Source [category] => no-sql ) )
[ci-box type=”warning”]Al utilizar un operador diferente al = puede que Cassandra te devuelva un
error. Para evitarlo añade otro indice secundario a la consulta pero con el operador =, siendo este la
primera columna que Cassandra procese. Por alguna razón Cassandra devuelve un error si no se
hace así. [/ci-box]
Con este post concluye la parte básica de PHPCassa, Cassandra y Cassandra Cluster Admin. En el
próximo post y siguientes trataré varios temas que se han quedado un poco colgados o faltan por
explicar como ordenar registros, cómo crear claves, mejorar el rendimiento de Cassandra, crear
clusters, etc.
Cassandra 1.x y PHP para desarrolladores
SQL: phpCassa (III)
Ya he tratado casi en su totalidad las funciones más básicas de PHPCassa y Cassandra, con lo que
ya tendrás un conocimiento suficientemente amplio de lo que se puede hacer con ellos, el resto
dependerá de la evolución de la BD y de las librerías (y de la experiencia que tengas xP).
41
Hoy trataré varios temas que por las consultas realizadas por varios usuarios se merece un post
aparte en el que se pueda tratar de una forma más amplia. Estos temas son: ordenar registros, crear
keys para los registros y contar registros.
ORDENAR REGISTROS
Cassandra dispone de varios tipos de comparadores y subcomparadores para ordenar los registros.
El más habitual es UTF-8 pero hay varios más. Si vamos a Cassandra Cluster Admin y accedemos al
formulario de creación de columns family, podremos pasar el ratón por los interrogantes que hay a la
izquierda de los campos para poder ver los diferentes tipos de comparadores:
Tipos de comparadores
Como puedes ver, estos comparadores le dicen a Cassandra como ordenar los registros. Si has
seguido este tutorial ya conocerás al menos uno de los comparadores (utf-8) por tanto vamos a ver
como ordena Cassandra los registros con este comparador.
Para este primer ejemplo vamos a crear una column family llamada column_family_order_utf8 de
tipo standard y el tipo de comparador UTF8Type.
Vamos a nuestro archivo test.php y escribimos el siguiente código:
Códigofuente
1. <?php
2.
3. $data = array();
4. $data[5] = array(
5. 'title' => 'Apache Cassandra',
42
6. 'license' => 'Open Source',
7. 'category' => 'no-sql',
8. );
9. $data[3] = array(
10. 'title' => 'MongoDB',
11. 'license' => 'Open Source',
12. 'category' => 'no-sql'
13. );
14. $data[1] = array(
15. 'title' => 'Neo4j',
16. 'license' => 'Open Source',
17. 'category' => 'no-sql',
18. );
19. $data[4] = array(
20. 'title' => 'MySQL',
21. 'license' => 'Open Source',
22. 'category' => 'sql'
23. );
24. $data[2] = array(
25. 'title' => 'MariaDB',
26. 'license' => 'Open Source',
27. 'category' => 'sql',
28. );
29.
30. foreach($data as $key => $value){
31. $cass->guardar('column_family_order_utf8', $key, $value);
32. }
Este código guardará un array desordenado en nuestra column family. Una vez ejecutado el script
accedemos a Cassandra Cluster Admin y visualizamos los registros de column_family_order_utf8,
nos mostrará el siguiente resultado:
Listado de los registros guardados
43
Como puedes observar los registros no se han ordenado, sin embargo cada una de las columns de
cada registro sí están ordenadas por orden alfabético. Esto sucede porque los comparadores no
ordenan por keys o claves de los registros sino por columns, aunque hay un caso especial, si la
column family es super los registros si estarán ordenados. Veamoslo.
Creamos una column family llamada column_family_utf8_super con el tipo de comparador
UTF8Type y el tipo de column family como super. En nuestro archivo test.php añadimos el siguiente
código:
Códigofuente
1. <?php
2.
3. $data = array();
4. $data[5] = array(
5. 'title' => 'Apache Cassandra',
6. 'license' => 'Open Source',
7. 'category' => 'no-sql',
8. );
9. $data[3] = array(
10. 'title' => 'MongoDB',
11. 'license' => 'Open Source',
12. 'category' => 'no-sql'
13. );
14. $data[1] = array(
15. 'title' => 'Neo4j',
16. 'license' => 'Open Source',
17. 'category' => 'no-sql',
18. );
19. $data[4] = array(
20. 'title' => 'MySQL',
21. 'license' => 'Open Source',
22. 'category' => 'sql'
23. );
24. $data[2] = array(
25. 'title' => 'MariaDB',
26. 'license' => 'Open Source',
27. 'category' => 'sql',
28. );
29.
30. $cass->guardar('column_family_order_utf8_super', 'databases', $data);
Una vez ejecutado este script nos vamos a nuestra column family y nos mostrará lo siguiente:
44
Listado de registros en la column family
Como puedes observar ahora sí están ordenados los registros, pero claro ahora están dentro de una
super column.
En Cassandra la ordenación se realiza a las columnas del registro o los registros dentro de las super
columns, si creasemos otra super column, esta no se ordenaría con respecto a la ya creada,
‘databases’.
Aunque esta ordenación puede ser útil y totalmente funcional, para los desarrolladores que vengan
de las bases de datos relacionales les puede resultar confuso. Por ejemplo, para guardar los
comentarios de un post de un blog podríamos utilizar este tipo de ordenación perfectamente, ya que
podemos utilizar el id del post como key de la super column (el ‘databases’ de la imagen anterior se
sustituiría por el id del post) y el timestamp (como este 1337787675.32246500) para la key de los
registros. De esta forma tendríamos ordenados los comentarios por tiempo y por post. Si
quisieramos recuperar los comentarios de un post concreto solo tendríamos que pasarle al método
correspondiente el id del post como key de la super column.
¿Y si quisieramos guardar los post del blog? En este caso una column family super nos lo podría
resolver indicando como key de la super column ‘posts‘ y utilizando como key en los registros el
timestamp. Pero si quisieramos hacer busquedas utilizando indices secundarios una column family
super no nos valdría, ya que los indices secundarios no funcionan en ellas.
Para ello habría que crear una column family standard para los post, que nos permitirá usar los
indices secundarios, y una column family super para guardar las keys de los post dentro de una super
column con key, por ejemplo, ‘key_posts‘. Para hacer la consulta habría que recuperar las keys de los
posts a mostrar en primer lugar, y después, utilizando un método de PHPCassa que aun no hemos
usado recuperar los registros correspondientes a esas keys.
45
El método que deberíamos añadir a nuestro archivo cassandra.php sería el siguiente:
Códigofuente
1. <?php
2.
3. function obtenerMultiplesRegistros($name_columnFamily, $multiKeys,
$super_column = ''){
4.
5. if (!empty($super_column)){
6. $column_family = new SuperColumnFamily($this->conexion,
$name_columnFamily);
7. $result = $column_family->multiget_super_column($multiKeys,
$super_column);
8. }
9. else{
10. $column_family = new ColumnFamily($this->conexion,
$name_columnFamily);
11. $result = $column_family->multiget($multiKeys);
12. }
13.
14. return $result;
15.
16. }
A este método le pasamos el nombre de la column family standard donde hemos guardado los posts
y un array con las keys a recuperar, nos devolverá un array con los datos de cada uno de los posts
que le hemos pedido… y en el orden en el que le hayamos pasado las keys a recuperar.
Existe otra forma de ordenar registros, pero además de que en versiones posteriores de Cassandra
desaparecerá y provoca problemas de rendimiento, yo no la recomiendo, ya que pierdes todos los
beneficios que ofrece Cassandra. Aun así os dejo un link para que le echéis un ojo xD:
http://ria101.wordpress.com/2010/02/22/cassandra-randompartitioner-vs-orderpreservingpartitioner/
Y os dejo otro link para que tengais algo más de información respecto a ordenar registros en
Cassandra:
http://ayogo.com/blog/2010/04/09/sorting-in-cassandra/
CREAR CLAVES O KEYS PARA LOS REGISTROS
Como has podido ver en el apartado anterior, para ordenar los registros es muy importante tener una
key de cada registro que sea única y siempre vaya en orden. Esto las bases de datos relacionales nos
lo dan ya hecho, sin embargo en las bases de datos no-sql esto no es así.
46
Las bases de datos no-sql se crearon para optimizar la lectura y escritura de los registros en la base
de datos, esto provocó que algunas funcionalidades muy útiles en las bases relaciones no tuvieran
cabida en las no-sql. Por tanto para mantener en orden los registros debemos crear nosotros nuestras
propias claves.
PHPCassa dispone de un método para crear una clave aleatoria basada en el timestamp.
Para utilizarla primero añadiremos la clase a nuestra lista:
Códigofuente
1. <?php
2.
3. use phpcassaConnectionConnectionPool;
4. use phpcassaColumnFamily;
5. use phpcassaSuperColumnFamily;
6. use phpcassaColumnSlice;
7. use phpcassaSystemManager;
8. use phpcassaSchemaStrategyClass;
9. use phpcassaIndexIndexExpression;
10. use phpcassaIndexIndexClause;
11. use phpcassaUUID;
Ahora crearemos un nuevo método en nuestro archivo cassamdra.php que devolverá la clave:
Códigofuente
1. <?php
2.
3. public function obtenerUuid(){
4.
5. $util = new UUID;
6.
7. return $util->import($util->uuid1());
8. }
Como me está quedando un post muy largo os voy a dejar algo de deberes xD. Sería interesante
probarlo tanto con column families standard y super, además de con un tipo de comparador
UTF8Type y TimeUUIDType.
Como el chorro de letras y números que devuelve es muy poco legible yo suelo utilizar mi propio
sistema de claves, normalmente utilizo el microtime() de php y un par de ids de lo que se esté
guardando: el id del usuario, el id de lo que se ha creado, etc. Algo que lo diferencie del resto. Para
la clave primero pongo los segundos que devuelve microtime() y después los microsegundos. Para
que os hagais una idea sería algo así:
47
$key = $segundos . ‘.’ . $microsegundos . ‘_’ . $id_post . ‘_’ . $id_usuario;
De esta forma le estamos dando una clave para los ejemplos del anterior apartado, más
concretamente para los comentarios en un post.
CONTAR REGISTROS
El último apartado de este post. Contar registros. Esto es algo que Cassandra no lleva muy bien,
sobre todo con grandes cantidades de información.
Cassandra cuando recibe una petición de lectura/escritura utiliza unas tablas en memoria llamadas
memtables (el que le puso el nombre de rompió la cabeza pensando). Cuantas más peticiones reciba
Cassandra más memtables creará, de esta forma permitirá una cierta consistencia de la información
almacenada en la base de datos.
Cuando le pedimos a phpCassa que nos devuelva el número de registros en una column family o en
una super column concreta, lo que está haciendo en realidad es hacer una petición a Cassandra de
todos los registros que haya en la column family o en la super column. Cuando esto ocurre
Cassandra guardará estos registros en la RAM del servidor antes de enviarlos a phpCassa, y sí
Cassandra no cuenta los registros, porque no está pensada para eso, es phpCassa la que cuenta los
registros y te devuelve el número concreto.
El método que utiliza phpCassa para contar registros es el que os muestro a continuación, dentro de
un método para añadir al archivo cassandra.php:
Códigofuente
1. <?php
2.
3. public function contar_registros($name_columnFamily, $key,
$super_column='', $range_start='', $range_end=''){
4.
5. $column_slice = new ColumnSlice($range_start, $range_end);
6.
7. if (!empty($super_column)){
8. $column_family = new SuperColumnFamily($this->conexion,
$name_columnFamily);
9. $result = $column_family->get_subcolumn_count($key, $super_column,
$column_slice);
10. }
11. else{
12. $column_family = new ColumnFamily($this->conexion,
$name_columnFamily);
13. $result = $column_family->get_count($key, $column_slice);
14. }
15.
48
16. return $result;
17.
18. }
Esta forma de contar registros provoca que Cassandra consuma todos los recursos de RAM del
servidor, con lo que no os la recomiendo.
La mejor manera de contar registros con Cassandra es utilizar una column family con contadores, de
tal forma que en nuestro código cada vez que se guarde un registro en la bd se aumente el contador
que lleva la cuenta de los registros guardados. En el caso de que se eliminen, habría que disminuirlo.
Y en el caso de que el registro se esté actualizando controlar que no aumente el contador xD.
Cualquier duda que tengais intentaré responderla lo mejor posible en los comentarios.
Cassandra 1.x y PHP para desarrolladores
SQL: Clusters
Cassandra permite crear anillos o clusters de servidores de una forma muy sencilla, esto nos
permitirá levantar nuevos servidores dentro de un cluster en cuestión de varios minutos.
Para ello tendremos que modificar la configuración de la BD.
En /etc/cassandra modificamos el archivo cassandra.yaml. Buscaremos la siguiente línea:
- seeds: "localhost"
Y sustituimos localhost por la ip local del servidor, en mi caso 192.168.1.10.
- seeds: "192.168.1.10"
A continuación modificamos las siguientes líneas:
listen_address: localhost
[...]
rpc_address: localhost
Por:
listen_address: 192.168.1.10
49
[...]
rpc_address: 192.168.1.10
Guardamos y reiniciamos el servidor.
Ahora el servidor con esta configuración será al que se conecten el resto de servidores del cluster.
Para el resto de servidores la configuración es parecida. En seeds mantenemos la ip del servidor
principal y en listen_address y rpc_address ponemos la ip del servidor a unir al cluster:
- seeds: "192.168.1.10"
[...]
listen_address: 192.168.1.103
[...]
rpc_address: 192.168.1.103
Utilizo la ip 192.168.1.103 ya que es la que tengo configurada en mi cluster de prueba, tu deberías
poner la ip correspondiente a la máquina donde estés configurando Cassandra.
Guardamos y reiniciamos la BD.
Esto es todo lo que hay que hacer para crear un cluster con Cassandra

Más contenido relacionado

La actualidad más candente (12)

Introducción a Servidor HTTP Apache
Introducción a Servidor HTTP ApacheIntroducción a Servidor HTTP Apache
Introducción a Servidor HTTP Apache
 
Habilitandoipv6linuxbr_linux
Habilitandoipv6linuxbr_linuxHabilitandoipv6linuxbr_linux
Habilitandoipv6linuxbr_linux
 
Instalación y Configuración SAN HP MSA 2040 SFF
Instalación y Configuración SAN HP MSA 2040 SFFInstalación y Configuración SAN HP MSA 2040 SFF
Instalación y Configuración SAN HP MSA 2040 SFF
 
Tuning Lamp
Tuning LampTuning Lamp
Tuning Lamp
 
Guía instalación koha por paquetes en ubuntu 16.04 lts actualizada
Guía instalación koha por paquetes en ubuntu 16.04 lts actualizadaGuía instalación koha por paquetes en ubuntu 16.04 lts actualizada
Guía instalación koha por paquetes en ubuntu 16.04 lts actualizada
 
Red t3 practica1_apachecms
Red t3 practica1_apachecmsRed t3 practica1_apachecms
Red t3 practica1_apachecms
 
Instalación de 2 CMS: Wordpress y Drupal
Instalación de 2 CMS: Wordpress y DrupalInstalación de 2 CMS: Wordpress y Drupal
Instalación de 2 CMS: Wordpress y Drupal
 
A4 instalación de koha
A4   instalación de kohaA4   instalación de koha
A4 instalación de koha
 
ocs inventory gpli gestor incidencias castellano
ocs inventory gpli gestor incidencias castellanoocs inventory gpli gestor incidencias castellano
ocs inventory gpli gestor incidencias castellano
 
Apache
ApacheApache
Apache
 
php
phpphp
php
 
Tutorial de php y my sql completo
Tutorial de php y my sql completoTutorial de php y my sql completo
Tutorial de php y my sql completo
 

Destacado

Instalacion,Configuracion y Creacion de Una Base de Datos en Apache Cassandra...
Instalacion,Configuracion y Creacion de Una Base de Datos en Apache Cassandra...Instalacion,Configuracion y Creacion de Una Base de Datos en Apache Cassandra...
Instalacion,Configuracion y Creacion de Una Base de Datos en Apache Cassandra...Daniel Briian
 
Immigrazione. Questione di dignità. Immigration, a question of human dignity
Immigrazione. Questione di dignità. Immigration, a question of human dignityImmigrazione. Questione di dignità. Immigration, a question of human dignity
Immigrazione. Questione di dignità. Immigration, a question of human dignityNicola Canestrini
 
Endangered Lawyers Avvocati Minacciati
Endangered Lawyers Avvocati MinacciatiEndangered Lawyers Avvocati Minacciati
Endangered Lawyers Avvocati MinacciatiNicola Canestrini
 
Optimising your Practice - a toolkit to survive a changing NHS environment
Optimising your Practice - a toolkit to survive a changing NHS environmentOptimising your Practice - a toolkit to survive a changing NHS environment
Optimising your Practice - a toolkit to survive a changing NHS environmentOneMedicalGroup
 
Great Gatsby trailer
Great Gatsby trailerGreat Gatsby trailer
Great Gatsby traileremmalouise01
 
Concurs regional de creații plastice și literare '15
Concurs regional de creații plastice și literare '15Concurs regional de creații plastice și literare '15
Concurs regional de creații plastice și literare '15angelica an
 
Mandato di arresto europeo European Arrest Warrant
Mandato di arresto europeo European Arrest WarrantMandato di arresto europeo European Arrest Warrant
Mandato di arresto europeo European Arrest WarrantNicola Canestrini
 
Tree species composition and above ground tree biomass estimation
Tree species composition and above ground tree biomass estimationTree species composition and above ground tree biomass estimation
Tree species composition and above ground tree biomass estimationMrumba E. John
 
Fight of terrorism as seen by the defense (it /de)
Fight of terrorism as seen by the defense (it /de)Fight of terrorism as seen by the defense (it /de)
Fight of terrorism as seen by the defense (it /de)Nicola Canestrini
 
Access to a lawyer directive: Italy.
Access to a lawyer directive: Italy. Access to a lawyer directive: Italy.
Access to a lawyer directive: Italy. Nicola Canestrini
 
U-Man Belgium: Training & coaching met een passie voor mensen
U-Man Belgium: Training & coaching met een passie voor mensenU-Man Belgium: Training & coaching met een passie voor mensen
U-Man Belgium: Training & coaching met een passie voor mensenU-Man Belgium
 
Roadmap directives nell'ordinamento italiano (Roadmap directives and italian ...
Roadmap directives nell'ordinamento italiano (Roadmap directives and italian ...Roadmap directives nell'ordinamento italiano (Roadmap directives and italian ...
Roadmap directives nell'ordinamento italiano (Roadmap directives and italian ...Nicola Canestrini
 
Portfolio 2017_Irene Fiorentini_LinkedIn
Portfolio 2017_Irene Fiorentini_LinkedInPortfolio 2017_Irene Fiorentini_LinkedIn
Portfolio 2017_Irene Fiorentini_LinkedInIrene Fiorentini
 
ComodalBasso Calendario 2015
ComodalBasso Calendario 2015ComodalBasso Calendario 2015
ComodalBasso Calendario 201529mico1970
 

Destacado (18)

Instalacion,Configuracion y Creacion de Una Base de Datos en Apache Cassandra...
Instalacion,Configuracion y Creacion de Una Base de Datos en Apache Cassandra...Instalacion,Configuracion y Creacion de Una Base de Datos en Apache Cassandra...
Instalacion,Configuracion y Creacion de Una Base de Datos en Apache Cassandra...
 
Immigrazione. Questione di dignità. Immigration, a question of human dignity
Immigrazione. Questione di dignità. Immigration, a question of human dignityImmigrazione. Questione di dignità. Immigration, a question of human dignity
Immigrazione. Questione di dignità. Immigration, a question of human dignity
 
Endangered Lawyers Avvocati Minacciati
Endangered Lawyers Avvocati MinacciatiEndangered Lawyers Avvocati Minacciati
Endangered Lawyers Avvocati Minacciati
 
Optimising your Practice - a toolkit to survive a changing NHS environment
Optimising your Practice - a toolkit to survive a changing NHS environmentOptimising your Practice - a toolkit to survive a changing NHS environment
Optimising your Practice - a toolkit to survive a changing NHS environment
 
Great Gatsby trailer
Great Gatsby trailerGreat Gatsby trailer
Great Gatsby trailer
 
Conversations With Peace
Conversations With PeaceConversations With Peace
Conversations With Peace
 
Tugas ilmu sosbud
Tugas ilmu sosbudTugas ilmu sosbud
Tugas ilmu sosbud
 
Concurs regional de creații plastice și literare '15
Concurs regional de creații plastice și literare '15Concurs regional de creații plastice și literare '15
Concurs regional de creații plastice și literare '15
 
Mandato di arresto europeo European Arrest Warrant
Mandato di arresto europeo European Arrest WarrantMandato di arresto europeo European Arrest Warrant
Mandato di arresto europeo European Arrest Warrant
 
Orientacion laboral
Orientacion laboralOrientacion laboral
Orientacion laboral
 
Tree species composition and above ground tree biomass estimation
Tree species composition and above ground tree biomass estimationTree species composition and above ground tree biomass estimation
Tree species composition and above ground tree biomass estimation
 
Fight of terrorism as seen by the defense (it /de)
Fight of terrorism as seen by the defense (it /de)Fight of terrorism as seen by the defense (it /de)
Fight of terrorism as seen by the defense (it /de)
 
Access to a lawyer directive: Italy.
Access to a lawyer directive: Italy. Access to a lawyer directive: Italy.
Access to a lawyer directive: Italy.
 
U-Man Belgium: Training & coaching met een passie voor mensen
U-Man Belgium: Training & coaching met een passie voor mensenU-Man Belgium: Training & coaching met een passie voor mensen
U-Man Belgium: Training & coaching met een passie voor mensen
 
Uts rpl 2010_1101_dan_solusi
Uts rpl 2010_1101_dan_solusiUts rpl 2010_1101_dan_solusi
Uts rpl 2010_1101_dan_solusi
 
Roadmap directives nell'ordinamento italiano (Roadmap directives and italian ...
Roadmap directives nell'ordinamento italiano (Roadmap directives and italian ...Roadmap directives nell'ordinamento italiano (Roadmap directives and italian ...
Roadmap directives nell'ordinamento italiano (Roadmap directives and italian ...
 
Portfolio 2017_Irene Fiorentini_LinkedIn
Portfolio 2017_Irene Fiorentini_LinkedInPortfolio 2017_Irene Fiorentini_LinkedIn
Portfolio 2017_Irene Fiorentini_LinkedIn
 
ComodalBasso Calendario 2015
ComodalBasso Calendario 2015ComodalBasso Calendario 2015
ComodalBasso Calendario 2015
 

Similar a Cassandra y php para desarrolladores sql

Requerimientos de instalación
Requerimientos de instalaciónRequerimientos de instalación
Requerimientos de instalaciónPrincezitha Ruiz
 
Instalacion de osc inventory en ubuntu
Instalacion de osc inventory en ubuntuInstalacion de osc inventory en ubuntu
Instalacion de osc inventory en ubuntuEcuteb Gv
 
Manual php y_mysql
Manual php y_mysqlManual php y_mysql
Manual php y_mysqljohan reyes
 
Instalación KOHA: desarrollo, requerimientos y configuración
Instalación KOHA: desarrollo, requerimientos y configuraciónInstalación KOHA: desarrollo, requerimientos y configuración
Instalación KOHA: desarrollo, requerimientos y configuraciónSocialBiblio
 
633f9e tutorial de php y my sql completo
633f9e tutorial de php y my sql completo633f9e tutorial de php y my sql completo
633f9e tutorial de php y my sql completoMETROPOLITANO
 
Tutorial de php y my sql completo
Tutorial de php y my sql completoTutorial de php y my sql completo
Tutorial de php y my sql completoErnesto Gamboa
 
633f9e tutorial de php y my sql completo
633f9e tutorial de php y my sql completo633f9e tutorial de php y my sql completo
633f9e tutorial de php y my sql completoUbeimar Navarro Herrera
 
Tutorial de php y my sql completo
Tutorial de php y my sql completoTutorial de php y my sql completo
Tutorial de php y my sql completoIgnacio Reyes
 
633f9e tutorial de php y my sql completo (1)
633f9e tutorial de php y my sql completo (1)633f9e tutorial de php y my sql completo (1)
633f9e tutorial de php y my sql completo (1)Eduardo Monroy Husillos
 
Tutorial de php y my sql completo
Tutorial de php y my sql completoTutorial de php y my sql completo
Tutorial de php y my sql completoAlberto Martinez
 
Instalar php 5 en windows 7 con apache
Instalar php 5 en windows 7 con apacheInstalar php 5 en windows 7 con apache
Instalar php 5 en windows 7 con apacheEsmeralda Lopez
 
Zend framework
Zend frameworkZend framework
Zend frameworkjasiel_14
 
Interchange How-To for Red Hat Linux ES4
Interchange How-To for Red Hat Linux ES4Interchange How-To for Red Hat Linux ES4
Interchange How-To for Red Hat Linux ES4David Ramirez
 

Similar a Cassandra y php para desarrolladores sql (20)

Requerimientos de instalación
Requerimientos de instalaciónRequerimientos de instalación
Requerimientos de instalación
 
Framework Catalyst
Framework CatalystFramework Catalyst
Framework Catalyst
 
Instalacion de osc inventory en ubuntu
Instalacion de osc inventory en ubuntuInstalacion de osc inventory en ubuntu
Instalacion de osc inventory en ubuntu
 
Manual php y_mysql
Manual php y_mysqlManual php y_mysql
Manual php y_mysql
 
Instalación KOHA: desarrollo, requerimientos y configuración
Instalación KOHA: desarrollo, requerimientos y configuraciónInstalación KOHA: desarrollo, requerimientos y configuración
Instalación KOHA: desarrollo, requerimientos y configuración
 
Mysql java
Mysql javaMysql java
Mysql java
 
Pdf
PdfPdf
Pdf
 
633f9e tutorial de php y my sql completo
633f9e tutorial de php y my sql completo633f9e tutorial de php y my sql completo
633f9e tutorial de php y my sql completo
 
Tutorial de php y my sql completo
Tutorial de php y my sql completoTutorial de php y my sql completo
Tutorial de php y my sql completo
 
633f9e tutorial de php y my sql completo
633f9e tutorial de php y my sql completo633f9e tutorial de php y my sql completo
633f9e tutorial de php y my sql completo
 
Tutorial de php y my sql completo
Tutorial de php y my sql completoTutorial de php y my sql completo
Tutorial de php y my sql completo
 
633f9e tutorial de php y my sql completo (1)
633f9e tutorial de php y my sql completo (1)633f9e tutorial de php y my sql completo (1)
633f9e tutorial de php y my sql completo (1)
 
Tutorial de php y my sql completo
Tutorial de php y my sql completoTutorial de php y my sql completo
Tutorial de php y my sql completo
 
Php andmysql (1)
Php andmysql (1)Php andmysql (1)
Php andmysql (1)
 
Tutorial mysqlphp
Tutorial mysqlphpTutorial mysqlphp
Tutorial mysqlphp
 
Php andmysql
Php andmysqlPhp andmysql
Php andmysql
 
Instalar php 5 en windows 7 con apache
Instalar php 5 en windows 7 con apacheInstalar php 5 en windows 7 con apache
Instalar php 5 en windows 7 con apache
 
Zend framework
Zend frameworkZend framework
Zend framework
 
Manual
ManualManual
Manual
 
Interchange How-To for Red Hat Linux ES4
Interchange How-To for Red Hat Linux ES4Interchange How-To for Red Hat Linux ES4
Interchange How-To for Red Hat Linux ES4
 

Último

Hanns Recabarren Diaz (2024), Implementación de una herramienta de realidad v...
Hanns Recabarren Diaz (2024), Implementación de una herramienta de realidad v...Hanns Recabarren Diaz (2024), Implementación de una herramienta de realidad v...
Hanns Recabarren Diaz (2024), Implementación de una herramienta de realidad v...Francisco Javier Mora Serrano
 
Cadenas de Markov investigación de operaciones
Cadenas de Markov investigación de operacionesCadenas de Markov investigación de operaciones
Cadenas de Markov investigación de operacionesal21510263
 
VIRUS FITOPATÓGENOS (GENERALIDADES EN PLANTAS)
VIRUS FITOPATÓGENOS (GENERALIDADES EN PLANTAS)VIRUS FITOPATÓGENOS (GENERALIDADES EN PLANTAS)
VIRUS FITOPATÓGENOS (GENERALIDADES EN PLANTAS)ssuser6958b11
 
Tiempos Predeterminados MOST para Estudio del Trabajo II
Tiempos Predeterminados MOST para Estudio del Trabajo IITiempos Predeterminados MOST para Estudio del Trabajo II
Tiempos Predeterminados MOST para Estudio del Trabajo IILauraFernandaValdovi
 
Centro Integral del Transporte de Metro de Madrid (CIT). Premio COAM 2023
Centro Integral del Transporte de Metro de Madrid (CIT). Premio COAM 2023Centro Integral del Transporte de Metro de Madrid (CIT). Premio COAM 2023
Centro Integral del Transporte de Metro de Madrid (CIT). Premio COAM 2023ANDECE
 
Uso y Manejo de Extintores Lucha contra incendios
Uso y Manejo de Extintores Lucha contra incendiosUso y Manejo de Extintores Lucha contra incendios
Uso y Manejo de Extintores Lucha contra incendioseduardochavezg1
 
2. UPN PPT - SEMANA 02 GESTION DE PROYECTOS MG CHERYL QUEZADA(1).pdf
2. UPN PPT - SEMANA 02 GESTION DE PROYECTOS MG CHERYL QUEZADA(1).pdf2. UPN PPT - SEMANA 02 GESTION DE PROYECTOS MG CHERYL QUEZADA(1).pdf
2. UPN PPT - SEMANA 02 GESTION DE PROYECTOS MG CHERYL QUEZADA(1).pdfAnthonyTiclia
 
SOUDAL: Soluciones de sellado, pegado y hermeticidad
SOUDAL: Soluciones de sellado, pegado y hermeticidadSOUDAL: Soluciones de sellado, pegado y hermeticidad
SOUDAL: Soluciones de sellado, pegado y hermeticidadANDECE
 
CHARLA DE INDUCCIÓN SEGURIDAD Y SALUD OCUPACIONAL
CHARLA DE INDUCCIÓN SEGURIDAD Y SALUD OCUPACIONALCHARLA DE INDUCCIÓN SEGURIDAD Y SALUD OCUPACIONAL
CHARLA DE INDUCCIÓN SEGURIDAD Y SALUD OCUPACIONALKATHIAMILAGRITOSSANC
 
Linealización de sistemas no lineales.pdf
Linealización de sistemas no lineales.pdfLinealización de sistemas no lineales.pdf
Linealización de sistemas no lineales.pdfrolandolazartep
 
COMPONENTES DE LA VIA FERREA UAJMS - BOLIVIA
COMPONENTES DE LA VIA FERREA UAJMS - BOLIVIACOMPONENTES DE LA VIA FERREA UAJMS - BOLIVIA
COMPONENTES DE LA VIA FERREA UAJMS - BOLIVIARafaelPaco2
 
Exposicion. del documentos de YPFB corporación
Exposicion. del documentos de YPFB corporaciónExposicion. del documentos de YPFB corporación
Exposicion. del documentos de YPFB corporaciónjas021085
 
183045401-Terminal-Terrestre-de-Trujillo.pdf
183045401-Terminal-Terrestre-de-Trujillo.pdf183045401-Terminal-Terrestre-de-Trujillo.pdf
183045401-Terminal-Terrestre-de-Trujillo.pdfEdwinAlexanderSnchez2
 
Topografía 1 Nivelación y Carretera en la Ingenierías
Topografía 1 Nivelación y Carretera en la IngenieríasTopografía 1 Nivelación y Carretera en la Ingenierías
Topografía 1 Nivelación y Carretera en la IngenieríasSegundo Silva Maguiña
 
CLASE - 01 de construcción 1 ingeniería civil
CLASE - 01 de construcción 1 ingeniería civilCLASE - 01 de construcción 1 ingeniería civil
CLASE - 01 de construcción 1 ingeniería civilDissneredwinPaivahua
 
CICLO DE DEMING que se encarga en como mejorar una empresa
CICLO DE DEMING que se encarga en como mejorar una empresaCICLO DE DEMING que se encarga en como mejorar una empresa
CICLO DE DEMING que se encarga en como mejorar una empresaSHERELYNSAMANTHAPALO1
 
Edificio residencial Becrux en Madrid. Fachada de GRC
Edificio residencial Becrux en Madrid. Fachada de GRCEdificio residencial Becrux en Madrid. Fachada de GRC
Edificio residencial Becrux en Madrid. Fachada de GRCANDECE
 
Historia de la Arquitectura II, 1era actividad..pdf
Historia de la Arquitectura II, 1era actividad..pdfHistoria de la Arquitectura II, 1era actividad..pdf
Historia de la Arquitectura II, 1era actividad..pdfIsbelRodrguez
 
Electromagnetismo Fisica FisicaFisica.pdf
Electromagnetismo Fisica FisicaFisica.pdfElectromagnetismo Fisica FisicaFisica.pdf
Electromagnetismo Fisica FisicaFisica.pdfAnonymous0pBRsQXfnx
 
Parámetros de Perforación y Voladura. para Plataformas
Parámetros de  Perforación y Voladura. para PlataformasParámetros de  Perforación y Voladura. para Plataformas
Parámetros de Perforación y Voladura. para PlataformasSegundo Silva Maguiña
 

Último (20)

Hanns Recabarren Diaz (2024), Implementación de una herramienta de realidad v...
Hanns Recabarren Diaz (2024), Implementación de una herramienta de realidad v...Hanns Recabarren Diaz (2024), Implementación de una herramienta de realidad v...
Hanns Recabarren Diaz (2024), Implementación de una herramienta de realidad v...
 
Cadenas de Markov investigación de operaciones
Cadenas de Markov investigación de operacionesCadenas de Markov investigación de operaciones
Cadenas de Markov investigación de operaciones
 
VIRUS FITOPATÓGENOS (GENERALIDADES EN PLANTAS)
VIRUS FITOPATÓGENOS (GENERALIDADES EN PLANTAS)VIRUS FITOPATÓGENOS (GENERALIDADES EN PLANTAS)
VIRUS FITOPATÓGENOS (GENERALIDADES EN PLANTAS)
 
Tiempos Predeterminados MOST para Estudio del Trabajo II
Tiempos Predeterminados MOST para Estudio del Trabajo IITiempos Predeterminados MOST para Estudio del Trabajo II
Tiempos Predeterminados MOST para Estudio del Trabajo II
 
Centro Integral del Transporte de Metro de Madrid (CIT). Premio COAM 2023
Centro Integral del Transporte de Metro de Madrid (CIT). Premio COAM 2023Centro Integral del Transporte de Metro de Madrid (CIT). Premio COAM 2023
Centro Integral del Transporte de Metro de Madrid (CIT). Premio COAM 2023
 
Uso y Manejo de Extintores Lucha contra incendios
Uso y Manejo de Extintores Lucha contra incendiosUso y Manejo de Extintores Lucha contra incendios
Uso y Manejo de Extintores Lucha contra incendios
 
2. UPN PPT - SEMANA 02 GESTION DE PROYECTOS MG CHERYL QUEZADA(1).pdf
2. UPN PPT - SEMANA 02 GESTION DE PROYECTOS MG CHERYL QUEZADA(1).pdf2. UPN PPT - SEMANA 02 GESTION DE PROYECTOS MG CHERYL QUEZADA(1).pdf
2. UPN PPT - SEMANA 02 GESTION DE PROYECTOS MG CHERYL QUEZADA(1).pdf
 
SOUDAL: Soluciones de sellado, pegado y hermeticidad
SOUDAL: Soluciones de sellado, pegado y hermeticidadSOUDAL: Soluciones de sellado, pegado y hermeticidad
SOUDAL: Soluciones de sellado, pegado y hermeticidad
 
CHARLA DE INDUCCIÓN SEGURIDAD Y SALUD OCUPACIONAL
CHARLA DE INDUCCIÓN SEGURIDAD Y SALUD OCUPACIONALCHARLA DE INDUCCIÓN SEGURIDAD Y SALUD OCUPACIONAL
CHARLA DE INDUCCIÓN SEGURIDAD Y SALUD OCUPACIONAL
 
Linealización de sistemas no lineales.pdf
Linealización de sistemas no lineales.pdfLinealización de sistemas no lineales.pdf
Linealización de sistemas no lineales.pdf
 
COMPONENTES DE LA VIA FERREA UAJMS - BOLIVIA
COMPONENTES DE LA VIA FERREA UAJMS - BOLIVIACOMPONENTES DE LA VIA FERREA UAJMS - BOLIVIA
COMPONENTES DE LA VIA FERREA UAJMS - BOLIVIA
 
Exposicion. del documentos de YPFB corporación
Exposicion. del documentos de YPFB corporaciónExposicion. del documentos de YPFB corporación
Exposicion. del documentos de YPFB corporación
 
183045401-Terminal-Terrestre-de-Trujillo.pdf
183045401-Terminal-Terrestre-de-Trujillo.pdf183045401-Terminal-Terrestre-de-Trujillo.pdf
183045401-Terminal-Terrestre-de-Trujillo.pdf
 
Topografía 1 Nivelación y Carretera en la Ingenierías
Topografía 1 Nivelación y Carretera en la IngenieríasTopografía 1 Nivelación y Carretera en la Ingenierías
Topografía 1 Nivelación y Carretera en la Ingenierías
 
CLASE - 01 de construcción 1 ingeniería civil
CLASE - 01 de construcción 1 ingeniería civilCLASE - 01 de construcción 1 ingeniería civil
CLASE - 01 de construcción 1 ingeniería civil
 
CICLO DE DEMING que se encarga en como mejorar una empresa
CICLO DE DEMING que se encarga en como mejorar una empresaCICLO DE DEMING que se encarga en como mejorar una empresa
CICLO DE DEMING que se encarga en como mejorar una empresa
 
Edificio residencial Becrux en Madrid. Fachada de GRC
Edificio residencial Becrux en Madrid. Fachada de GRCEdificio residencial Becrux en Madrid. Fachada de GRC
Edificio residencial Becrux en Madrid. Fachada de GRC
 
Historia de la Arquitectura II, 1era actividad..pdf
Historia de la Arquitectura II, 1era actividad..pdfHistoria de la Arquitectura II, 1era actividad..pdf
Historia de la Arquitectura II, 1era actividad..pdf
 
Electromagnetismo Fisica FisicaFisica.pdf
Electromagnetismo Fisica FisicaFisica.pdfElectromagnetismo Fisica FisicaFisica.pdf
Electromagnetismo Fisica FisicaFisica.pdf
 
Parámetros de Perforación y Voladura. para Plataformas
Parámetros de  Perforación y Voladura. para PlataformasParámetros de  Perforación y Voladura. para Plataformas
Parámetros de Perforación y Voladura. para Plataformas
 

Cassandra y php para desarrolladores sql

  • 1. 1 FenixTech System International http://www.interadictos.es/cassandra-y-php-para-desarrolladores-sql/ Cassandra y PHP para desarrolladores SQL Normalmente la mayoría de programadores trabajamos con bases de datos relacionales, utilizando para interactuar con la BD un lenguaje llamado SQL (structured query language) lo que nos facilita inmensamente la tarea de recuperar registros. Sin embargo las bases de datos no-sql como Cassandra no disponen de este lenguage y nos vemos obligados a aprender cómo funcionan. Y el aprendizaje puede ser algo confuso, debido a que estas bases son bastante diferentes a lo que estamos acostumbrados. Por eso he creado este tutorial, que te permitirá conocer cómo funciona Cassandra y cómo interactuar con ella a través de las clases que nos ofrece PHPCassa, para trabajar con PHP obviamente. LISTADO DE TEMAS Cassandra 1.x — PHPCassa 1.0.a.x 1. Instalación 2. El modelo de datos 3. La consola 4. Cassandra Cluster Admin, el phpMyAdmin de Cassandra 5. PHPCassa (I) 6. PHPCassa (II) 7. PHPCassa (III) 8. Clusters Cassandra 0.8 — PHPCassa 0.8.a.2 1. Instalación 2. El modelo de datos 3. La consola 4. Cassandra Cluster Admin, el phpMyAdmin de Cassandra 5. PHPCassa (I) 6. PHPCassa (II) 7. PHPCassa (III) 8. Clusters
  • 2. 2 Cassandra 1.x y PHP para desarrolladores SQL: Instalación La base de datos No-SQLCassandra fue creada por Facebook a causa de la necesidad de disponer de una base de datos distribuida de alto rendimiento, flexible, tolerante a fallos, escalable y que fuese capaz de procesar grandes cantidades de datos, más tarde fue liberada bajo licencia Apache y actualmente es utilizada principalmente por empresas de internet con proyectos con un alto uso de base de datos como Twitter. En esta serie de artículos iré desgranando la instalación, funcionamiento y desarrollo de aplicaciones en PHP con Cassandra, comparando las sentencias utilizadas para insertar, actualizar, etc de SQL con los métodos a utilizar en Cassandra. Por desgracia al ser algo completamente distinto a cualquier base de datos SQL tendré que añadir algo de teoría, pero intentaré que os resulte lo más ameno posible. Al toro. REQUISITOS Para la realización de esta guía se utilizará Debian Squeeze como sistema operativo. Doy por hecho que ya se dispone de un servidor web Apache con PHP instalado en la máquina de testeo que se esté usando. Las aplicaciones que se van a instalar han sido probadas en una máquina virtual Debian utilizando como aplicación de virtualización, VirtualBox instalado en un host Windows XP SP3. En un servidor de producción recomiendo que tenga bastante RAM (por encima de 1GB, ya veremos más adelante el porqué. En la máquina virtual que uso de testeo dispone de 700 MB y funciona bien, pero en producción no es lo recomendable). Instalaremos la base de datos Cassandra, el protocolo para conectar con ella y que nos generará el módulo para poder trabajar desde PHP, y PHPCassa que será la abstracción de la base de datos donde tenemos los métodos básicos para trabajar con Cassandra: insertar, actualizar, borrar, crear, etc. PREPARANDO EL SISTEMA Antes de empezar a instalar debemos actualizar el sistema operativos de la forma habitual: apt-get update apt-get upgrade Una vez actualizado el sistema empezamos a instalar.
  • 3. 3 INSTALANDO CASSANDRA Lo primero que necesitamos hacer para instalar Cassandra es editar los repositorios de Debian: nano /etc/apt/sources.list Una vez que se abra el editor añadimos las siguientes lineas: deb http://www.apache.org/dist/cassandra/debian/ 11x main deb-src http://www.apache.org/dist/cassandra/debian/ 11x main Como podrás observar después de la ruta del repositorio se ha añadido “11x” esto indica el número de versión a obtener, en este caso es la versión actual de cassandra al crear este post. No se indica el número de parche, es decir, actualmente se puede descargar Cassandra 1.1. Si dentro de unos meses sale la versión “1.2” solo tendrás que cambiar el uno por el dos. Volvemos a consola y actualizamos los repositorios. apt-get update Nos dará un error en las claves gpg. Procedemos a actualizarlas con las siguientes instrucciones: gpg --keyserver pgp.mit.edu --recv-keys F758CE318D77295D gpg --export --armor F758CE318D77295D | sudo apt-key add - Ojo con el guión del final, hay que añadirlo sino dará error. Con el paquete 0.7.5 nos da otro error de clave gpg así que también instalamos esta de la misma manera: gpg --keyserver pgp.mit.edu --recv-keys 2B5C1B00 gpg --export --armor 2B5C1B00 | sudo apt-key add - Verificamos que tenemos el sistema actualizado. apt-get update apt-get upgrade Actualizamos todos los paquetes que aparezcan. Procedemos a instalar el paquete de la base de datos NoSQL Cassandra: apt-get install cassandra Cassandra necesita a Java para funcionar para ello, una vez instalado Cassandra instalaremos el paquete sun-java6-jdk de la siguiente manera: apt-get install sun-java6-jdk
  • 4. 4 En el caso de que no encuentre el paquete verificar que los repositorios de Debian son correctos. Verifica la versión de Java con: java -version Debería aparecer algo así: java version "1.6.0_20" Java(TM) SE Runtime Environment (build 1.6.0_20-b02) Java HotSpot(TM) Client VM (build 16.3-b01, mixed mode, sharing) Se recomienda usar la versión de Java de Sun (Sun JDK) en vez de Open JDK debido a un bug encontrado en el mismo. Si os muestra algo distinto a esto, escribid el siguiente comando: update-alternatives --config javac Os mostrará un listado con los diferentes paquetes instalados en el sistema que pueden ser utilizados para trabajar con Java. Nosotros usaremos el paquete de Sun, así que pulsa el número del paquete para que Debian lo utilice. Por último, ejecutamos el siguiente comando para construir las dependencias: dpkg-buildpackage -uc -us INSTALANDO THRIFT Y LA EXTENSIÓN PARA PHP [ci-box type=”info”]PHPCassa ya incluye Thrift en el archivo descargable, con lo que puedes saltarte esta parte si quieres. En la sección de PHPCassa se trata la creación del archivo .so con los archivos contenidos en el paquete de PHPCassa[/ci-box] Thrift es tan solo el protocolo de conexión para poder utilizar Cassandra. Aunque en la extensión para PHP existen métodos para poder trabajar con cassandra, requieren bastante código por eso utilizaremos PHPCassa como abstracción de la base de datos. Primero descargamos Thrift desde su web: http://thrift.apache.org/download/ y descomprimimos tar -xzvf thrift-0.8.0.tar.gz Nos colocamos dentro de la carpeta de Thrift. Antes de hacer nada ahí instalamos algunos paquetes que nos serán necesarios: apt-get install libboost-dev automake libtool flex bison pkg-config g++ Una vez instalados esos paquetes configuramos y construimos Thrift: ./configure make
  • 5. 5 Construimos la interfaz de PHP Thrift para Cassandra: ./compiler/cpp/thrift -gen php ../ruta-a-cassandra/interface/cassandra.thrift Copiamos archivos necesario para que PHPCassa funcione: mkdir -p /usr/share/php/Thrift cp -R gen-php/ /usr/share/php/Thrift/packages/ cp -R lib/php/src/* /usr/share/php/Thrift/ Cambiamos al directorio del protocolo de Thrif: ruta-a-thrift/lib/php/src/ext/thrift_protocol. Instalamos el paquete para construir las extensiones de PHP: apt-get install php5-dev Construimos la extensión: phpize ./configure --enable-thrift_protocol make Copiamos la extensión a la siguiente carpeta (cuidado: dependiendo del sistema el nombre de la carpeta de destino puede variar): cp modules/thrift_protocol.so /usr/lib/php5/20060613/ Habilitamos el módulo creando el archivo /etc/php5/conf.d/thrift_protocol.ini con el siguiente texto: extension=thrift_protocol.so Comprobamos la instalación: php -i | grep -v "PWD" | grep "thrift_protocol" Si todo ha ido bien, reiniciamos Apache: /etc/init.d/apache2 restart Iniciamos Cassandra: /opt/cassandra/bin/cassandra Y probamos la consola para comprobar que todo ha ido correctamente: /opt/cassandra/bin/cassandra-cli -host localhost -port 9160 Debería indicarte algo así: Connected to: "Test Cluster" on localhost/9160
  • 6. 6 Welcome to cassandra CLI. INSTALANDO PHPCassa Bajamos PHPCassa desde github: https://github.com/thobbs/phpcassa Descomprimimos a una carpeta dentro del proyecto en el que vayamos a utilizar PHPCassa, para el tutorial usaré /var/www/prueba_cassandra/phpcassa. Si aun no has creado el archivo .so para que PHP pueda trabajar con Cassandra, escribe los siguientes comandos en tu consola: cd lib/thrift/ext/thrift_protocol phpize ./configure make sudo make install Una vez finalizados estos pasos edita el archivo php.ini y añade la siguiente línea: extension=thrift_protocol.so Con esto finalizamos la instalación de Cassandra para que pueda ser utilizada por PHP. Cassandra 1.x y PHP para desarrolladores SQL: El modelo de datos Si has trabajado con una base de datos relacional tal vez te resulte algo confuso al principio comprender el modelo de datos que usa Cassandra, intentaré ser lo más claro posible, pero si te surgen preguntas no dudes en dejarlas en los comentarios. Columnas El elemento más básico de la base de datos Cassandra es la columna, se compone de tres elementos: nombre de la columna, valor y timestamp. Os muestro un ejemplo como un array: array( "nombre" => "email", "valor" => "webmaster@localhost.com", "timestamp" => time(), );
  • 7. 7 Super columnas Es el conjunto de columnas con sus correspondientes valores: array( "nombre_superColumna" => array( "usuario1" => array( "nombre" => "email", "valor" => "webmaster@localhost.com", "timestamp" => time() ), "usuario2" => array( "nombre" => "email", "valor" => "email@email.com", "timestamp" => time() ), "usuario3" => array( "nombre" => "email", "valor" => "otroemail@otroemail.com", "timestamp" => time() ), ), ) Familia de columnas Es el conjunto de columnas o super columnas. Me explico: Las column Family o familia de columnas se puede configurar de dos maneras: como Super o como Standard. Si se elige la opción Standard, en la column family solo se podrán guardar columnas no super columnas. En cambio si la column family está configurada como Super podrá guardar, además de las columnas, las super columnas. Esta flexibilidad permite jugar con la base de datos y adaptarla a nuestras necesidades. Ejemplo: array( "name" => "ColumnFamily", array( "name" => "SuperColumn", array( "colums" ) ), ) Keyspace El keyspace es nuestra base de datos, donde alojaremos todas las columFamilies que necesitemos. Ejemplo: array( "name" => "keyspace",
  • 8. 8 array("name" => "columnFamily", array( [...] ), ), ) Cassandra 1.x y PHP para desarrolladores SQL: La consola Cassandra dispone de una herramienta a través de la consola o shell para poder trabajar con ella. Parecida a la de MySQL. Para acceder a la consola solo tendremos que escribir lo siguiente: > cassandra-cli Si todo va bien nos aparecerá algo parecido al siguiente texto: Welcome to Cassandra CLI version 1.0.7 Type 'help;' or '?' for help. Type 'quit;' or 'exit;' to quit. [default@unknown] Ahora tenemos que conectar con la base de datos de la siguiente manera: connect localhost/9160; Fíjate que al final del comando hay un punto y coma. Hay que añadirlo, como si fuera una sentencia SQL, sino te aparecerán unos puntos suspensivos para que finalices el comando. Si te ocurre esto último, pon el punto y coma y pulsa enter. Te debería aparecer algo como lo siguiente: Connected to: "Test Cluster" on localhost/9160 Hay una forma de resumir los pasos anteriores en una sola linea: > cassandra-cli -h localhost -p 9160 Ahora vamos a mostrar los keyspaces que tiene la base de datos actualmente: show keyspaces; [ci-box type=”warning”]Recuerda poner el punto y coma.[/ci-box] Este comando te mostrará un listado de los keyspaces y sus column families que se encuentran en la BD, además de información relevante sobre las propiedades, tanto de los keyspaces como de sus column families correspondientes.
  • 9. 9 El objetivo de este post no es explicar con detalle cada propiedad de los keyspaces y las column families (he de admitir que muchas de ellas las desconozco), sino mostrar y enseñar la forma de trabajar por consola con Cassandra. Vamos al lío. CREAR UN KEYSPACE Tan sencillo como la siguiente sentencia: create keyspace my_keyspace; Después de dos o tres segundos te mostrará algo como esto: b511da50-88c0-11e1-0000-242d50cf1fff Waiting for schema agreement... ... schemas agree across the cluster ACCEDER A UN KEYSPACE Igual de sencillo: use my_keyspace; Ahora que ya estamos dentro de nuestro keyspace, toca añadir column families. CREAR COLUMN FAMILIES Muy sencillo: create column family my_column_family; Añadamos datos. AÑADIR DATOS A UNA COLUMN FAMILY En MySQL utilizaríamos una sentencia INSERT para añadir información a una tabla concreta, en la que anteriormente habremos creado sus columnas. En Cassandra no hay que crearlas con antelación. (En realidad se puede utilizar un archivo para configurar el esquema del keyspace dando las
  • 10. 10 propiedades adecuadas a cada column family y sus respectivas columnas, pero para iniciarnos en Cassandra y aprender su funcionamiento no es necesario). Para no complicarnos mucho primero vamos a configurar la column family. Las column families disponen de diferentes tipos de codificación de datos para guardar los datos, es decir, si guardamos información en UTF-8 y nuestra column family está configurada como ASCII o Bytes nuestros datos se guardarán, sí, pero al recuperarla solo veremos un batiburrillo de número y letras. Para evitar esto configuramos la column family para que guarde los datos en UTF-8: assume my_column_family keys as utf8; assume my_column_family comparator as utf8; assume my_column_family validator as utf8; Ahora ya podemos crear nuestro primer registro: set my_column_family['1']['nombre'] = 'pepito'; set my_column_family['1']['edad'] = '120'; Si ejecutamos el siguiente comando: get my_column_family['1']; Nos devolverá las columnas que tuviese la fila con id = 1, junto con los correspondientes valores de esas columnas. Esto es el funcionamiento básico de la consola de Cassandra. Hay muchos más comandos para obtener información de Cassandra y realizar algunas tareas más, para obtener la ayuda y ver estos comandos solo tienes que escribir lo siguiente: help; ¿Fácil verdad? Por último, para salir de la consola: quit; Cassandra 1.x y PHP para desarrolladores SQL: Cassandra Cluster Admin, el phpMyAdmin de Cassandra En el anterior post expliqué el funcionamiento de la consola de Cassandra y como trabajar con ella. En este post explicaré como hacer lo mismo de una forma más rápida y fácil.
  • 11. 11 La razón de que no haya empezado ha explicar como se utiliza Cassandra desde PHP, es que primero hay que conocer cómo funciona Cassandra, su modelo de datos (que ya hemos visto) y algunos comandos básicos para ir aprendiendo a guardar y recuperar datos. El próximo post ya trataré el funcionamiento de PHPCassa y empezaremos a programar. Este post será bastante ligerito. Explicaré principalmente como hacer lo mismo que hicimos por consola pero de modo gráfico. CassAdmin, como yo le llamo, tiene más opciones de edición para los keyspaces y column families de los que vamos a ver (igual que ocurría con la consola), pero solo tocaremos las opciones más habituales. INSTALACIÓN Lo típico en estos casos. Descargar. Descomprimir y ejecutar. Descargamos los archivos desde el repositorio de git: https://github.com/sebgiroux/Cassandra-Cluster-Admin, o a través de git o como archivo comprimido. Como más te guste. Proceso para descargar Cassandra Cluster Admin
  • 12. 12 Página de descargas del administrador Ahora descomprimimos a una carpeta dentro de nuestro servidor web, ya que trabajamos con una aplicación programada en PHP. Si tienes Cassandra instalado en otro equipo que no sea en local, una máquina virtual por ejemplo, tendrás que cambiar la ip a la que se conecta cassAdmin. Es bastante sencillo. Para ello debes modificar el archivo includes/config.inc.php y sustituir la ip de localhost (127.0.0.1) por la ip del equipo en el que tengas instalado Cassandra:
  • 13. 13 Archivo config.inc.php Comoverásen la captura,yo utilizolaiplocal 192.168.1.10 que pertenece aunamáquinavirtual.Si tuviera instaladoCassandraen el mismoequipolaipa laque deberíaapuntar sería 127.0.0.1. El puertono lo modificamos. Una vez instalado y configurado (si fuese el caso) probamos a acceder desde nuestro navegador. Debería mostrarte algo como esto: Página principal de Cassandra Cluster Admin
  • 14. 14 CREAR KEYSPACES Como has podido ver, en la página principal del administrador ya aparece un keyspace, llamado system, perteneciente a Cassandra, con lo que lo mantendremos como está. Justo encima tenemos un botón para crear un nuevo keyspace (Create a new keyspace). Lo pulsamos. Formulario para crear un keyspace Solo nos pide tres parámetros a rellenar: Keyspace name: El nombre del keyspace a crear. Replication factor: Es el número de servidores o instancias de Cassandra de los que se debe guardar un registro u obtener una respuesta al recuperar algún registro. Strategy: Es la estrategia que seguirá Cassandra para guardar los datos. En el caso de tener varios servidores o centro de datos diferenciados entre sí, se aplicará una estrategia u otra para que los datos no se pierdan. Más info: http://answers.oreilly.com/topic/2408-replica-placement-strategies- when-using-cassandra/ En nuestro caso escribiremos los siguientes valores: Formulario para crear un keyspace con datos Pulsamos en Create keyspace y nos llevará a la página principal:
  • 15. 15 Página principal mostrando el keyspace que acabamos de crear Pulsamos sobre el keyspace que acabamos de crear y nos llevará a la siguiente página: Página de detalle del keyspace my_keyspace Aquí podemos ver información relativa al keyspace y al anillo (o cluster) en el que se encuentra guardado. También nos permite editar el keyspace o eliminarlo, pero la opción más interesante es la de crear nuevas column families (Create a new column family).
  • 16. 16 CREAR UNA COLUMN FAMILY Dentro del keyspace pulsamos sobre el botón Create a new column family, nos mostrará lo siguiente: Formulario para crear una column family Primero crearemos una column family standard con los siguientes datos:
  • 17. 17 Datos para crear la primera column family Para crear una column family solo son necesarios tres parámetros: Column Family Name: El nombre de la column family que vamos a crear. Column Type: El tipo de column family que vamos a crear (Standard o Super). Comparator Type: El comparador principal de las columnas. Es decir, la codificación que tendrán los datos dentro de la column family. Pulsamos en Create Column Family y en la página de nuestro keyspace se habrá añadido una nueva column family: Detalle de la column family creada AÑADIR REGISTROS A UNA COLUMN FAMILY STANDARD Ahora toca guardar registros en la BD. Como comenté en post anteriores Cassandra no necesita conocer los campos de las tablas (nuestras column families) ya que los creamos cada vez que añadimos un registro. Primero en la página principal del keyspace haz click en el nombre de la column family. Te aparecerá lo siguiente:
  • 18. 18 Detalle de la página principal de la column family creada En esta página te aparecerá, además de la información referente a la column family, los siguientes botones: Browse Data: Para mostrar un listado de los registros que contiene la column family. Create Secondary Index: Para crear indices secundarios. Parecido a los indices de MySQL. Get Key: Para buscar una clave o registro concreto. Insert Row: Para insertar un nuevo registro. Edit Column Family: Para editar los parámetros de la column family. Truncate Column Family: Para eliminar los registros de la column family sin eliminar esta. Drop Column Family: Para eliminar la column family y su contenido. Pulsamos en Insert Row. Nos aparecerá lo siguiente: Formulario para insertar registros Siempre que añadamos un nuevo registro deberemos indicar una key diferente que deberá ser única, sino cassAdmin pensará que lo que quieres hacer es actualizar ese registro. Añadimos los siguientes datos al formulario:
  • 19. 19 Formulario para insertar registros con datos Para añadir otra fila de cuadro de texto solo tienes que pulsar el botón Add… Volvemos a la página principal de la column family y pulsamos en Browse Data. Aquí veremos un listado con los registros que hayamos añadido: Listado de registros CREAR UNA COLUMN FAMILY SUPER Y AÑADIR REGISTROS El proceso para crear una column family Super es idéntico a las column family Standard, solo hay que cambiar un valor a la hora de crearla: Creación de una column family Super
  • 20. 20 Entramos en la página principal de la nueva column family y pulsamos en Insert Row. Aquí veremos que el formulario a cambiado un poco, nos aparece un nuevo campo llamado Super Column Name y un nuevo botón encima del formulario, Add Super Column: Formulario para insertar registros de una column family super Las column family Super son como las muñecas matrioskas, esas figuras que si las abrías había otra igual dentro, y dentro de esa otra más, y otra, etc. Algo parecido sucede con estas column family. Disponemos de una key (nuestra primera matrioska) que contiene a las super columns (segunda matrioska), que a su vez contienen las columnas clave:valor. Añadamos un registro para verlo: Datos para crear una super column Si nos vamos a Browse Data:
  • 21. 21 Listado de registros en una column family Super Como ves, ahora las columns se agruparían dentro de la super column. Añadiré más registros para que lo veas mejor: Listado de registros en una column family Super ¿Ves? Las keys agrupan a las super columns y estas a su vez a las columns. Creo que esto es suficiente para que conozcas el funcionamiento de Cassandra Cluster Admin. Quedarían algunas cosillas, como editar registros, hacer búsquedas o eliminar registros, pero eso es bastante sencillo (a excepción de las Secondary Index y las Counter Columns que trataré más adelante). Para cualquier duda o problema déjala en los comentarios. Cassandra 1.x y PHP para desarrolladores SQL: PHPCassa (I)
  • 22. 22 ¡Por fin llego el día! ¡Hoy toca programar! Para ello vamos a utilizar las clases de abstracción de la base de datos PHPCassa que nos ahorrará bastante tiempo para trabajar con Cassandra. Puedes descargarlo desde https://github.com/thobbs/phpcassa. Ubicamos PHPCassa en una carpeta dentro de nuestro servidor web y creamos dos archivos. Yo los he llamado test.php y cassandra.php. El segundo será una clase que nos ahorrará algunas lineas de código con las tareas habituales. El primero lo utilizaré para testear la clase y sus respectivos métodos. Bien empecemos. PRIMEROS PASOS En primer lugar necesitamos incluir un archivo de PHPCassa en cassandra.php: Códigofuente 1. <?php 2. 3. // CLASES NECESARIAS PARA CONECTAR CON CASSANDRA 4. require_once('phpcassa/lib/autoload.php'); He inmediatamente llamamos a los namespace mínimos para trabajar con PHPCassa: Códigofuente 1. <?php 2. 3. use phpcassaConnectionConnectionPool; 4. use phpcassaColumnFamily; 5. use phpcassaSystemManager; 6. use phpcassaSchemaStrategyClass; Justo debajo creamos la clase: Códigofuente 1. <?php 2. 3. class cassandra { 4.
  • 23. 23 5. } CONECTANDO Para realizar la conexión a la BD, PHPCassa nos pide tan solo un dato obligatorio: el nombre del keyspace con el que vamos a trabajar. También nos permite añadir las ips de los nodos con los que queramos trabajar, aunque por defecto su valor es localhost. Por tanto podemos crear un constructor como el siguiente: Códigofuente 1. <?php 2. 3. function __construct($keyspace, $nodos = array('localhost')){ 4. if (!empty($keyspace)){ 5. $this->conexion = new ConnectionPool($keyspace, $nodos); 6. }else{ 7. print "El keyspace está vacío"; 8. } 9. } Este constructor nos permite indicarle a la clase el keyspace con el que queremos trabajar y la ip o nombre de servidor donde se encuentre nuestra instancia de Cassandra. Por defecto el puerto al que se va a conectar es el 9160. Si hubieses configurado Cassandra para escuchar en otro puerto deberás especificarlo: localhost:9160. Este código nos crea una variable llamada conexion que será una instancia del objeto ConnectionPool, necesario para todas las consultas a la BD GUARDANDO REGISTROS Ahora procedemos a crear el método que guardará los registros. Para ello primero crearemos un objeto ColumnFamily al que le pasaremos el nombre de la column family en la que queremos trabajar: Códigofuente 1. <?php 2. 3. public function guardar($name_columnFamily, $key, $data = array()){ 4. try { 5. $column_family = new ColumnFamily($this->conexion, $name_columnFamily); 6. $column_family->insert($key, $data); 7. return true;
  • 24. 24 8. }catch(Exception $e){ 9. return false; 10. } 11. } Este método nos devolverá true si se ha guardado correctamente el registro, o false en caso de error. Como puedes ver, al objeto ColumnFamily se le pasa como primer parámetro el objeto ConnectionPool que creamos en el constructor, después se le pasa el nombre de la column family. Una vez creado el objeto ColumnFamily ya podemos utilizar el método insert para guardar el registro pasándole como parámetros la key y un array con las columnas y sus respectivos valores. RECUPERANDO REGISTROS Recuperar registros de Cassandra es algo más complejo que guardarlos: Primero debemos añadir un nuevo namespace que nos permitirá usar una clase que nos será muy útil. El listado de namespaces nos quedaría así: Códigofuente 1. <?php 2. 3. use phpcassaConnectionConnectionPool; 4. use phpcassaColumnFamily; 5. use phpcassaColumnSlice; 6. use phpcassaSystemManager; 7. use phpcassaSchemaStrategyClass; A continuación creamos el método en nuestro archivo cassandra.php: Códigofuente 1. <?php 2. 3. public function obtener($name_columnFamily, $key, $column_names= NULL, $range_start = "", $range_end = "", $column_count = 100, $invertir_orden=false){ 4. 5. try{ 6. $column_slices = new ColumnSlice($range_start, $range_end, $column_count, $invertir_orden); 7. $column_family = new ColumnFamily($this->conexion, $name_columnFamily); 8. $result = $column_family->get($key, $column_slices, $column_names); 9. }catch(Exception $e){ 10. return false;
  • 25. 25 11. } 12. 13. return $result; 14. 15. } Este método tiene algunos parámetros más que al guardar, pero tienen su razón de ser: $columnFamily: Nombre de la column family donde buscar. $key: Clave del registro donde buscar. $columns: Columnas a buscar. No es obligatorio. Por defecto NULL. $range_start: Key por la que Cassandra debe empezar a recuperar registros. No es obligatorio. Por defecto “”.$range_end: Key por la que Cassandra dejará de recuperar registros. No es obligatorio. Por defecto “”. $column_count: Número de registros a obtener, Por defecto 100. $invertir_orden: Invierte el orden en el que se recuperar los registros. De mayor a menor o viceversa, de la A-Z o viceversa, etc. Como ves tienes bastantes opciones para recuperar registros. Este método devuelve un array con los registros. PROBANDO LA CLASE Vamos a probar el código a ver que tal funciona. Nos vamos al archivo test.php y escribimos el siguiente código: Códigofuente 1. <?php 2. 3. include_once "cassandra.php"; 4. 5. $cass = new cassandra('my_keyspace', array('192.168.1.10')); 6. 7. $data = array( 8. 'nombre' => 'pepito', 9. 'ciudad' => 'Madrid', 10. 'vehiculo' => 'coche', 11. ); 12. 13. if ( $cass->guardar('my_column_family_standard', $key=1, $data)){ 14. print "El registro se ha guardado correctamente<br />"; 15. }else{ 16. print "Error al guardar el registro<br />"; 17. } 18. 19. $result = $cass->obtener('my_column_family_standard', $key=1);
  • 26. 26 20. 21. print_r($result); 22. ?> Explico un poco el código anterior: 1. Incluimoslaclase enel archivo. 2. Creamosel objetoindicándole el keyspaceconel que trabajar(my_keyspace),ydentrode un array, la ipdonde se encuentraennodode Cassandra.Si tuviesesCassandrainstaladoenlocalhostno sería necesarioindicarel segundoparámetro. 3. Creamosel array que contendrálosdatosa guardar. 4. Creamosun condicional que guardarálosdatosenCassandray nos indicarási se han guardado correctamente oha habidoalgúnerror. 5. Guardamosen unavariable ($result) losregistrosque recuperamosatravésdel método obtenerdel objeto$cass.A este métodole indicamoslacolumn family a buscar y lakey a obtener. 6. Mostramos losregistros. Si todo ha salido correctamente verás un texto como el siguiente cuando ejecutes el script: El registro se ha guardado correctamente Array ( [ciudad] => Madrid [nombre] => pepito [vehiculo] => coche ) Si te aparecen más registros es posible que no vaciases las column family con la que trabajas. Simplemente ves a Cassandra Cluster Admin, entra en la column family y pulsa en Truncate Column Family. Así eliminarás todos los datos de la column family. ACTUALIZAR UN REGISTRO Ahora que ya funciona nuestra clase podemos ampliarla con nuevas características. Aunque pienses que para actualizar un registro es necesario un nuevo método, en Cassandra no es necesario, simplemente utilizaremos el método guardar indicandole la key a modificar y el array con los datos a guardar. Justo debajo del código que ya tenemos en el archivo test.php escribimos lo siguiente: Códigofuente 1. <?php 2. 3. $data = array( 4. 'ciudad' => 'Barcelona', 5. ); 6. 7. if ( $cass->guardar('my_column_family_standard', $key=1, $data)){ 8. print "El registro se ha guardado correctamente<br />"; 9. }else{ 10. print "Error al guardar el registro<br />"; 11. }
  • 27. 27 12. 13. $result = $cass->obtener('my_column_family_standard', $key=1); 14. 15. print_r($result); Como observarás el array no tiene todos los datos de la key que vamos a modificar, ya que no es necesario, tan solo pasaremos los datos que queremos actualizar. El resultado de este código es el siguiente: El registro se ha guardado correctamente Array ( [ciudad] => Madrid [nombre] => pepito [vehiculo] => coche ) El registro se ha guardado correctamente Array ( [ciudad] => Barcelona [nombre] => pepito [vehiculo] => coche ) La columna ciudad a cambiado, el resto sigue igual, la razón está en que cuando le pasas a Cassandra una key que ya existe, lo que hace es actualizar las columnas que se correspondan con las keys del array. Si en ese array hubiera keys que no existen como columnas en el registro, Cassandra simplemente las crearía nuevas. GUARDANDO UNA SUPER COLUMN Aquí tampoco nos hace falta crear un nuevo método ya que nos sirve perfectamente el método guardar, pero deberemos hacerle algunas modificaciones. En primer lugar, para trabajar con column families super es necesario añadir una llamada al namespace concreto. La lista de namespaces quedaría de la siguiente manera: Códigofuente 1. <?php 2. 3. use phpcassaConnectionConnectionPool; 4. use phpcassaColumnFamily; 5. use phpcassaSuperColumnFamily; 6. use phpcassaColumnSlice; 7. use phpcassaSystemManager; 8. use phpcassaSchemaStrategyClass; Ahora debemos modificar el método guardar y añadirle el parámetro $is_super_column, que nos permitirá crear un objeto SuperColumnFamily o ColumnFamily según corresponda. El método nos quedaría así: Códigofuente 1. <?php 2.
  • 28. 28 3. public function guardar($name_columnFamily, $key, $data = array(), $is_super_column = false){ 4. 5. try { 6. if ($is_super_column){ 7. $column_family = new SuperColumnFamily($this->conexion, $name_columnFamily); 8. } 9. else{ 10. $column_family = new ColumnFamily($this->conexion, $name_columnFamily); 11. } 12. 13. $column_family->insert($key, $data); 14. return true; 15. }catch(Exception $e){ 16. return false; 17. } 18. } Como ambas clases comparten el método insert no nos hace falta incluir esa linea dentro del condicional. A continuación modificamos el método obtener con el mismo parámetro y utilizando el mismo sistema para crear el objeto correspondiente: Códigofuente 1. <?php 2. 3. public function obtener($name_columnFamily, $key, $is_super_column=false, $column_names= NULL, $range_start = "", $range_end = "", $column_count = 100, $invertir_orden=false){ 4. 5. try{ 6. if ($is_super_column){ 7. $column_family = new SuperColumnFamily($this->conexion, $name_columnFamily); 8. } 9. else{ 10. $column_family = new ColumnFamily($this->conexion, $name_columnFamily); 11. } 12. $column_slices = new ColumnSlice($range_start, $range_end, $column_count, $invertir_orden); 13. $result = $column_family->get($key, $column_slices, $column_names); 14. }catch(Exception $e){ 15. return false; 16. } 17. 18. return $result; 19. 20. } Ahora podemos añadir el siguiente código a nuestro archivo test.php:
  • 29. 29 Códigofuente 1. <?php 2. 3. $data = array('vecino_1' => array( 4. 'nombre' => 'pepito', 5. 'ciudad' => 'Madrid', 6. 'vehiculo' => 'coche', 7. )); 8. 9. if ( $cass->guardar('my_column_family_super', $key=1, $data, $is_super_column=true)){ 10. print "El registro se ha guardado correctamente<br />"; 11. }else{ 12. print "Error al guardar el registro<br />"; 13. } 14. 15. $result = $cass->obtener('my_column_family_super', $key=1, $is_super_column=true); 16. 17. print_r($result); El único cambio además del nombre de la column family donde vamos a guardar el registro, se encuentra en el array con los datos. Este tiene un elemento que es la key de la super column, y como valor, el array de las columns a guardar. Si ejecutamos el código anterior nos devolverá lo siguiente: El registro se ha guardado correctamente Array ( [vecino_1] => Array ( [ciudad] => Madrid [nombre] => pepito [vehiculo] => coche ) ) [ci-box type=”warning”]Al probar el código, PHP me devolvió el siguiente aviso: Strict Standards: Declaration of phpcassaSuperColumnFamily::add() should be compatible with that of phpcassaColumnFamily::add() in /var/www/prueba_cassandra/phpcassa/lib/phpcassa/SuperColumnFamily.php on line 491. No te preocupes no afecta ni a los ejemplos ni a la clase que funcionan correctamente.[/ci-box] ACTUALIZANDO UNA SUPER COLUMN La actualización de una super column se limita a las columnas que contienen los valores del registro no a su key. Si modificáramos la key , lo que en realidad estaríamos haciendo sería crear una nueva super column. Añadimos el siguiente código a nuestro archivo test.php: Códigofuente 1. <?php 2. 3. $data = array('vecino_1' => array(
  • 30. 30 4. 'nombre' => 'pepito', 5. 'ciudad' => 'Barcelona', 6. 'vehiculo' => 'coche', 7. )); 8. 9. if ( $cass->guardar('my_column_family_super', $key1, $data, $is_super_column=true)){ 10. print "El registro se ha guardado correctamente<br />"; 11. }else{ 12. print "Error al guardar el registro<br />"; 13. } 14. 15. $result = $cass->obtener('my_column_family_super', $key=1, $is_super_column=true); 16. 17. print_r($result); Y el resultado es: El registro se ha guardado correctamente Array ( [vecino_1] => Array ( [ciudad] => Barcelona [nombre] => pepito [vehiculo] => coche ) ) ELIMINAR REGISTROS Sí, aquí toca crear un nuevo método para nuestra clase en cassandra.php, aunque tampoco nos vamos a matar programando: Códigofuente 1. <?php 2. 3. public function eliminar($name_columnFamily, $key, $is_super_column = false){ 4. 5. try{ 6. if ($is_super_column){ 7. $column_family = new SuperColumnFamily($this->conexion, $name_columnFamily); 8. } 9. else{ 10. $column_family = new ColumnFamily($this->conexion, $name_columnFamily); 11. } 12. $column_family->remove($key); 13. return true; 14. }catch(Exception $e){ 15. return false; 16. }
  • 31. 31 17. } El método es bastante sencillo: se le pasan tres parámetros que ya conocemos. Dentro del método se crea un objeto ColumnFamily y se utiliza el método remove para eliminar el registro pasándole la key correspondiente, y si fuese una super column, la key de este. El método remove tiene un segundo parámetro que por defecto tiene un valor null, en él se pueden añadir como array los nombres de las columnas a eliminar. Como no es habitual ese proceso he creído adecuado no utilizarlo. Una vez añadido esté método a nuestra clase modificamos el archivo test.php con el siguiente código: Códigofuente 1. <?php 2. 3. if ( $cass->eliminar('my_column_family_standard', $key=1)){ 4. print "El registro se ha eliminado correctamente<br />"; 5. }else{ 6. print "Error al eliminar el registro<br />"; 7. } 8. 9. $result = $cass->obtener('my_column_family_standard', $key=1); 10. 11. print_r($result); Y el resultado es: El registro se ha eliminado correctamente De momento con esto es suficiente, dejo en tus manos estos métodos para que juegues con ellos todo lo que quieras y te familiarices con PHPCassa. En el próximo post trataré las Counter Columns que nos servirán para contar registros, los Secondary Index que nos permitirán realizar búsquedas por columnas concretas, y algunas cosas más. Cassandra 1.x y PHP para desarrolladores SQL: phpCassa (II)
  • 32. 32 En el anterior post traté las acciones habituales que realizamos con Cassandra: guardar, actualizar y eliminar. Sin embargo aun quedan dos acciones muy útiles por tratar: los contadores y los indices secundarios. CONTADORES Los contadores son en realidad un tipo especial de validador de Column Family. CREAR UN CONTADOR Para crearla procedemos de la siguiente manera: – Accedemos a Cassandra Cluster Admin: Página principal de Cassandra Cluster Admin – Entramos en el keyspace con el que estamos trabajando:
  • 33. 33 Detalle del keyspace my_keyspace – Pulsamos en Create New Column Family y escribimos los siguientes datos: Datos para crear una Column Family con contadores – En Default Validation Class el texto completo a escribir es:
  • 34. 34 org.apache.cassandra.db.marshal.CounterColumnType – Y pulsamos el botón Create Column Family. Varias cosas sobre los CounterColumn: – Para crear los CounterColumns es obligatorio indicar en Default Validation Class la clase de validador correcto. Indicado más arriba. – Los contadores puedes tener números positivos o negativos. – Los CounterColumns no son un sustituto de el autoincrement de las bases relacionales. Ahora que ya está creada la Column Family es hora de programar. GUARDAR Y/O ACTUALIZAR UN CONTADOR En nuestra clase en cassandra.php creamos el siguiente método: Códigofuente 1. <?php 2. 3. public function guardarContador($name_columnFamily, $key, $column, $value=1, $super_column=NULL){ 4. 5. try { 6. if (!is_null($super_column)){ 7. $column_family = new SuperColumnFamily($this->conexion, $name_columnFamily); 8. $column_family->add($key, $super_column, $column, $value); 9. } 10. else{ 11. $column_family = new ColumnFamily($this->conexion, $name_columnFamily); 12. $column_family->add($key, $column, $value); 13. } 14. return true; 15. } 16. catch(Exception $e){ 17. return false; 18. } 19. } Con este método podremos incrementar o disminuir el contador. $name_columnFamily: Es el nombre de la column family donde se encuentra el contador a modificar.
  • 35. 35 $key: Clave del registro donde se encuentra el contador. $column: Nombre del contador. $value: Valor a añadir al contador. $super_column: Clave de la super column donde se encuentra el contador. Añadimos el siguiente código a nuestro archivo test.php: Códigofuente 1. <?php 2. 3. if ( $cass->guardarContador('column_family_counter', 'post', 'num_total_post', 1)){ 4. print "El contador se ha actualizado correctamente<br />"; 5. }else{ 6. print "Error al actualizar el contador<br />"; 7. } 8. 9. $result = $cass->obtener('column_family_counter', 'post'); 10. 11. print_r($result); Como ves, para recuperar un contador se utiliza el mismo método que para obtener cualquier otro registro. El resultado de este código sería: El contador se ha actualizado correctamente Array ( [num_total_post] => 1 ) PONER A CERO EL CONTADOR Para poner a cero un contador hay que restarle el valor que tenga en ese momento el contador. En test.php escribiríamos lo siguiente: Códigofuente 1. <?php 2. 3. if ( $cass->guardarContador('column_family_counter', 'post', 'num_total_post', ($result['num_total_post']*-1))){ 4. print "El contador se ha actualizado correctamente<br />"; 5. }else{ 6. print "Error al actualizar el contador<br />"; 7. } 8. 9. $result = $cass->obtener('column_family_counter', 'post'); 10. 11. print_r($result);
  • 36. 36 Y el resultado: El contador se ha actualizado correctamente Array ( [num_total_post] => 0 ) INDICES SECUNDARIOS Los indices secundarios son un objeto especial en Cassandra que nos permite realizar búsquedas por columnas concretas. Estos índices solo funcionan en las column family standard, con lo que su uso se ve bastante limitado. CREAR UN INDICE SECUNDARIO Para ello vamos a nuestro Cassandra Cluster Admin y en la column family my_column_family_standard pulsamos en Create Secondary Index: Detalle de la ubicación del botón Create Secondary Index – Nos aparecerá el siguiente formulario: Detalle del formulario para crear un índice secundario – Para nuestro cometido vamos a crear el siguiente índice secundario:
  • 37. 37 Formulario con los datos para el ejemplo – Pulsamos en Add Secondary Index. REALIZAR UNA CONSULTA CON UN INDICE SECUNDARIO Nos vamos a nuestro archivo cassandra.php y añadimos el siguiente método: Códigofuente 1. <?php 2. 3. private function getIndexOperator($value){ 4. switch ($value){ 5. case '=': 6. $operator = 'EQ'; 7. break; 8. case '>=': 9. $operator = 'GTE'; 10. break; 11. case '>': 12. $operator = 'GT'; 13. break; 14. case '<=': 15. $operator = 'LTE'; 16. break; 17. case '<': 18. $operator = 'LT'; 19. break; 20. default: 21. $operator = 'EQ'; 22. break; 23. } 24. 25. return $operator; 26. } Este método nos permitirá trabajar con operadores diferentes a la igualdad, pudiendo utilizar >,<,>=,<=.
  • 38. 38 Pero para poder trabajar con índices es necesario incluir en nuestro listado de namespaces dos nuevas clases, tal y como se muestra en el siguiente código: Códigofuente 1. <?php 2. 3. use phpcassaConnectionConnectionPool; 4. use phpcassaColumnFamily; 5. use phpcassaSuperColumnFamily; 6. use phpcassaColumnSlice; 7. use phpcassaSystemManager; 8. use phpcassaSchemaStrategyClass; 9. use phpcassaIndexIndexExpression; 10. use phpcassaIndexIndexClause; A continuación creamos el método que generará la consulta con los índices secundarios. Códigofuente 1. <?php 2. 3. public function obtenerPorIndices($name_columnFamily, $arrayColumnsValues, $range_start = "", $range_end = '', $column_count = 100, $invertir_orden = false){ 4. 5. try{ 6. // Creamos el objeto 7. $column_family = new ColumnFamily($this->conexion, $name_columnFamily); 8. 9. // Inicializamos las variables 10. $index_exp = array(); 11. $registros = array(); 12. 13. // Creamos un array de index_expression 14. foreach($arrayColumnsValues as $key => $value){ 15. if (array_key_exists('operator', $value)){ 16. $op = $this->getIndexOperator($value['operator']); 17. } 18. else{ 19. $this->getIndexOperator('='); 20. } 21. 22. $column = $value['values']; 23. $key_column = key($column); 24. 25. $index_exp[] = new IndexExpression($key_column, $column[$key_column], $op); 26. } 27. 28. // Creamos la index_clause 29. $index_clause = new IndexClause($index_exp, $range_start, $column_count);
  • 39. 39 30. 31. // Creamos la column_slice 32. $column_slice = new ColumnSlice($range_start, $range_end, $column_count, $invertir_orden); 33. 34. // Recuperamos los registros 35. $rows = $column_family->get_indexed_slices($index_clause, $column_slice); 36. 37. foreach($rows as $key => $columns){ 38. if (!array_key_exists($key, $registros)){ $registros[$key] = null; } 39. $registros[$key] = $columns; 40. } 41. return $registros; 42. }catch (Exception $e){ 43. return false; 44. } 45. } Con este método podremos buscar registros con varios índices secundarios. Lo primero que hacemos en este método es crear el objeto ColumnFamily que nos proveerá de los métodos para hacer la consulta con indices secundarios. A continuación inicializamos varias variables necesarias para el método. Dentro de un bucle creamos un array de IndexExpression(). Este objeto le indicará a Cassandra qué indices, con qué valores y qué operador se deben buscar los registros. Seguidamente creamos la iIndexClause(), que nos permite indicarle la key desde la que comenzará a recuperar registros y el número de registros a obtener. Por último recuperamos los registros utilizando el método get_indexed_slices(). Para probar el método vamos a crear datos de prueba en test.php y haremos la consulta: Códigofuente 1. <?php 2. 3. $data[] = array( 4. 'title' => 'Apache Cassandra', 5. 'license' => 'Open Source', 6. 'category' => 'no-sql', 7. ); 8. 9. $data[] = array( 10. 'title' => 'MongoDB', 11. 'license' => 'Open Source', 12. 'category' => 'no-sql',
  • 40. 40 13. ); 14. 15. $data[] = array( 16. 'title' => 'MySQL', 17. 'license' => 'Open Source', 18. 'category' => 'sql', 19. ); 20. 21. foreach($data as $key => $value){ 22. $cass->guardar('my_column_family_standard', $key, $value); 23. } 24. 25. $arrayColumnsValues[] = array( 26. 'values' => array( 27. 'category' => 'no-sql' 28. ), 29. 'operator' => '=' 30. ); 31. 32. $result = $cass->obtenerPorIndices('my_column_family_standard', $arrayColumnsValues); 33. 34. print_r($result); Si ejecutamos el código anterior Cassandra nos devolverá: Array ( [0] => Array ( [title] => Apache Cassandra [license] => Open Source [category] => no-sql ) [1] => Array ( [title] => MongoDB [license] => Open Source [category] => no-sql ) ) [ci-box type=”warning”]Al utilizar un operador diferente al = puede que Cassandra te devuelva un error. Para evitarlo añade otro indice secundario a la consulta pero con el operador =, siendo este la primera columna que Cassandra procese. Por alguna razón Cassandra devuelve un error si no se hace así. [/ci-box] Con este post concluye la parte básica de PHPCassa, Cassandra y Cassandra Cluster Admin. En el próximo post y siguientes trataré varios temas que se han quedado un poco colgados o faltan por explicar como ordenar registros, cómo crear claves, mejorar el rendimiento de Cassandra, crear clusters, etc. Cassandra 1.x y PHP para desarrolladores SQL: phpCassa (III) Ya he tratado casi en su totalidad las funciones más básicas de PHPCassa y Cassandra, con lo que ya tendrás un conocimiento suficientemente amplio de lo que se puede hacer con ellos, el resto dependerá de la evolución de la BD y de las librerías (y de la experiencia que tengas xP).
  • 41. 41 Hoy trataré varios temas que por las consultas realizadas por varios usuarios se merece un post aparte en el que se pueda tratar de una forma más amplia. Estos temas son: ordenar registros, crear keys para los registros y contar registros. ORDENAR REGISTROS Cassandra dispone de varios tipos de comparadores y subcomparadores para ordenar los registros. El más habitual es UTF-8 pero hay varios más. Si vamos a Cassandra Cluster Admin y accedemos al formulario de creación de columns family, podremos pasar el ratón por los interrogantes que hay a la izquierda de los campos para poder ver los diferentes tipos de comparadores: Tipos de comparadores Como puedes ver, estos comparadores le dicen a Cassandra como ordenar los registros. Si has seguido este tutorial ya conocerás al menos uno de los comparadores (utf-8) por tanto vamos a ver como ordena Cassandra los registros con este comparador. Para este primer ejemplo vamos a crear una column family llamada column_family_order_utf8 de tipo standard y el tipo de comparador UTF8Type. Vamos a nuestro archivo test.php y escribimos el siguiente código: Códigofuente 1. <?php 2. 3. $data = array(); 4. $data[5] = array( 5. 'title' => 'Apache Cassandra',
  • 42. 42 6. 'license' => 'Open Source', 7. 'category' => 'no-sql', 8. ); 9. $data[3] = array( 10. 'title' => 'MongoDB', 11. 'license' => 'Open Source', 12. 'category' => 'no-sql' 13. ); 14. $data[1] = array( 15. 'title' => 'Neo4j', 16. 'license' => 'Open Source', 17. 'category' => 'no-sql', 18. ); 19. $data[4] = array( 20. 'title' => 'MySQL', 21. 'license' => 'Open Source', 22. 'category' => 'sql' 23. ); 24. $data[2] = array( 25. 'title' => 'MariaDB', 26. 'license' => 'Open Source', 27. 'category' => 'sql', 28. ); 29. 30. foreach($data as $key => $value){ 31. $cass->guardar('column_family_order_utf8', $key, $value); 32. } Este código guardará un array desordenado en nuestra column family. Una vez ejecutado el script accedemos a Cassandra Cluster Admin y visualizamos los registros de column_family_order_utf8, nos mostrará el siguiente resultado: Listado de los registros guardados
  • 43. 43 Como puedes observar los registros no se han ordenado, sin embargo cada una de las columns de cada registro sí están ordenadas por orden alfabético. Esto sucede porque los comparadores no ordenan por keys o claves de los registros sino por columns, aunque hay un caso especial, si la column family es super los registros si estarán ordenados. Veamoslo. Creamos una column family llamada column_family_utf8_super con el tipo de comparador UTF8Type y el tipo de column family como super. En nuestro archivo test.php añadimos el siguiente código: Códigofuente 1. <?php 2. 3. $data = array(); 4. $data[5] = array( 5. 'title' => 'Apache Cassandra', 6. 'license' => 'Open Source', 7. 'category' => 'no-sql', 8. ); 9. $data[3] = array( 10. 'title' => 'MongoDB', 11. 'license' => 'Open Source', 12. 'category' => 'no-sql' 13. ); 14. $data[1] = array( 15. 'title' => 'Neo4j', 16. 'license' => 'Open Source', 17. 'category' => 'no-sql', 18. ); 19. $data[4] = array( 20. 'title' => 'MySQL', 21. 'license' => 'Open Source', 22. 'category' => 'sql' 23. ); 24. $data[2] = array( 25. 'title' => 'MariaDB', 26. 'license' => 'Open Source', 27. 'category' => 'sql', 28. ); 29. 30. $cass->guardar('column_family_order_utf8_super', 'databases', $data); Una vez ejecutado este script nos vamos a nuestra column family y nos mostrará lo siguiente:
  • 44. 44 Listado de registros en la column family Como puedes observar ahora sí están ordenados los registros, pero claro ahora están dentro de una super column. En Cassandra la ordenación se realiza a las columnas del registro o los registros dentro de las super columns, si creasemos otra super column, esta no se ordenaría con respecto a la ya creada, ‘databases’. Aunque esta ordenación puede ser útil y totalmente funcional, para los desarrolladores que vengan de las bases de datos relacionales les puede resultar confuso. Por ejemplo, para guardar los comentarios de un post de un blog podríamos utilizar este tipo de ordenación perfectamente, ya que podemos utilizar el id del post como key de la super column (el ‘databases’ de la imagen anterior se sustituiría por el id del post) y el timestamp (como este 1337787675.32246500) para la key de los registros. De esta forma tendríamos ordenados los comentarios por tiempo y por post. Si quisieramos recuperar los comentarios de un post concreto solo tendríamos que pasarle al método correspondiente el id del post como key de la super column. ¿Y si quisieramos guardar los post del blog? En este caso una column family super nos lo podría resolver indicando como key de la super column ‘posts‘ y utilizando como key en los registros el timestamp. Pero si quisieramos hacer busquedas utilizando indices secundarios una column family super no nos valdría, ya que los indices secundarios no funcionan en ellas. Para ello habría que crear una column family standard para los post, que nos permitirá usar los indices secundarios, y una column family super para guardar las keys de los post dentro de una super column con key, por ejemplo, ‘key_posts‘. Para hacer la consulta habría que recuperar las keys de los posts a mostrar en primer lugar, y después, utilizando un método de PHPCassa que aun no hemos usado recuperar los registros correspondientes a esas keys.
  • 45. 45 El método que deberíamos añadir a nuestro archivo cassandra.php sería el siguiente: Códigofuente 1. <?php 2. 3. function obtenerMultiplesRegistros($name_columnFamily, $multiKeys, $super_column = ''){ 4. 5. if (!empty($super_column)){ 6. $column_family = new SuperColumnFamily($this->conexion, $name_columnFamily); 7. $result = $column_family->multiget_super_column($multiKeys, $super_column); 8. } 9. else{ 10. $column_family = new ColumnFamily($this->conexion, $name_columnFamily); 11. $result = $column_family->multiget($multiKeys); 12. } 13. 14. return $result; 15. 16. } A este método le pasamos el nombre de la column family standard donde hemos guardado los posts y un array con las keys a recuperar, nos devolverá un array con los datos de cada uno de los posts que le hemos pedido… y en el orden en el que le hayamos pasado las keys a recuperar. Existe otra forma de ordenar registros, pero además de que en versiones posteriores de Cassandra desaparecerá y provoca problemas de rendimiento, yo no la recomiendo, ya que pierdes todos los beneficios que ofrece Cassandra. Aun así os dejo un link para que le echéis un ojo xD: http://ria101.wordpress.com/2010/02/22/cassandra-randompartitioner-vs-orderpreservingpartitioner/ Y os dejo otro link para que tengais algo más de información respecto a ordenar registros en Cassandra: http://ayogo.com/blog/2010/04/09/sorting-in-cassandra/ CREAR CLAVES O KEYS PARA LOS REGISTROS Como has podido ver en el apartado anterior, para ordenar los registros es muy importante tener una key de cada registro que sea única y siempre vaya en orden. Esto las bases de datos relacionales nos lo dan ya hecho, sin embargo en las bases de datos no-sql esto no es así.
  • 46. 46 Las bases de datos no-sql se crearon para optimizar la lectura y escritura de los registros en la base de datos, esto provocó que algunas funcionalidades muy útiles en las bases relaciones no tuvieran cabida en las no-sql. Por tanto para mantener en orden los registros debemos crear nosotros nuestras propias claves. PHPCassa dispone de un método para crear una clave aleatoria basada en el timestamp. Para utilizarla primero añadiremos la clase a nuestra lista: Códigofuente 1. <?php 2. 3. use phpcassaConnectionConnectionPool; 4. use phpcassaColumnFamily; 5. use phpcassaSuperColumnFamily; 6. use phpcassaColumnSlice; 7. use phpcassaSystemManager; 8. use phpcassaSchemaStrategyClass; 9. use phpcassaIndexIndexExpression; 10. use phpcassaIndexIndexClause; 11. use phpcassaUUID; Ahora crearemos un nuevo método en nuestro archivo cassamdra.php que devolverá la clave: Códigofuente 1. <?php 2. 3. public function obtenerUuid(){ 4. 5. $util = new UUID; 6. 7. return $util->import($util->uuid1()); 8. } Como me está quedando un post muy largo os voy a dejar algo de deberes xD. Sería interesante probarlo tanto con column families standard y super, además de con un tipo de comparador UTF8Type y TimeUUIDType. Como el chorro de letras y números que devuelve es muy poco legible yo suelo utilizar mi propio sistema de claves, normalmente utilizo el microtime() de php y un par de ids de lo que se esté guardando: el id del usuario, el id de lo que se ha creado, etc. Algo que lo diferencie del resto. Para la clave primero pongo los segundos que devuelve microtime() y después los microsegundos. Para que os hagais una idea sería algo así:
  • 47. 47 $key = $segundos . ‘.’ . $microsegundos . ‘_’ . $id_post . ‘_’ . $id_usuario; De esta forma le estamos dando una clave para los ejemplos del anterior apartado, más concretamente para los comentarios en un post. CONTAR REGISTROS El último apartado de este post. Contar registros. Esto es algo que Cassandra no lleva muy bien, sobre todo con grandes cantidades de información. Cassandra cuando recibe una petición de lectura/escritura utiliza unas tablas en memoria llamadas memtables (el que le puso el nombre de rompió la cabeza pensando). Cuantas más peticiones reciba Cassandra más memtables creará, de esta forma permitirá una cierta consistencia de la información almacenada en la base de datos. Cuando le pedimos a phpCassa que nos devuelva el número de registros en una column family o en una super column concreta, lo que está haciendo en realidad es hacer una petición a Cassandra de todos los registros que haya en la column family o en la super column. Cuando esto ocurre Cassandra guardará estos registros en la RAM del servidor antes de enviarlos a phpCassa, y sí Cassandra no cuenta los registros, porque no está pensada para eso, es phpCassa la que cuenta los registros y te devuelve el número concreto. El método que utiliza phpCassa para contar registros es el que os muestro a continuación, dentro de un método para añadir al archivo cassandra.php: Códigofuente 1. <?php 2. 3. public function contar_registros($name_columnFamily, $key, $super_column='', $range_start='', $range_end=''){ 4. 5. $column_slice = new ColumnSlice($range_start, $range_end); 6. 7. if (!empty($super_column)){ 8. $column_family = new SuperColumnFamily($this->conexion, $name_columnFamily); 9. $result = $column_family->get_subcolumn_count($key, $super_column, $column_slice); 10. } 11. else{ 12. $column_family = new ColumnFamily($this->conexion, $name_columnFamily); 13. $result = $column_family->get_count($key, $column_slice); 14. } 15.
  • 48. 48 16. return $result; 17. 18. } Esta forma de contar registros provoca que Cassandra consuma todos los recursos de RAM del servidor, con lo que no os la recomiendo. La mejor manera de contar registros con Cassandra es utilizar una column family con contadores, de tal forma que en nuestro código cada vez que se guarde un registro en la bd se aumente el contador que lleva la cuenta de los registros guardados. En el caso de que se eliminen, habría que disminuirlo. Y en el caso de que el registro se esté actualizando controlar que no aumente el contador xD. Cualquier duda que tengais intentaré responderla lo mejor posible en los comentarios. Cassandra 1.x y PHP para desarrolladores SQL: Clusters Cassandra permite crear anillos o clusters de servidores de una forma muy sencilla, esto nos permitirá levantar nuevos servidores dentro de un cluster en cuestión de varios minutos. Para ello tendremos que modificar la configuración de la BD. En /etc/cassandra modificamos el archivo cassandra.yaml. Buscaremos la siguiente línea: - seeds: "localhost" Y sustituimos localhost por la ip local del servidor, en mi caso 192.168.1.10. - seeds: "192.168.1.10" A continuación modificamos las siguientes líneas: listen_address: localhost [...] rpc_address: localhost Por: listen_address: 192.168.1.10
  • 49. 49 [...] rpc_address: 192.168.1.10 Guardamos y reiniciamos el servidor. Ahora el servidor con esta configuración será al que se conecten el resto de servidores del cluster. Para el resto de servidores la configuración es parecida. En seeds mantenemos la ip del servidor principal y en listen_address y rpc_address ponemos la ip del servidor a unir al cluster: - seeds: "192.168.1.10" [...] listen_address: 192.168.1.103 [...] rpc_address: 192.168.1.103 Utilizo la ip 192.168.1.103 ya que es la que tengo configurada en mi cluster de prueba, tu deberías poner la ip correspondiente a la máquina donde estés configurando Cassandra. Guardamos y reiniciamos la BD. Esto es todo lo que hay que hacer para crear un cluster con Cassandra