Post del autor

Generar sitemaps de millones de páginas

Escrito en Tutoriales

Los creadores de sortea2 siempre hemos tenido que tratar con el mismo problema en todas las webs que hemos tenido que realizar: generar los sitemaps.

En qué consiste un sitemap

Un sitemap no es más que un fichero XML en el que ponemos todas las URLs que tiene nuestro sitio web con el fin de que Google, Bing o el robot que quiera lo lea y sea capaz de indexar todo el sitio mucho más fácilmente de lo que lo haría normalmente.

A estas URLs les podemos dar además una prioridad, que es un número decimal de entre 0 y 1 que puede servirle como dato orientativo para el motor de búsqueda. No tiene lógica ninguna darle prioridad 1 a todas las páginas con la idea de que nuestras páginas indexen mejor porque el sistema no va así. Está hecho para diferenciar importancias entre diversas secciones del sitio web y cosas así. Luego será el propio motor de búsqueda el que determine qué vale la pena más o menos.

Un sitemap en su forma más simple es algo como esto:

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.google.com/schemas/sitemap/0.84">
<url>
  <loc>http://www.sortea2.com</loc>
  <priority>0.6</priority>
</url>
</urlset>

 

Dentro de cada <url> meteremos en <loc> el link en sí y luego su prioridad. Dentro del urlset irán todas las URLs.

Un sitemap así será fácil de generar con cualquier lenguaje que queramos (PHP, python, perl, etc.), puesto que simplemente es meter en un bucle todas las URLs e ir poniéndolas en ese formato XML.

El problema viene en que existe un límite de URLs que puede tener un sitemap. El límite está en 50.000 páginas y 10MB como máximo.

En este caso habrá que dividir los sitemaps en el máximo e ir separándolos mediante Sitemap indexs. Esto no es más que otro XML con la ruta de cada sitemap al que habrá que acceder.

Un Sitemap Index tiene la siguiente estructura:

<?xml version="1.0" encoding="UTF-8"?>
<sitemapindex xmlns="http://www.google.com/schemas/sitemap/0.84">
<sitemap>
<loc>http://www.sortea2.com/sitemap/sitemap1.xml</loc>
</sitemap>
<sitemap>
<loc>http://www.sortea2.com/sitemap/sitemap2.xml</loc>
</sitemap>
</sitemapindex>

 

Hasta aquí la breve explicación de en qué consisten los sitemaps.

Proceso habitual para generarlos

Habitualmente los generaremos mediante una tarea programada a una hora a la que veamos que nuestro tráfico baja considerablemente y ésta se encargará de escribir todo lo que sea necesario.

En PHP tenemos el problema de que por defecto los servidores suelen capar el máximo tiempo de ejecución del script a 30, 60 o 90 segundos, y si vamos a generar una cantidad grande de sitemaps implicando consultas de MySQL complicadas lo más normal es que nos quedemos cortos.

Para este problema habría que poner al principio del todo del script: set_time_limit(0); para que se le permita tardar todo lo que necesite. Aún así habrán servidores que tendrán fijado un tiempo máximo y no dejará de ninguna de las maneras cambiarlo.

Otra opción bastante viable puede ser usar Python o Perl; lenguajes mucho más veloces que PHP y que suelen venir instalados en hostings compartidos.

Primero se generarían los distintos sitemaps, cortando cada archivo cuando se llegue al límite y al final del todo se creará un índice de sitemaps conteniendo las URLs de todos los que acabamos de generar.

La manera de implementarlo ya variará dependiendo de cómo lo vayamos a hacer.

Consejos para generar miles de ellos

