• Publicidad

Performance Perl vs MySQL en búsquedas

¿Apenas comienzas con Perl? En este foro podrás encontrar y hacer preguntas básicas de Perl con respuestas aptas a tu nivel.

Performance Perl vs MySQL en búsquedas

Notapor Fernando » 2011-05-18 07:25 @350

¿Qué tal, gente? Esta vez los molesto para que me den un consejo.

Tengo el siguiente problema: a partir de un dominio/URL que me pasan (por web service, por parámetro de un script, etc, no importa) debo decir a qué categoría pertenece dicho dominio/URL.

Para esto cuento con varios archivos dispuestos en directorios (nombre de categorías) de la siguiente manera:

Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
[...]
foros/dominios
foros/urls
hacking/dominios
hacking/urls
[...]
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


El archivo "foros/dominios", por ejemplo, cuenta con la siguiente información:
Sintáxis: [ Descargar ] [ Ocultar ]
  1. [...] 
  2. blog.cnexp.net 
  3. blog.codigophp.com 
  4. blog.columbiarecords.com 
  5. blog.com 
  6. blog.com.pt 
  7. blog.concept-i.dk 
  8. blog.converter.cz 
  9. blog.craftzine.com 
  10. blog.csdn.net 
  11. blog.cuatro.com 
  12. blog.cynx.de 
  13. blog.czhannes.com 
  14. blog.damonledet.com 
  15. [...] 



Entonces por ejemplo, si el dominio/URL se encuentra dentro de alguno de los archivos (dominio, URL) del directorio "foros", la categoría sería "foros". Y así.

En total estamos hablando de unas 20-30 categorías, cada una con sus archivos correspondientes, que suman unas 3 millones de líneas, aprox.

Mi consulta es la siguiente: ¿este tipo de búsquedas (estamos hablando, en cantidad, de unas 100 por minuto tal vez) conviene hacerlas a partir de archivos, o me conviene pasar todo a una base de datos MySQL y buscar desde allí?

¡¡Desde ya muchas gracias!!
Saludos./

Fernando.-
Fernando
Perlero nuevo
Perlero nuevo
 
Mensajes: 15
Registrado: 2011-04-16 08:10 @382

Publicidad

Re: Performance Perl vs MySQL en búsquedas

Notapor explorer » 2011-05-18 09:27 @436

Estoy seguro que, almacenando la información en un hash, la determinación de la categoría es mucho más rápida que haciendo consultas al motor de la base de datos.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Performance Perl vs MySQL en búsquedas

Notapor Fernando » 2011-05-18 09:56 @455

Antes que nada ¡muchas gracias por la respuesta!

Perfecto, acepto tu consejo y almaceno la info en un hash.

Ahora bien, ¿me conviene almacenar todo el listado de dominios/URL de todas las categorías en un solo hash, o armar un hash por cada categoría?

¡Muchas gracias!

¡Saludos!
Fernando
Perlero nuevo
Perlero nuevo
 
Mensajes: 15
Registrado: 2011-04-16 08:10 @382

Re: Performance Perl vs MySQL en búsquedas

Notapor explorer » 2011-05-18 10:16 @470

Si cada URL corresponde a una sola categoría, se pueden meter los 3 millones de URL en un solo hash, cuyas claves sean las URL, y el valor, la categoría (que es lo que queremos obtener, claro).

Otra cosa es cuándo leerlas y cuántas consultas tenemos que resolver.

Si son muchas consultas, pero espaciadas en el tiempo (dices que vienen desde un servicio web), entonces lo más efectivo sería dejar el proceso en segundo plano, o persistente, algo así como PPerl, SpeedCGI o FastCGI, para que el programa no tenga que leer los 3 millones de líneas en cada invocación (bueno, tampoco es tanta información, todo depende de las prestaciones que quieras obtener).
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Performance Perl vs MySQL en búsquedas

Notapor Fernando » 2011-05-18 10:50 @493

Hola explorer.

Sí, son varias consultas por segundo, y cada URL pertenece a UNA categoría solamente.

Y en cuanto al uso de hashes, ¿lo que vos me sugerís es un hash de arrays? Es decir, algo como esto en salida:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. $dominios = {
  2.           'foros' => [
  3.                       'url1',
  4.                       'url2',
  5.                       'url3'
  6.                     ],
  7.           'hacking' => [
  8.                       'url1',
  9.                       'url2',
  10.                       'url3'
  11.                         ],
  12.           '[...]' => [
  13.                          '[...]'
  14.                      ]
  15.         };
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4


¿Cómo realizaría luego la búsqueda ahí dentro?

¡Muchas gracias! ¡Saludos!
Fernando
Perlero nuevo
Perlero nuevo
 
Mensajes: 15
Registrado: 2011-04-16 08:10 @382

Re: Performance Perl vs MySQL en búsquedas

Notapor panterozo » 2011-05-18 11:17 @512

Hola Fernando:

Yo plantearía distinto el hash, y creo que es lo que te decía explorer...

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. my %dominios;
  2. $dominios{'foros'} = [
  3.                'url1',
  4.                'url2',
  5.                'url3'
  6.               ];
  7. $dominios{'hacking'} = [
  8.                'url1',
  9.                'url2',
  10.                'url3'
  11.               ];
  12. $dominios{'[...]'} = [
  13.                'url1',
  14.                'url2',
  15.                'url3'
  16.               ];
  17.  
  18.  
  19. foreach my $k (sort keys %dominios){
  20.         print $k;
  21.         foreach my $url (@{$dominios{$k}}){
  22.                 print "\n--> ".$url;
  23.                 }
  24.         print "\n";
  25.         }
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


