Búsqueda en Rails con Sphinx

Written on February 11th, 2008
.

Cuando lo que quieres es maximizar el rendimiento de tu aplicación en consultas y búsquedas en una base de datos con millones registros normalmente utilizar el indexador y buscador de MySql no es la mejor opción.

Desde hace poco se mueve por la red Sphinx, pero la verdad es que está pegando muy fuerte, digamos que es el nginx del mundo de la búsqueda (rápido y ruso) según Evan Weaver.
Sphinx se divide de 2 componentes:

  • Indexador: es la parte que procesa toda la información recogida por un crawler y genera uno o varios índices.
  • Buscador: componente que consulta el índice y recupera la información resultante

Instalación

Para instalarlo en GNU/Linux o en cualquier sabor de *nix necesitamos compilar desde las fuentes par eso hacemos:

$ wget http://www.sphinxsearch.com/downloads/sphinx-0.9.7.tar.gz
$ tar xvzf sphinx-0.9.7.tar.gz
$ cd sphinx-0.9.7
$ ./configure --with-mysql-includes=/opt/local/include/mysql5/mysql/
--with-mysql-libs=/opt/local/lib/mysql5/mysql/
$ make
$ sudo make install

Lógicamente los parámetros –with-mysql-includes y –with-mysql-libs tendrás que poner los tuyos propios. En el primer caso serán los ficheros cabecera que nos conectan con mysql y en el segundo será la ruta a las librerías de mysql.
En este tutorial estoy configurando para MySql pero también se puede hacer para PostgreSQL.

Ligándolo con Rails

Inicialmente voy a utilizar el plugin UltraSphinx de Evan que está genial para emprezar con un sphinx.conf auto-generado. Despues indexamos el contenido entero de lo que nos interese.

El ruido que está haciendo en la red es porque es tremendamente rápido, por ejemplo para una base de datos con una tabla con 1.5 millones de registros el chaval lo hace en solo unos pocos minutos. La rapidez de búsqueda es tambien muuy rápida. Desforturnadamente he tenido problemas con mi aplicación Rails con el plugin UltraSphinx instalado – algunos errores muy extraños sucedieron.

Habiendo probado varios plugins para Sphinx me decanté por probar acts_as_sphinx. Despues de algunas modificaciones en el fichero sphinx.conf (y volver a reindexar) la búsqueda estaba trabajando y mucho más importante, también sobre mi aplicación Rails. Una opción alternativa es Sphincter pero tiene una documentación limitada.

Indexando y flipando

Ahora sobre nuestra aplicación Rails corremos:

$ rake sphinx:index
$ rake sphinx:start

Indexando en mi MacBook…

$ time rake sphinx:index
using config file 'sphinx.conf'...
indexing index 'items'...
collected 1455733 docs, 1255.2 MB
sorted 182.4 Mhits, 100.0% done
total 1455733 docs, 1255246639 bytes
total 438.695 sec, 2861316.50 bytes/sec, 3318.32 docs/sec
real    7m25.307s
user    4m28.963s
sys     0m17.578s

Y ahora sobre rails

Vasmos a probar con el plugin acts_as_sphinx via consola (ruby script/console) el término ‘Rails’, ordenando por fecha de publicación.

>> search = Item.find_with_sphinx 'Rails',
           :sphinx => {
                       :sort_mode => [:attr_desc, 'pub_date'], :page => 1
            },
            :order => 'items.pub_date DESC'; 0
=> 0
>> search.total
=> 1000
>> search.total_found
=> 73717
>> search.time
=> "0.000"

Esto es, un índice de 943Mb de almenos 1.5 millones de elementos. Nótese que los resultados de la búsqueda se limitaron a 1000 en el fichero de configuración sphinx.conf.

En el controlador de Rails, la búsqueda se hace a través de:
@items = Item.find_with_sphinx(params[:query],
:sphinx => {:sort_mode => [:attr_desc, 'pub_date'], :limit => 50, :page => (params[:page] || 1)},
:order => 'items.pub_date DESC')

Actualizando el índice de Sphinx

Como para cada casi toda taréa en Rails, existe una tarea de _rake_ para actualizar el índice de Sphinx que puede ser llamado mediante una entrada en cron, frente a las actualizaciones en ‘vivo’.
El comando rotate nos permite reindexar el índice mientras el demonio de Sphinx está corriendo, forzando el reinicio una vez se haya completado

