View all posts

¿Programando un buscador en su sitio web? Te va a interesar Sphinx

Cuando se trata de búsquedas customizadas en un sitio web, lo principal es que los resultados sean tan precisos como sea posible. Para esto podemos utilizar técnicas como las sugerencias de búsqueda o búsquedas semánticas. Sin embargo, dada la competitividad de la web existe un parámetro más, vital para un sistema de búsqueda web: la velocidad.

Existen diversas técnicas que permiten acelerar las búsquedas en una página web. Antes de escoger alguna técnica para acelerar las búsquedas, es necesario identificar cual es el balance costo/beneficio que podemos obtener de esta.

El propósito de este artículo es presentar a Sphinx como una excelente técnica de aceleración de búsquedas, a la vez que resume su integración en un sistema y analiza en cuales ambientes se podría podría obtener mayor ventaja.

Sphinx

Sphinx es un servidor de búsqueda de texto completo (Full Text Search). Sphinx LogoEsto significa que se conecta con el repositorio de datos y crea índices textuales, los cuales son consultados en cada búsqueda, en lugar de ir hasta el repositorio de datos. Las búsquedas indexadas de Sphinx pueden resultar hasta 50% más rápidas que una búsqueda común en un repositorio Claro que este resultado varía dependiendo de la potencia del servidor y del tamaño del conjunto de índices (en adelante: colección) que se indexa.

Es importante aclarar que Sphinx funciona con las base de datos comunes al desarrollo web (SQL Server, MYSQL, Oracle, PostgreSQL, etc…), pero también con colecciones de documentos o cualquier objeto que pueda ser indexado textualmente, desde archivos de texto simples hasta pdfs.

Compañías tan importantes como WordPress y Mozilla lo están utilizando actualmente.

Benchmarks

Veamos la siguiente tabla comparativa entre Sphinx y Mysql (tomada del blog oficial de Sphinx).

N Consulta Resultados de MySQL Tiempo Resultados de Sphinx Tiempo k
1 min(a) 2244 0.39s 2244 0.08s 4.9x
2 min(a+b*c) 790494849806 0.45s 309 0.09s 5.0x
3 min(bigint(a)+b*c) 790494849806 0.45s 790494849806 0.11s 4.1x
4 sum(sin(a+b+c)) -695.3422782.. 0.50s 765.542419 0.17s 2.9x
5 max(a+b*2-c/3*4+5+6+7+8+9) 6404668209 1.42s 6404668416 0.14s 10.1x
6 max(a+b*2-c*4/3+35) 6404668209 1.05s 6404668416 0.14s 7.5x
7 max(a+b*2-c*1.333333333+35) 6404668209.003.. 0.84s 6404668416 0.14s 6.0x
8 max(a+b*2-idiv(bigint(c),3)*4+5+6+7+8+9) 6404668209 1.42s 6404668209 0.14s 10.1x
9 avg(a*b/c/1/2/3/4) 326342841.944.. 2.55s 326041280.000 0.13s 19.6x
10 avg(a*b/c/24) 326342841.944.. 1.39s 326041280.000 0.13s 10.7x

Como vemos en negrita, Sphinx siempre es considerablemente más rápido que Mysql para todas las búsquedas, lo cual es en promedia un rendimiento casi 10 veces superior. De hecho, se ha calculado que Sphinx puede ejecutar más de 500 consultas por segundo en una colección de un millón de documentos, mucho más de lo que muchos sistemas de búsqueda web podrían alcanzar.

Relevancia

Sphinx siempre devuelve un campo más, el weigth, peso o relevancia del resultado. Este valor significa qué tanta coincidencia tuvo este resultado con respecto a la búsqueda del usuario. Con esto, y sin programar una sola línea de código más, podemos presentarle al usuario los resultados ordenados por su relevancia para la búsqueda, un plus muy importante en una búsqueda web.

Indexación

Para encontrar una coincidencia entre un registro del repositorio (AKA: documento) y la busqueda de un usuario, Sphinx busca en los índices y retorna los resultados cuyas palabras claves coincidan de acuerdo con la forma en que fue creado el índice. Los índices, por supuesto, son completamente configurables. Entre muchas otras opciones, para cada índice se puede definir:

  • Tamaño del keyword: si se buscará por palabras completas o por secciones de palabras. Esto es, si se busca Aeropuerto, Sphinx podría retornar solamente los documentos que coincidan con la palabra, o también aquellos que contengan las palabras aero y puerto. Además, para hacer más ágil el índice, se eliminan artículos y preposiciones.
  • Palabras restringidas (stopwords): Palabras que no serán tomadas en cuenta para una búsqueda.
  • Stemming: El stemming es un método para reducir una palabra a su raíz. Por ejemplo, si se busca bibliotecas. Sphinx podrá retornar palabras que vengan de la misma raíz como bibliotecario o bibliotecario.

Sphinx cuenta con un solo archivo de configuración, muy sencillo, en donde se detalla como será indexado cada documento y de cuales fuentes (tablas, directorios) serán tomados.

Filtros y Geolocalización

Algo muy interesante sobre Sphinx es la capacidad que tiene para desarrollar búsquedas geolocalizadas, es decir, que tomen en cuenta distancias geográficas reales. Por ejemplo, si quiero encontrar todos los restaurantes de mi colección que estén a menos de 5 km de mi posición actual.

