And finally the beta is out!

After some time of the alpha version, FileS3 beta is finally out. As you can see the site now have a new, simplest design, much faster than the others sites.

Probably you may be wondering why another file share system?, the answer is quite simple, I got tired of wait more than a  minute because I was not a premium user, or download slower over the time when download a bunch of things.

Another things that really really bother me is that if my connection goes down during a large download, I need to start again, and also, I cannot have parallel download.

So, I created FileS3, a simple share system, where every user is a premium user.

What is next:

  • Right now the Link live time is two hours, What I will do next is calculate the LLT (link live time) based on the file size.
  • MP3-embedding, if you upload an mp3 file, FileS3 will generate the HTML code for embedded an mp3 player in your blog.
  • Internationalization, because not all the people speak only English…
  • Desktop uploader: This will be a cool Python+Gtk2 (Of course will be Free Software) app that will help user to upload largest file and pause.

¿como mejorar el rendimiento de un sitio web?

En estos días, después de terminar la beta de mi nuevo sitio para compartir archivos FileS3, me puesto en teoría mis conocimientos sobre optimización de paginas webs (para mejor rendimiento, nada que ver con el SEO, esa es otra rama). Mi motivación para escribir este post es que hay varios sitios webs en el Paraguay con mucho trafico (o al menos eso dicen) , y todos ellos desoptimizados. Esta desoptimización es costosa para la empresa que gasta millones en hardware (supongo… no trabajo para ninguna) y en ancho de banda, y para el usuario ya que el tiempo de respuesta no es optimo.

Archivos estáticos (*.png, *.jpg, *.js, *.css, etc)

Aunque Apache es un gran servidor web, perfecto para todas las consultas dinámicas (mod_php, mod_*), consultas CGI, pero es demasiado costosa para procesar archivos estáticos, con esto no estoy diciendo que tener archivo estáticos con Apache este mal, solamente digo que si quieren ahorrar recursos para recibir mas visitantes se debe cambiar esto.

