lunes, 27 de agosto de 2012

Review de NoSQL - MongoDb

Experiencias con MongoDb.

Bueno en un inicio habia visto Cassandra de la Apache Foundation, pero por alguna razon no termine de engancharme, sabia que esto de los NO SQL era un tema importante a ver pero paso el tiempo, ahora que retome y ya me encuentro bastante mas metido en el tema es que escribo sobre mi expereincia con MongoDb.

Basicamente opte por ella por que vi que habia mucha documentacion y tenia drivers para poder hacer pruebas desde Python.


El set de pruebas es el siguiente:

5 millones de registros, cada uno de 42 campos.
La maquina es una Notebook DELL i3 con 3 GB Ram, disco de 250 y Ubuntu 12.04 64bits.
Los paquetes son exclusivamente de repositorios.

Como primera cosa opte justamente bajar los paquetes originales que ofrecia ubuntu, aun estaba con la version 32 bits, no sabia, ni habia leido de limitaciones sobre espacios, pero dejenme decirles que la mejor opcion si aun no lo han hecho es ver de instalar una version de 64 bits. Esto es basicamente por que la version de 32 solo admite hasta 2 Gbytes, y para las pruebas que queria realizar debia poder usar mas que esa capacidad, la version de 64 no tiene limites.

Bien entonces luego de migrar todo el equipo a ubuntu de 64 reinstale todos los paquetes y puse manos a la obra.

Prepare una pequeña app en python que me permitiria pasar de a 100000 registros a esta nueva base.

Antes que nada vamos a usar los terminos de manera correcta.

SQL NoSQL
--------------------------------------
DATABASE DATABASE
TABLE COLLECTION
REGISTER DOCUMENT

Es cuestion de algunos cambios de nombre, pero el concepto es casi el mismo sobre lo que a organizacion se refiere. Pero aqui terminan esas similitudes.
El noSQL difiere con las clasicas estructuras de SQL, aqui no se usa el tipico lenguaje SQL, los datos no requieren un estructura fija como en las tablas, aca no hay joins y no se granrantiza atomicidad, coherencia, aislamiento y durabilidad.

Estas bases de datos que permiten escalar de manera muy interesante en horizontal son las que usan grandes empresas como Amazon, Google, Twitter... es decir aquellos que estan guardando de manera constante grandes cantidades de informacion. Que necesitan tener alta disponibilidad, full index, replicacion, almacenamiento de documentos, etc. o se si usamos este tipo de base de datos estamos jugando como lo hacen los grandes...
No es que este menospreciando a otras RDBM, esto es diferente.

Como primera cosa que me encontre es que si uno esta acostumbrado a hacer SELECT * FROM... bueno aca eso no esta.

Creamos nuestra primera base de datos desde el shell de mongo de esta manera:

use miDb

esto ya creo la db, asi de facil, bueno agreguemos unos datos... perdon DOCUMENTOS...

db.miColeccion.insert({“nombre”: “juan”, “apellido”: “perez”})

si asi, sin mas ni mas... pero quiero ver que creo...

db.miColeccion.find()

{ "_id" : ObjectId("5039d449e8b6579e419a8082"), "nombre" : "juan", "apellido" : "perez" }

y si quiero gurdar otra cosa diferente...

db.miColeccion.insert({“nombre”: “pedro”, “apellido”: “garcia”, “edad”: “30”, “ciudad”: “buenos aires”})

y esto se guarda sin preguntas sin errores por que agregamos mas “campos” de los que habiamos guradado antes... miremos a ver que sale...
> db.miColeccion.find(){ "_id" : ObjectId("5039d449e8b6579e419a8082"), "nombre" : "juan", "apellido" : "perez" }
{ "_id" : ObjectId("5039d61b814cce694f0cae64"), "nombre" : "pedro", "apellido" : "garcia", "edad" : "30", "ciudad" : "buenos aires" }


y si quiero ver solo los nombres...
db.miColeccion.find({},{“nombre”:1})

bueno para no seguir agobiando con la lista de convinaciones y equivalencias para hacer lo mismo en SQL vamos con las comparaciones de tiempos...
Voy a comparar entre Mysql en su version 5.5 contra MongoDb en su version 2.0.4
para hacer un poco mas rapida la situacion voy a hacer que las consultas se ejecuten desde un script en python.

De los 5 millones vamos a trabajar con un conjunto de 1367486 registros.

CACHE LIMPIO PARA MYSQL:
RESET QUERY CACHE

Count(*)
Mysql 10.02 segundos
MongoDb 141.27 segundos

Limit 10
Mysql 0.15 segundos
MongoDb 0.00 segundos

Order by (10000 documentos o registros)
Mysql 72.24663687 segundos
MongoDb 0.00012994 segundos

Insert (1 solo registro)
Mysql 0.18899107 segundos
MongoDb 0.00038910 segundos

Insert (10000 registros)
Mysql 2.72425699 segundos
MongoDb 0.66726208 segundos

Aun estoy haciendo pruebas sobre el rendimiento, aspectos a probas son los de hacer un update, o iniciar tests mas profundos sobre hacer un relacional por medio de los keyword _id de MongoDb.

Mis conclusiones hasta ahora son buenas y si bien no esta todo dicho respecto a las ventajas y desventajas de SQL y NoSQL he visto que este modelo puede ser de mucha utilidad para una buena cantidad de tipos de desarrollo.

Aun no he probado la opcion de GridFS para poder almacenar mas alla de los 16mb por documento que tiene como limitacion, pero seguramente hare una nueva entrega con las pruebas que ejecute.

Codigo usado para pruebas:

# -*- coding: utf-8 *-*
import pymongo
import datetime
import MySQLdb
import time

print("Inicio APP - TEST")

dbMysql = MySQLdb.connect(host='127.0.0.1',
user='root',
passwd='123456',
db='DATADBTEST')

conn = pymongo.Connection()
db = conn.datadbtest

sql = """/* QUERY */"""
inicio = time.time()
cursor = dbMysql.cursor()
cursor.execute(sql)
resultado = cursor.fetchall()
fin = time.time()
tf = fin - inicio
print "MySQL - contar cantidad de registros: %0.8f " % (tf)

print("\n\n")
post = {'KEYWORD':'VALOR'}
inicio = time.time()
db.coltest.insert(post)
fin = time.time()
tf = fin - inicio
print "MongoDb - contar cantidad de registros: %0.8f " % (tf)

Saludos y hasta la proxima...

Sitio oficial: www.mongodb.org


by marcelo.martinovic@gmail.com