¡¡¡Saludos!!!
Última edición por explorer el 2011-05-18 11:48 @533, editado 1 vez en total
Razón: Signos de admiración
panterozo
Perlero nuevo
Perlero nuevo
 
Mensajes: 160
Registrado: 2010-01-26 08:36 @400

Re: Performance Perl vs MySQL en búsquedas

Notapor ileiva » 2011-05-18 11:55 @538

Si cada URL pertenece sólo a una categoría y quieres privilegiar el tiempo de respuesta entonces es más eficiente almacenar cada URL como clave en el hash y su valor sería la categoría a la que pertenece. Creo que eso es lo que quiso decir explorer.

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. my %URLS = {
  2.         'url1' => 'categoriadeurl1',
  3.         'url2' => 'categoriadeurl2'
  4. };
  5.  
  6. print "La categoria de url1 es ".$URLS{'url1'}."\n";
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4



Saludos.
Última edición por ileiva el 2011-05-18 11:58 @540, editado 2 veces en total
Avatar de Usuario
ileiva
Perlero nuevo
Perlero nuevo
 
Mensajes: 30
Registrado: 2011-04-23 03:25 @184
Ubicación: Santiago, Chile

Re: Performance Perl vs MySQL en búsquedas

Notapor explorer » 2011-05-18 11:55 @538

No, yo solo hablaba de un hash:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
my %categorias = (
    'blog.cnexp.net'           => 'foros/dominios',
    'blog.codigophp.com'       => 'foros/dominios',
    'blog.columbiarecords.com' => 'foros/dominios',
    'blog.com'                 => 'foros/dominios',
    'blog.com.pt'              => 'foros/dominios',
    'blog.concept-i.dk'        => 'foros/dominios',
);

print $categoria{'blog.com'}, "\n";
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


El verdadero problema es aumentar la eficiencia del programa, por cada petición.

Una forma de resolverlo sería incluir esta información en el propio programa, bien de forma directa como he puesto yo en las líneas anteriores, o en la sección __DATA__. Naturalmente esto es válido si las 3 millones de líneas no cambian frecuentemente.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Performance Perl vs MySQL en búsquedas

Notapor Fernando » 2011-05-19 07:18 @346

Hola gente, ¡muchas gracias por las respuestas!

Este script lo voy a armar como servicio web, y va a recibir varias consultas por segundo. Como prueba hice lo siguiente:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl -w
  2. use IO::File;
  3. use strict;
  4. use warnings;
  5.  
  6. my %hash_table;
  7.  
  8. open(CHAT, "<bl/dominios")
  9.   or die "Error abriendo el archivo: $!";
  10. while (<CHAT>) {
  11.   chomp;
  12.   $hash_table{$_} = 'chat';
  13. }
  14. close CHAT;
  15.  
  16. open(FORO, "<bl/foro")
  17.   or die "Couldn't open file for processing: $!";
  18. while (<FORO>) {
  19.   chomp;
  20.   $hash_table{$_} = 'foros';
  21. }
  22. close FORO;
  23.  
  24. print "chat.com pertenece a la categoria: " .$hash_table{'chat.com'}, "\n";
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Parece funcionar bien con 780.000 registros. ¿Algo así más o menos me aconsejaban?

Voy a dejar el servicio web corriendo de fondo, como bien dijo explorer, utilizando pperl, por ejemplo. Ahora bien, si tengo que agregar dominios nuevos al hash (una vez por semana o una vez cada 15 días):
¿tengo que reiniciar el servicio web y recargar todos los dominios? ¿o existe alguna forma de hacerlo en tiempo de ejecución?

¡Muchas gracias a todos!
Fernando
Perlero nuevo
Perlero nuevo
 
Mensajes: 15
Registrado: 2011-04-16 08:10 @382

Re: Performance Perl vs MySQL en búsquedas

Notapor explorer » 2011-05-19 09:18 @429

Se me ocurre dividir el problema en partes...

Primero, un programa que vigile los cambios en los directorios donde están los ficheros. Se puede usar un cron, por ejemplo, que mire a ver si hay cambios. O usar el propio sistema operativo para que te informe de que hay un cambio en el árbol de ficheros (en Windows y Linux se puede hacer sin muchos problemas).

Desde Perl, se puede realizar con módulos como Filesys::Notify::Simple (para Linux y MacOS X) y Win32::FileNotify (para Windows).

Entonces, este programa queda esperando por los cambios. En caso de que ocurran, se lee todos los ficheros de todos los directorios y crea un nuevo fichero con todos ellos reunidos, con solo dos columnas (dominio/URL y categoría).

Segundo, el programa que hace de servidor, al arrancar, lee el fichero y lo pasa a un hash, y se queda en un bucle esperando por las peticiones externas (si dices que tiene que ser un servicio web, se podría hacer con algún módulo tipo HTTP::Server, y con fork() para responder a varios al mismo tiempo, etc). Antes de servir una petición, puede mirar a ver si el fichero ha cambiado (con el operador -M, por ejemplo). Si ha cambiado, reinicia el proceso de carga del fichero. Y luego sirve la petición.

Bueno, esto es una idea, pero seguro que hay formas mejores.

Con pperl, hay un problema: está sin actualizar desde el 2004, por lo que ya no es compatible con los Perl modernos.

Lo recomendado, entonces, es usar FCGI (Fast CGI). Con el módulo CGI::Fast se puede crear, fácilmente, un proceso CGI que queda persistente y puede responder a la petición web, de forma rápida.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Siguiente

Volver a Básico

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 43 invitados

cron