Para eso existen varios servidores “lightweight”, yo recomendaría NGinx (se lee engine x) pero hay varias alterativas, solo basta googlear un poco (también leí mucho sobre el http://www.lighttpd.net/).

Si se pregunta porque estos servidores “lightweight” son mejores que Apache para archivos estáticos, la respuesta es que estos servidores usan hilos (o métodos similares) para atender a varias consultas en simultaneo, ademas cuenta con una arquitectura mucho mas simple y pequeña, lo que se adecua a las necesitas de los archivos estáticos, ya que no necesitan nada mas que ser leídas del disco duro y ser enviada al cliente.

Otra cosa muy importante para ahorrar ancho de banda, es el cacheo en el cliente. Este cacheo es simplemente que el servidor le dice al browser (claro, a firefox casi siempre) que estos archivos estáticos no cambiaran en un tiempo dado (10 días, 20 días, 10 meses, etc), entonces el browser una vez que obtiene los archivos no vuelve a bajar el mismo archivo ya que sabe que ese archivo no va a cambiar, y tiene una copia del archivo en el disco. Para realizar esta configuracion con el NGinx pueden leer esta pagina, si usan otro servidor deben buscar como manipular el header “Expires”.

Seguramente se estarán preguntando, que pasaría si actualizamos algún archivo estático, bueno, el browser no se enteraría mientras que no se alcance el tiempo de validez del cache. Pero no se alarmen, existe una solución bastante simple, un poco de orden todo lo arregla.

Ya que nuestro contenido dinámico no se debe cachear (o se debe cachear por un tiempo mínimo como 10 min, 1h ,etc), y ya que el contenido dinámico incluye, es la que incluye a el contenido estático, nuestro problema esta resuelto!, simplemente tendremos que crear un sistema rudimentario de versionamiento. Ejemplo:

Esta es la manera como una pagina incluye a un elemento estático, un archivo css:
<link rel='stylesheet' href='/style.css' type='text/css' />

Con el versionamiento seria algo asi:
<link rel='stylesheet' href='/css/1/style.css' type='text/css' />

Entonces cuando cambiamos algo, simplemente tendremos que crear una
nueva carpeta y actualizar las referencias de la pagina hacia el elemento
estatico (si es una web en serio organizada no seria un problema).
<link rel='stylesheet' href='/css/2/style.css' type='text/css' />

Como ven, no es una solución complicada y así no tenemos excusas para utilizar el cacheo de archivos y así empezar a ahorrar un montón de ancho de banda.

Otro tip importante, para ahorrar ancho de banda es utilizar algún módulo del servidor que pueda comprimir los archivos antes de enviar (si el browser soporta). Aquí está un ejemplo de configuración para el NGinx que tiene activado la compression (gzip).

Consultas dinámicas. (*.php, cualquier otro)

Bases de datos…

En esta sección hay mucho para hablar, yo me voy a enfocar en lo mas conozco, y en lo que pienso es en donde mayor desoptimización hay, las bases de datos.

La base de datos es un mal necesario, digo mal, porque es bastante costosa, pero no podemos vivir sin ella, es costosa porque hay autenticación (casi siempre, excepto SQLite), comunicación por la red (casi todos), compilación del código SQL, ejecución del código y acceder al disco duro. Pero como dije antes, no podemos vivir sin el, entonces la solución es evitarlo cuando sea posible, para eso podemos cachear el resultado de una consulta con un TTL (time to live) apropiado. El medio de almacenamiento puede ser un archivo en el disco duro, aunque es costoso el acceso al disco duro hoy en día los sistemas operativos tienen en memoria RAM los archivos que son leídos frecuentemente. Cuando hay varios servidores webs, la mejor alternativa seria guardar el cache en un servidor de Memcached, así no se duplica el cache.

Para ayudar a todo que es cacheo, en mi opinión, se debería construir un Capa de abstracción entre el acceso a base de datos y la aplicación (similiar al PDO del PHP5) y ahí implementar todo lo que sea cache. Ahora mismo estoy escribiendo un lenguaje de modelado de datos y su generador de código. Su misión sera que genera las tablas y el código PHP (mas adelante python, java,etc) para acceder a la tablas sin escribir SQL (similar a www.metastorage.net) y ahí estará implementado cacheo de consultas a disco duro, memcached o cualquier otro medio. Más adelante estaré hablando mas sobre este proyecto, que espero que muy pronto este todo terminado.

Minimizando el tráfico.

Al igual que los archivos estáticos, los archivos dinámicos pueden ser cacheado y comprimidos. Claro que el TTL tiene que ser un tiempo razonable. Imagínense la página principal de un diario digital, esa página si tiene último momento, no cambiaría tan frecuentemente, cambiaría a cada 5 minutos o 10 minutos, entonces para que generar toda la página para cada visitante?. La solución sería (para los usuarios que no este logueados, si soporta logueo) cachear toda la página (en el disco duro) y comprimir así tenemos dos versiones del mismo cache, la comprimida y la descomprimida, porque comprimir “on the fly” es costosa, se pierde tiempo y valiosos ciclos de CPU. Para cada visitante enviamos el cache comprimido si soporta o el cache normal y también le enviamos el tiempo que falta para que el cache sea recreado (para un diario yo pondria 5 ~ 10 min). Y para los artículos que generalmente no cambian creo que un TTL adecuado es de 2 horas o algo así.

Hace algún tiempo escribí una clase que hace eso mismo, gCache.

APC.

APC (Alternative PHP Cache) es un excelente cache en RAM del bytecode del PHP (PHP no es interpretado desde la versión 4). Para demostrar la diferencia, hice una simple prueba con la pagina principal del  FileS3, cuya pagina esta bien optimizada ya que cuenta con un cache y en el momento de la prueba el cache existia, lo que significa que solo una par de lineas de códigos PHP fueron ejecutadas, ademas fue probada en el servidor para que no haya retardo de red.

Para la prueba utilice ApacheBench (ab -c 30 -t 30 http://local.files3.com/) simulando a 30 usuarios concurrentes que visitaban a http://local.files3.com/ por 30 seguntos.

This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright 2006 The Apache Software Foundation, http://www.apache.org/

Benchmarking local.files3.com (be patient)

Server Software:        Apache/2.2.8
Server Hostname:        local.files3.com
Server Port:            80

Document Path:          /
Document Length:        7232 bytes

Concurrency Level:      30
Time taken for tests:   30.8135 seconds
Complete requests:      3166
Failed requests:        0
Write errors:           0
Total transferred:      23656585 bytes
HTML transferred:       22918208 bytes
Requests per second:    105.50 [#/sec] (mean)
Time per request:       284.347 [ms] (mean)
Time per request:       9.478 [ms] (mean, across all concurrent requests)
Transfer rate:          769.86 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0  10.1      0     117
Processing:    19  281  75.0    282     675
Waiting:        1  248  75.2    252     653
Total:         20  282  74.0    283     675

Percentage of the requests served within a certain time (ms)
  50%    283
  66%    302
  75%    316
  80%    328
  90%    364
  95%    408
  98%    472
  99%    499
 100%    675 (longest request)

Como verán, con toda la optimización pudimos responder 3166 paginas. Ahora instale APC ( yum install php-pecl-apc.i386  -y), y la configuración  de facto, realice la misma prueba y aquí están los resultados.

This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright 2006 The Apache Software Foundation, http://www.apache.org/

Benchmarking local.files3.com (be patient)

Server Software:        Apache/2.2.8
Server Hostname:        local.files3.com
Server Port:            80

Document Path:          /
Document Length:        7244 bytes

Concurrency Level:      30
Time taken for tests:   30.1087 seconds
Complete requests:      7028
Failed requests:        0
Write errors:           0
Total transferred:      52570787 bytes
HTML transferred:       50932564 bytes
Requests per second:    234.26 [#/sec] (mean)
Time per request:       128.064 [ms] (mean)
Time per request:       4.269 [ms] (mean, across all concurrent requests)
Transfer rate:          1711.20 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   4.2      0      69
Processing:    39  126  23.1    123     300
Waiting:        1  123  22.7    120     300
Total:         39  127  22.9    123     300

Percentage of the requests served within a certain time (ms)
  50%    123
  66%    130
  75%    136
  80%    141
  90%    154
  95%    169
  98%    191
  99%    206
 100%    300 (longest request)

El resultado es asombroso, ahora pudimos servir 7028 paginas, con solamente haber instalado APC, si pasan un poco mas de tiempo tuneando, podríamos mejor mucho mas.

Tu experiencia!

Seria espectacular si ustedes comparten aqui sus metodos de optimizacion para ayudarnos entre todos, varias cabezas son mejores que una.

Saludos.

GeekSlides - Presentaciones con LaTeX

Despues de hacer algunas presentaciones, y cansado del Impress (el mouse no fue creado para mi), he decidido utilizar Latex para crear mis presentaciones, como una prueba, para ver que tal me va.

Basicamente en este post voy a describir, paso por paso lo que hice para tener hermosas presentaciones en pdf (código fuente), escribiendo un poco de codigo con LaTeX. Antes que nada utilize la guia escrita por Matt Welsh (Creating Presentations in PDFLaTeX), por cierto muy buena guia, excepto que no pude instarlas las fuentes con el script perl que esta en esa pagina.

  • Deben bajarse el textslides.tbz2.
  • Descomprimir ( tar xfvj textslides.tbz2 -C $HOME)
  • Editar el archivo de configuración de cuenta
    • echo “export TEXINPUTS=\$TEXINPUTS:~/.texslides/” >> ~/.bashrc
    • echo “export PATH=\$PATH:~/.texslides/” >> ~/.bashrc
  • Para instalar fuentes nuevas, hacer lo siguiente:
    • Copiar las fuentes en una carpeta dada (archivos *.ttf)
    • Luego ejecutar “addfont”
    • Si siguieron todos los pasos las fuentes estaran bien instaladas.
  • Luego para compilar el archivos Latex deben realizar lo siguiente:
    • pdflatex archivo.tex
    • ppower4 archivo.pdf carchivo.pdf
    • mv carchivo.pdf archivo.pdf

Básicamente crear presentaciones con LaTeX, es algo sencillo, y vale la pena si la presentación es simple, como imágenes de fondos, incluir imágenes, citar cosas. La cosa se va complicando (cosa que me pasó) cuando se requiere hacer cosas complejas, como resaltar código (escribí un pequeño script en python que con otro script bash hace eso, es algo grocero, pero funciona más o menos). Aún asi para presentaciones normales, lo mejor es utilizar LaTeX (claro con ViM), porque todo está en su lugar, no hay utilizar el mouse para alinear textos, ni nada.

Como me encanto el LaTeX (la idea de no depender del Impress me encanta), decidí comenzar un proyecto llamado GeekSlide, que básicamente será un generador de presentaciones (por ahora a HTML) basado en modelado de texto bastante sencillo (similar pero no igual al RST), que será modular, el “core” no generará ninguna presentación, solo parseará el texto y pasara esa información a un “render” (un plug-in) que será el encargado de generar la presentación.

Así será un típico archivo de gslides (ojo: no es gnu/slides, es GeekSlides).

% Esto es un comentario que será ignorado por el parseador
% Definir variables globales
% Estas variables serán pasadas al render, generalmente será

% útil para generar la primera página

title:
Introducción a GeekSlides.
author:
Cesar Rodas
email:
talks@cesar.la
% “—” Es el separador de páginas.


=Que es GeekSlides= % Típico Título (header 1)
% Llamamos a la función “gradient” definida en el “render”.
% Básicamente mostrará los items en un color claro, luego
% cambiarán de color en los siguientes slides.

{gradient}
* Generador de Presentaciones.
* Totalmente modular.
* Open source.

=Caracteristicas=
==Textos==
{font,¨arial”,”14px”}
* *Texto en negríta*
* _Texto en cursiva_
* Resalto de código.
{source,”foobar.php”,”grey”}

{center}
=¿Preguntas?=

Como se darán cuenta la sintaxis es mucho más amigable que el LaTeX, y es bastante útil (a no ser que necesiten realizar complejas formulas matemáticas). El proyecto ahora mismo es solo un prototipo que estoy armando, y creo que pronto estará disponible para que lo puedan utilizar, extender, o lo que quiera. El proyecto será publicado en PHPClasses, y la documentación estará aqui mismo.

PHPAJAX 3 - Write an AJAX app was never this easy

After some time of inactivity due personal activities (University, work, investigations, etc) I had large to-do list, basically rewrite and improve some of my classes, talking fast the Amazon S3 class and the PHPAJAX. Right now I am working on Rewrite the PHPAJAX and release its version 3 with major changes, and in the background I’m working on the PHP Pagerank (php-coding pagerank &), but ut will wait some time until the PHPAJAX is fully working.

As in previous versions, PHPAJAX aims to help developer to write AJAX app. without write javascript (or writing just a little of). In previous versions execute PHP functions directly from the browser (as most of AJAX libraries), with some little advantages, such as read data directly from the HTML objects, File upload, and others.

The new version of PHPAJAX will be completely rewritten from scratch, and it will not use anymore Prototype, it will have its own set of javascript code, optimized to what the PHPAJAX program does. The idea is produce the Javascript code on the fly (then in a near future js-cache the code). The code by default will be obfuscated and minimized.

Basically the PHPAJAX compatibility will be broken right now, later I’ll code a wrapper that will execute PHPAJAX 2 code.

Some features of the PHPAJAX 3 will be:

  • File Upload.
  • Better PHP-DOM functions, to manipulate HTML objects as if they were PHP objects.
  • Special Objects.
    • Drag and Drop (containers and objects)
    • Autocomplete fields.
  • PHP to JS API for write Javascript code using just PHP.
  • Easy to extends.

I have not an official release date, but I’m doing my best, I think it will be available in two weeks, you can keep an eye on my blog, I promise that I will disclose the repository URL soon.

BTW, you can take a look on Fossil SCM, because I’m using it for this project.

Happy hacking, have a nice weekend!

Europe, DNSSEC and more! (Powered by ISOC)

After a great week in Amsterdam (pictures?) in a wonderful ISOC’s workshop at the RIPE.net, I learnt many useful things, specially about the weakness of the DNS and the benefits about the DNSSEC. Also I had a brief overview about the network monitoring.

The greatest part was that I met the administrator of the l.root-servers.net (If you don’t know what is the root-servers.net read this) and he gave us useful tricks of how to manage a huge network (just figure out the hard work of a root server).

Also I met people from other NICs, it was a great experiences.

From now on, I’ll start to write in English and Spanish (depending of my mood) about these topics, and also I’ll write some scripts to manage the DNSSEC, also I’ll write about the DNS poisoning and other attacks (just to show how weak is the DNS), so if you’re interested just keep watching my site.