Si tienes que enfrentarte a la generación de una cantidad enorme de sitemaps, te convendrá tener en cuenta algunos consejos:

  • Escribe de golpe en los archivos con fwrite() pero sin usar flush(). De esta manera solo utilizaremos la memoria indispensable en cada momento.
  • Utiliza tablas temporales de MySQL cuando haya que hacer consultas complejas: una buena práctica que podemos necesitar es crear una tabla temporal. Si la consulta que va a generar el sitemap implica a muchas tablas, agrupaciones, eliminación de duplicados, etc. te puede convenir crear una tabla temporal que contenga simplemente los ids de los elementos a los que acceder de tal manera que luego las consultas que se hagan sean directas.

    Con este sistema el mal trago solo pasará una vez al crear la tabla temporal y aún así se ejecutará mucho más rápido que la consulta en sí porque no necesita generar ningún cursor. Las consultas directas sobre esa tabla serán tan simples que serán inmediatas.

    Lo óptimo es borrar la tabla temporal tan pronto como se pueda.

  • Parte en trozos la consulta que vas a tener que hacer: no es recomendable coger todos los datos de golpe e introducirlos en un cursor. Si tienes un millón de registros esa operación es inviable, porque tendrá que gastar una cantidad brutal de memoria (dependiendo de los datos) que realmente no va a valer para nada, porque cada vez solo vamos a leer un dato. Además, si tenemos que realizar esta consulta inmensa junto con algún tipo de ORDER BY, DISTINCT o algo así, es muy probable que agotemos la memoria interna de MySQL y nos dé un error interno grave de Incorrect key file for table ‘/tmp/#sql_7cd7_0.MYI’; try to repair it que quiere decir que no se ha podido generar la tabla temporal necesaria.

    La manera de partir en cachos el resultado de la consulta es meterla dentro de un while() que vaya cogiendo trozos del tamaño que veamos (50.000, 100.000 o lo que sea) con un LIMIT y que pare cuando ya no haya más datos.

    Así se irán escribiendo las URLs usando no demasiada memoria y se leerán de inmediato gracias a la tabla temporal.

  • Escribe todos los sitemaps olvidando saltos de línea y tabulaciones: Google no te va a premiar por escribir tus sitemaps completamente bien estructurados y legibles. Escríbelo todo en una sola línea continua con el menor número de espacios posible y así ahorrarás espacio en disco.

    Estamos hablando de miles de sitemaps, por lo que la diferencia si puede ser notable. En pocos sitemaps esto sería absurdo e innecesario.

  • Se pueden comprimir usando GZIP: si lo consideras oportuno puedes comprimir tus sitemaps usando GZIP, de esta manera ocuparán mucho menos y ahorrarás ancho de banda.

    Es de libre elección hacerlo o no. Por un lado tiene la ventaja de que ahorra disco duro y ancho de banda pero por otro tiene la desventaja de que te costará muchísimo más el generarlos porque la compresión tardará también lo suyo.

    Se pueden generar todos normalmente y luego lanzar un proceso que vaya comprimiendo uno a uno. No habría problema ninguno y serían perfectamente válidos.


Etiquetas: , ,
Escrito por .

Zonas horarias con PHP

Escrito en PHP, Tutoriales

Hace un par de años publicamos un artículo titulado Zonas horarias y PHP en el que explicábamos los entresijos del sistema que habíamos empleado para la programación de los sorteos que se realicen fuera de España.

En ese artículo se narra un mecanismo que proporciona el lenguaje de PHP para realizar los cambios de horario de forma eficaz y abarcando todas las opciones posibles. Sin embargo recientemente tuvimos que revisar todo el sistema porque había muchas quejas de usuarios que tenían problemas con sus sorteos programados que se realizaban a horas diferentes a las que ellos habían definido.

Al analizar la situación más en detalle pudimos ver que hay bastantes problemas en el sistema que indicamos en el artículo «Zonas horarias y PHP» que no tienen fácil solución.

Por un lado está el problema de que todo el empaquetado de zonas horarias y fechas de cambio está dentro de la instalación de PHP. Si un gobierno decide cambiar esa fecha, como ha sucedido recientemente con Argentina, la información de cambio está obsoleta y es sencillamente equivocada. PHP soluciona el problema creando una modificación a sus programas pero esa modificación se incluye en la versión más moderna de todas.

Ahora bien, uno no puede actualizarse la versión de PHP cada día. Sobre todo si se tiene la página en un hosting compartido, la actualización de versión la dictan los proveedores del servicio, uno no puede realizar dicho cambio. En nuestro caso, tenemos que vivir con una versión desfasada que tiene errores en las conversiones de hora para sorteos de Argentina y hemos tenido que implementar soluciones alternativas un poco artificiales. Oficialmente con la versión de PHP instalada, cuando queremos saber la hora actual de Buenos Aires no da una que está equivocada en dos horas.