Para esto, es necesario saber la longitud y latitud de mi posición actual y que cada documento tenga un campo para su longitud y su latitud.

Por supuesto, la longitud y la latitud deben estar contemplados en el índice. Pero además debe existir un filtro. Sphinx permite crear filtros en cada índice para extender las posibilidades de las búsquedas. Por ejemplo, puedo hacer una consulta para encontrar todos los documentos que sean restaurantes en mi colección, pero además aplicaré el filtro de geolocalización @geo con la latitud y longitud de mi posición actual, de modo que Sphinx solo retorne los restaurantes que estén a menos de 5 Km.

Metodología de Indexación

La información de la base de datos va a actualizarse. Es necesario, entonces, actualizar la información de los índices. Para esto normalmente se crea alguna tarea programada o Cronjob que corra en el servidor cada cierto tiempo y ejecute el comando indexer, el script de indexación de Sphinx. Este tiempo varía según qué tanto movimiento exista en los repositorios.

¿Problema resuelto? Casi… Resulta que la indexación puede ser un proceso costoso, dependiendo de la cantidad de documentos a indexar, la capacidad del servidor y de la complejidad de la consulta que se vaya a utilizar para generar cada índice. Por ejemplo, imagine que tenemos una base de datos de restaurantes. Cada restaurante tiene varias locaciones, distintas especialidades y distintos platillos a ofrecer. Digamos que el requisito de la búsqueda con Sphinx es que se pueda ubicar un restaurante por cualquier palabra almacenada en la tabla que guarda la información del restaurante, o por cualquiera de sus locaciones, o por cualquiera de sus especialidades o platillos. Sin importar cuán optimizada esté una consulta, esta será significativamente más “costosa” que una consulta sobre una sola tabla. Imagine ahora, que tenemos cinco mil restaurantes en nuestro sistema y dos o tres veces más esa información para las locaciones, platillos y especialidades.

Se ha calculado que Sphinx puede indexar de 10 a 15 MB de texto por segundo por núcleo de CPU en un servidor dedicado. Sin embargo, no siempre se cuenta con un servidor dedicado, por lo cual estos números pueden bajar significativamente. El gran problema es que si la indexación toma mucho tiempo se podrían desplegar resultados obsoletos en las búsquedas. Por ello se debe intentar reducir el tiempo de indexación al mínimo, a segundos.

Para ello existen los deltas. Los deltas son un tipo especial de indice que solamente toma en cuenta los últimos registros modificados. Existirá un delta por cada índice. Entonces, en cada indexación, simplemente se re-indexa un delta y se mezcla con el índice original, de este modo la información queda actualizada en segundos, o menos.

Algunos contras

Sí, Sphinx tiene algunos contras. El primero y más grande es que Sphinx no admite documentos que tengan el mismo identificador. Esto es, por ejemplo, si la consulta que crea mi índice de restaurantes retorna dos veces mi restaurante, debido a que tiene dos ubicaciones distintas, Sphinx solo incluirá una de estas en el índice, y la otra será sobreescrita. Para solucionar esto es necesario tener índices aparte, u optimizar la consulta para que ambas ubicaciones se agrupen, lo cual puede ser complejo.

En este mismo sentido está otra desventaja: hacer una búsqueda que incluya diferentes objetos requeriría que el sistema sea pensado para Sphinx, es decir, que no existan identificadores repetidos en toda la base de datos. Siguiendo con los restaurantes, si quiero crear un índice que me permita encontrar restaurantes y clientes en una sola búsqueda, tendría que crear un índice para ello, pero esto significa que las tablas de restaurantes y clientes deben estar sincronizadas de modo que no existan identificadores repetidos. Esto hace muy complejo incluir Sphinx en un proyecto que no se haya pensado para Sphinx. Claro que es posible, pero implica un mayor esfuerzo y tiempo de desarrollo.

Lo último es un pequeño detalles de los deltas: aunque actualizan la información, estos no eliminan información. Si un restaurante eliminó una de sus locaciones, está persistirá incluso después de la indexación con el delta, ya que el delta solo actualiza los nuevos datos provenientes del repositorio. Para eliminar estos residuos en los índices se hace necesario re-indexar por completo los índices diariamente.

¿Servirá Sphinx para mi proyecto web?

A pesar de las complicaciones que puede ofrecer, la ganancia que se obtiene a partir del uso de Sphinx en las búsquedas es dificil de ignorar. Además ya existen herramientas que permiten integrar mas fácilmente Sphinx con los sistemas web más comunes, como Drupal, WordPress e incluso API’s para lenguajes web como PHP.

Si en su proyecto web las búsquedas juegan un papel fundamental, si necesita brindar opciones de geolocalización o si va a incluir grandes volúmenes de datos, definitivamente Sphinx es una opción. Si su proyecto es más sencillo, tenga la seguridad de que un buen diseño, una programación eficiente y consultas bien optimizadas siempre darán buenos réditos.

De cualquier forma, ahora ya conoce Sphinx y tiene una herramienta más para competir a la velocidad del mercado actual.

Etiquetas: , , , , , ,