$ rake sphinx:rotate

Presumiendo con Ruby

Written on January 20th, 2008
.

Es bien conocido que Ruby es uno de los lenguajes que más cercanos y que más satisfacción dan al programador. ¿Pero que pensarías si te enseñara esto?

ejemplo codigo ruby1 Presumiendo con Ruby

Y es muy difícil de implementar? Sigue leyendo!

ejemplo implementacion codigo ruby11 Presumiendo con Ruby

Mola un cacho, eh?

Solo tienes que recordar correr el programa con el flag KCODE -Ku, esto es, ruby -Ku nombre_programa,rb  :)

Benchmarks de Ruby 1.9

Written on December 27th, 2007
.

lenguaje ruby1 Benchmarks de Ruby 1.9Recientemente ha salido Ruby on Rails versión 2 que todavía estoy estudiando para llevar a cabo un review. Pero ahora mismo voy a mostrar unos pequeños benchmarks de Ruby 1.9, versión recién salida del horno, y que por lo que parece los se va acercando a lenguajes más “enterprise”.

Pero vayamos al meollo de la cuestión, inicialmente había pensado en crearme alguna función que cargue el sistema de procesos pero como soy un Vago Bueno™, he deducido que el Makefile del intérprete de Ruby tenía que tener algún sistema de benchmark.

Descargaremos la nueva versión 1.9.0 y compilaremos como siempre ./configure && make && make test && make install. Así que lanzaremos lo siguiente:

make benchmark

Esta tarea detectará tu versión anterior y ejecutará un elevado número de pruebas comparando la versión recién compilada con la antigua, he aquí un ejemplo que se lleva a cabo.

vm1_rescue

i=0
while i<30000000 # while loop 1
  i+=1
  begin
  rescue
  end
end

ruby 1.8.6 (2007-09-24) [universal-darwin9.0]    11.3471548557281
ruby 1.9.0 (2007-12-25 revision 14709) [i686-darwin9.1.0]    1.78452610969543

La mejora es evidente, también es verdad que en algunos casos la mejora no es tan sustancial y en otras contadas ocasiones incluso empeora la anterior marca de tiempo. Si queréis ver el reporte completo de mis pruebas os dejo aquí el archivo Benchmarks de Ruby 1.9

Para aquel que esta más interesado en hacer benchmarks de sus scripts, es bueno utilizar la clase Benchmark, que da muchísimas facilidades para llevar a cabo pruebas de forma muy rápida.

Ahora solo falta que el amado/odiado ActionPack de Ruby on Rails soporte MultiThreading para que volemos. Aunque me está gustando el proyecto Merb, que a costa de perder alguna mágia este si que es multithread y ya no corre… vuela.

Por cierto que si estás interesado en benchmarks más generales y más fidedignos pasate por esta review.

De Symbian, mi Nokia e65 y Ruby

Written on October 20th, 2007
.

image De Symbian, mi Nokia e65 y RubyRecientemente me he comprado el móbil que veis en la imagen, el Nokia E65, y que decir para describirlo despues de testearlo y estresarlo durante unos días, pues yo diría

Impresionante

Este dispositivo es de lo má estilizado que he visto con una slide activa incorpora 3G y conexión WIFI (WPA(1 y 2) Personal o Enterprise, WEP), cuatribanda, con cámara de 2 megapíxeles, sincronización de cuentas de correo IMAP4 y POP3, utilidades de oficina (lector pdf) y una de las cosas más importantes, totalmente integrable con GNU/Linux esto es, sincronización de contactos, notas, calendario y demás gracias a msynctool y gracias a este tutorial.

De la apariencia solo decir que es impecable, todo muy estilizado, slide muy robusto, tapa de batería en “cuero”, y el resto de plástico “Bat-man”.

El sistema operativo un Symbian 9.1, s60, que nunca lo había probado y cada día que sorprende más.

Y atención, me ha surgido la idea y se me encendió la lucecilla, Ruby for Symbian. He buscado en la red y ya hay una Proof-of-Concept, desde esta página podeis descargar el “irb” para mobiles symbian además de algunas ideas de como programar una aplicación con Ruby. Ya os iré contando de las cosillas que desenvolveré con Ruby para este flamante mobil.