Hace unas semanas se produjo el cambio de hora y también pudimos ver cómo horas antes de dicho cambio cuando se consultaba la hora estándar del sistema (mediante time(), tras establecer la zona horaria), la UTC (antigua de Greenwich) el sistema estaba dando un dato erróneo en una hora.

En conclusión, dar una actualización a la opinión que expresábamos hace dos años. No se puede establecer un sistema de cambios horarios que sea eficaz al 100% mediante PHP. La única opción es actualizar las versiones casi de continuo o crear un sistema artesanal donde ir indicando las diferencias horarias. El problema no es exclusivo de PHP y la culpa no es de ellos sino de muchos gobiernos que arbitrariamente modifican los políticas sobre diferencias horarias, no se ciñen a lo previsto años antes sino que realizan muchos cambios con efecto inmediato. En algunos casos también hay medidas de tipo político, como algunas regiones que pretenden distinguirse del resto del país con un cambio de zona horaria. Estos cambios no se reflejan automáticamente en las funciones de PHP.


Escrito por .

Coincidencias en la lotería

Escrito en Loterias

El pasado sábado 16 de octubre de 2010 se produjo una asombrosa coincidencia en la lotería de Israel, similar a la lotería primitiva española: salieron los mismos números que habían resultado premiados el día 21 de septiembre del mismo año, apenas un par de semanas antes. Para mayor coincidencia los números habían salido en aquella ocasión justo en el orden inverso a esta nueva oportunidad.

Estadísticamente es un suceso de una improbabilidad enorme, aunque se descarta cualquier tipo de fraude al respecto, no deja de ser una tremenda casualidad. Los números fatídicos fueron: 36, 33, 32, 26, 14, 13.

Hace ahora poco más de un año que en la lotería de Bulgaria sucedió algo parecido: allí incluso se repitieron los resultados en dos sorteos consecutivos:
4, 15, 23, 24, 35 y 42 fueron los números que se repitieron en aquella otra ocasión el seis y el diez de septiembre.

Cabe destacar que ante estas coincidencias los premiados en segunda convocatoria fueron muy dispares. En Bulgaria hubo hasta 18 personas que acertaron la combinación (en la primera ocurrencia no hubo ganadores). En este nuevo caso de Israel sólo ha habido tres ganadores del sorteo.


Escrito por .

Sortear grupos online con Sortea2

Escrito en Novedades

En sortea2 siempre tratamos de comprender a nuestros usuarios y ofrecerles lo que creemos que necesitan, es por ello que hemos desarrollado la opción en los sorteos avanzados de sorteo de grupos, ideal para cualquier deporte e incluso útil para otros fines simplemente para agrupar gente de cuatro en cuatro.

sorteo_gruposs_prueba

Está opción estará disponible solamente desde los sorteos avanzados porque creemos que sorteos simples se debe mantener como una herramienta fiel a su propio nombre: simple, debe tener el mínimo número de opciones posible.

sortear_grupos_sortea2

Simplemente seleccionamos la opción de sorteo de grupos y ya obtendremos la lista de jugadores encuadrada en grupos de cuatro. Si el número de jugadores no es múltiplo de 4 entonces habrá un grupo que quedará cojo aunque es así también en el Mundo Real, por lo que no se consideraría un error.

Decir que estos sorteos también podrán ser programados y se podrá abrir la participación para que se vayan apuntando los participantes.

Enlace: http://www.sortea2.com/sorteos-avanzados


Etiquetas: , ,
Escrito por .

Ganador Sueldo Nescafé 2010

Escrito en Sorteos

Este miércoles ya se dieron a conocer los resultados de uno de los sorteos anuales más importantes de este país, el Sueldo Nescafé.

Este año el ganador ha sido Joaquín Martinez Herrera y según publica Nescafé en su página de facebook, es de Jerez de la Frontera.

Al parecer Ángel Llácer fue en persona a Jerez de la Frontera a darle la noticia directamente.

Seguid animándoos a participar para la edición del año que viene.


Etiquetas: ,
Escrito por .