Alfonso Jiménez

Keep calm and carry on

Noviembre 5, 2012 at 1:42pm

comentarios


Backend dinámico en Varnish

Llevamos unos meses usando Varnish Cache como frontend para nuestras aplicaciones. El rendimiento está siendo fantástico, liberando al backend de mucho workload. Como backend, usamos un cluster de Apache con autoscaling en Amazon EC2. Para enroutar peticiones al cluster usamos ELB (Elastic Load Balancing), que ofrece un endpoint con IP dinámica. Uno de los problemas que encontramos al montar la infraestructura fue al definir la configuración del backend en Varnish.

¿Por qué usar ELB?

Antes que nada, preguntémonos porqué queremos usar ELB con IP dinámica en lugar de nuestro propio load balancer. Si estuviésemos usando la segunda opción, la capacidad máxima de nuestra aplicación estaría limitada por la capacidad del tráfico de red entrante de nuestro frontend load balancer, sin importar la cantidad de instancias que tengamos detrás. De esta manera, al disponer de un solo punto de entrada nos encontramos con un bottle neck.

Usando ELB nos aprovechamos de la ventaja de poder usar más de una conexión de red de entrada, ya que según el tráfico existente Amazon usará un load balancer u otro.

El problema de Varnish con backend dinámico

El problema al configurar un backend dinámico en Varnish reside en que no resuelve un registro CNAME para cada petición. Es decir, en la primera petición Varnish resuelve el host y cachea la dirección IP para las peticiones posteriores. En cuanto la IP cambie el backend dejará de estar disponible.

La solución que hemos encontrado es agrupar las instancias de backend del cluster autoscaling en un director. Al ser dinámico, tenemos que autogenerarlo cada vez que una instancia se cree o se destruya. Para ello he escrito un pequeño script en ruby que nos genera el director con las instancias pertenecientes a un grupo de autoscaling.

Podéis conseguir el script completo en github. Por defecto el script genera los nodos con las IPs privadas de las instancias, así que habría que permitir en el firewall acceder a las máquinas de Varnish a esas instancias. Aún así podéis cambiar esas IPs por las públicas, además de la lógica de arbitrariedad y otras bondades que ofrece Varnish como el healthcheck polling.

Si deseamos eliminar el bottleneck de entrada que comentábamos antes, podemos usar ELB delante de las máquinas que tengamos con Varnish.

Marzo 4, 2012 at 10:07pm

comentarios


Instalar Android 4.0 ICS en ExoPC

Ya han sido varias las personas que me han preguntado cómo instalar Android 4.0 Ice Cream Sandwich en una ExoPC Slate. El procesador que la tablet posee es un Intel Atom Pineview-M N450, perteneciente a la segunda generación de cores de Intel Atom (45 nm), que soporta un conjunto de instrucciones x86 (también la extensión de 64 bits). Existe un proyecto open source llamado Android x86 que consiste en portar este sistema operativo a plataformas x86. Desde la propia web del proyecto podemos conseguir imágenes ya compiladas. Para el caso de la ExoPC, tendremos que descargar android-x86-4.0-RC1-tegav2.iso: http://code.google.com/p/android-x86/downloads/list

Una vez que tengamos la imagen, crearemos un dispositivo de arranque usando una memoria flash USB. Para ello, podemos crear el bootloader usando la utilidad unetbootin.

Para la instalación necesitaremos un teclado USB, ya que no se cargarán los drivers de la pantalla multitouch. Para ejecutar el bootloader es necesario tener la memoria USB como prioridad de arranque.

El proceso de instalación tiene una duración de unos 5 minutos aproximadamente creando una partición nueva en el disco. Además, el instalador te ofrece la posibilidad de instalar GRUB, para poder seleccionar durante el arranque la versión/kernel de Android que desees usar. Por otro lado, también podrás crear una fake SD card para almacenar tus datos.

Más información | Android x86

Enero 3, 2012 at 11:12pm

comentarios


No bra, no panties

Diciembre 29, 2011 at 2:59pm

comentarios


Memoization en Ruby

Un ejemplo práctico muy usado cuando se intenta enseñar recursividad es una función que calcule la secuencia de Fibonacci. Una solución trivial en Ruby podría ser la siguiente:

def fib(n)
  n < 2 ? n : fib(n-1) + fib(n-2)
end

Las primeras iteraciones de la secuencia se computan con una profundidad reducida. Por ejemplo fib(6) = 8, fib(7) = 13 o fib(8) = 21. Ejecutando el anterior código en mi máquina, el problema de rendimiento aparece cuando la entrada alcanza valores superiores a 40. Cómo se puede observar, la complejidad del algoritmo es del orden φn. Por ejemplo, para calcular fib(50) es necesario realizar 20.365.011.073 sumas.

Matemáticamente hablando, una función bien definida siempre devuelve un único valor para una determinada entrada. Es decir, un simple mapeo de elementos. Volviendo a la función anterior, sabemos que fib(8) siempre devolverá 21 independientemente del número de veces que ejecutemos la llamada. Un ejemplo de función matemáticamente mal definida sería rand(n), donde podríamos obtener un resultado diferente en varias llamadas con el mismo valor de entrada.

Existe una técnica que permite acelerar el rendimiento de funciones bien definidas llamada memoization. Básicamente consiste en cachear y reutilizar cálculos ya efectuados, ya que sabemos que la función para un valor de entrada n siempre devolverá el mismo resultado. Refactorizando la función fib(n), obtendríamos lo siguiente:

@series = [0,1]
def fib(n)
@series[n] ||= fib(n-1) + fib(n-2) end

Esta nueva versión almacena los resultados de las llamadas anteriores en un array (@series), reduciendo drásticamente el número de cálculos. De este modo podemos calcular fib(50) = 12586269025 de forma inmediata.

Además, en Ruby existe un gema muy útil llamada <a href=”http://rubygems.org/gems/memoize”>memoize</a>, que permite acelerar funciones bien definidas de una manera sencilla. El primer trozo de código quedaría de la siguiente manera:

require 'rubygems'
require 'memoize'

include Memoize

def fib(n)
n < 2 ? n : fib(n-1) + fib(n-2) end

memoize(:fib)

Para futuras llamadas a fib(n), la gema se encargará de cachear los resultados y aumentará el rendimiento de la función.

Fuente | Wikipedia
Fuente | Ruby best practises

Diciembre 8, 2011 at 5:50pm

comentarios


La importancia del foco y ser constante

A menudo comenzamos proyectos en nuestra vida, tanto personales como profesionales, tanto por placer, por vitalidad o por ánimo de lucro. A priori es sencillo empezar algo, pero menos fácil es mantenerlo y aún más complicado es acabarlo*.

Evitar procrastinación

La procrastinación es la mayor traba para el abandono de proyectos. El aplazamiento eterno, el dejar las cosas para mañana cuando las podemos hacer hoy. Falta de organización, distracciones, nacimiento de otras inquietudes o simplemente desilusión son los factores más comunes que nos lleva a ello. Por suerte o desgracia, nuestro tiempo es limitado y la frustración puede apoderarse de nosotros. En muchas ocasiones la principal razón es un mal planteamiento inicial.

Antes de comenzar algo, piensa si realmente quieres hacerlo

Y es que la raíz de la procrastinación surge antes de comenzar algo. Imagina la satisfacción de hacer ese proyecto que tienes en mente y formúlate una serie de preguntas a ti mismo. Aprendizaje, realización como persona, dinero, reconocimiento. ¿Qué te aportará? ¿Serás más feliz? ¿De verdad quieres hacerlo? ¿No hay otra cosa que prefieras hacer?

Leer más

Noviembre 28, 2011 at 6:21pm

comentarios


Volver a escribir

Ya hacía tiempo que no escribía, al menos en público. A pesar de que este humilde blog lleva online desde 2004, apenas he escrito una decena de posts en los últimos 2 años. Se me hace raro responder a la pregunta de ¿tienes un blog?. No voy a entrar en la discusión de si los blogs están muertos o no, de si la blogosfera en realidad existió o de si esto ya no es lo que era. Si no he publicado casi nada últimamente habré tenido mis motivos.

No acuso directamente a la falta de motivación, ni a la escasez de temas de los que hablar (siempre hay algo interesante que contar), ni siquiera al limitado tiempo libre que dispongo. Tal vez culpo a la evolución de la manera de comunicarse digitalmente, que como en otros ámbitos, es inevitable. Siempre he aplaudido la progresión y nunca he temido a los cambios. Por esa razón, nunca digo que los blogs hayan muerto, sino que los medios digitales han evolucionado y las personas con ellos. Años atrás si encontraba algo interesante que contar, lo analizaba en mi blog personal, la gente comentaba y enlazaba mis contenidos, se creaba una conversación. Hoy en día cuando encuentro algo interesante comparto el enlace con mis seguidores en Twitter, éstos vuelven a compartirlo con sus propios seguidores y así sucesivamente. Se ha perdido espíritu crítico, opinión y profundidad sobre los temas a tratar, pero se ha ganado difusión e inmediatez en la propagación de contenidos. Ahora el flujo de información que una persona puede consumir en un día es mucho mayor que en años atrás. Los usuarios cada vez generan menos contenidos, pero consumen más, dejando a los medios profesionales ese rol de productores.

Leer más

Octubre 30, 2010 at 12:00am

comentarios


fcron and non interactive apt-get install

This is a very short post, but it might be useful for someone with the same problem. I was trying to install fcron on a remote machine via an automated script, but apt-get install couldn’t finish because a dialog using whiptail came up. It wasn’t the common prompt asking yes or no, which can be ignored by the -y option.

Fortunately, there’s a smart workaround to get rid of these prompts:

DEBIAN_FRONTEND=noninteractive apt-get install -q -y fcron

Basically we set the type of user interface used for the installer to noninteractive mode before installing the package. You can always reset DEBIAN_FRONTEND to its default value.

Septiembre 7, 2010 at 8:29pm

comentarios


Mourinho y la teoría del torneo

Lo importante no es ganar sino participar, es el consuelo para perdedores por excelencia. 27 de Abril de 2010, Camp Nou. El Inter de Milán contra todo pronóstico elimina al FC Barcelona en las semifinales de la Champions League. José Mourinho, técnico del Inter por aquel entonces y émulo de Nereo Rocco, empleó un sistema táctico muy defensivo que noqueó todas las opciones de remontada de los azulgranas. Dicho sistema, popularmente conocido como catenaccio y que prolifera en las formaciones de muchos equipos italianos, fue duramente criticado por los aficionados del Barça tras la eliminatoria. Recibió todo tipo de calificaciones: destructivo, feo, injusto, inmoral, atentatorio de los derechos más sagrados de la humanidad … pero lo que nadie insinuó es que la estrategia desplegada por el once del jacarandoso Mourinho era ilegal. A pesar de ser la antítesis del juego del Barça, no podemos discutir la validez ni la legimitidad de la victoria del Inter. Y es que esa noche hicieron lo que tenían que hacer, eliminar al equipo rival. Para eso es lo que les pagan.

Leer más

Julio 30, 2010 at 8:33pm

comentarios


5 tips for working from home

I have been working in my pyjamas since more than two years ago. I mean by this that I have been working remotely from home. Now you may be thinking, I could never do that, and yeah, you are right, this kind of job is not made for everyone. It’s got its advantages, but it’s got its disadvantages as well like everything else in the world. If you don’t organize yourself thoroughly, you will never be able to put up with it for a long time. I must to admit that I sometimes miss working in an office with my colleagues, but in the other hand I’m absolutely aware of the great advantages that my current job offers me. I think the right thing to do is try to find a good balance among work and free time. Here you have some tips to help you find that balance.

Leer más

Mayo 30, 2010 at 12:00am

comentarios


2011 Porsche Boxster Spyder. 320-hp, 3.4-liter flat-six

Febrero 14, 2010 at 12:00am

comentarios


La cultura de la propina en los Estados Unidos

Una propina consiste en el pago voluntario como recompensa por un buen trato recibido. Generalmente estos pagos van dirigidos a empleados del sector servicios (camareros, taxistas, …). En Europa es bastante común dejar una parte del cambio como propina cuando la atención por parte del servidor ha sido excepcional y por lo consiguiente el cliente se siente muy satisfecho por ello. En mi caso suelo dejar algo de propina cuando en un restaurante me sirven extraordinariamente bien, es decir, en muy pocas ocasiones. Y con esto no quiero decir que me traten mal ni mucho menos. En muchos restaurantes se incluye en la factura un cargo extra por el servicio (normalmente viene descrito en concepto de cubierto), el cual por ley el cliente está en pleno derecho a no pagar en caso de que el servicio no haya sido lo suficientemente bueno.

Leer más

Diciembre 21, 2009 at 12:00am

comentarios


Integrating Yahoo r3 with phing

Yahoo r3 is a powerful tool for building websites which could require multiple

languages or dimensions. The r3 outputs may be plain text files, web templates, configuration files or even source code. Sometimes maintaining a big site translated into different languages can become a nightmare, but r3 lets you do it on an easy way. It offers a neat and powerful command line interface which will make your life easier. It can also be managed by using a web interface.

I know this could be a somewhat confusing thing to explain, so I’m going to try to give an example of what you can do with it. At Weblogs SL, we have a platform which handles instances of 37 blogs in 2 languages (Spanish and Portuguese), so we have to maintain 37×2 = 74 sites. They almost share the same layout

structure, but sometimes we need to make specific changes on certain site (maybe a customized header or sidebar). r3 lets you do all this kind of things by specializing templates for a particular site/language. Coming back to our example, we have two dimensions: blog and language. Once we have created the dimensions, we can generate all the templates. These raw templates are parseable by the template engine included within our platform, so they are processed by the application afterwards. We can also put all the “static variables” for each blog (such as blog titles, URLs, paths, …) during this pre-build process.

Leer más

Junio 2, 2009 at 12:00am

comentarios


phpredis, 2 Fast 2 Furious

Redis (REmote DIctionary Server) is a persistent key-value database with built-in net interface written in ANSI-C for Posix systems. Whilst it may at first seem like the wheel is being reinvented here, the need for something beyond a simple key-value database is pretty clear. It’s possible to use Redis like a replacement of memcached, with the main difference being the dataset is stored persistently – not volatile data – and Redis introduces new data structures such as list and sets. Furthermore, it implements atomic operations in order to interoperate with these data structures.

I released a PHP extension called phpredis a couple of weeks ago, which works as a PHP client API for Redis. The project is hosted at Google Code at the moment, and you can get the code directly from the SVN repository: http://phpredis.googlecode.com/svn/trunk/.

Despite a vanilla PHP client library already exists, I felt the need to write it since a PHP extension normally performs better and I wanted to make the most of Redis potential.

Let’s see a snippet of how to make a simple operation to Redis using the PHP client:

    $redis = new Redis();
    $redis->connect('127.0.0.1', 6379);

    $redis->set('key', 27);

    echo $redis->get('key'); // it should print 27

    $redis->incrby('key', 3);

    echo $redis->get('key'); // it should print 30

The code above was quite obvious, it stored a value associate to key and it increments its value by 3. Let’s see another snippet a bit more complex, for example using a list:

    $redis = new Redis();
    $redis->connect('127.0.0.1', 6379);

    $redis->lPush('list', 'val');
    $redis->lPush('list', 'val2');
    $redis->lPush('list', 'val3', 1);

    echo $redis->lPop('list', 1); // it should print val3
    echo $redis->lPop('list'); // it should print val2
    echo $this->lPop('list'); //it should print val

Notice that depending on the last optional parameter (0 by default) it’s possible to append/extract an element to/from the tail or to/from the head of the list.

There is a list including all the available methods. At the moment, I’m working on the implementation of more new Redis commands and on the support for complex data structures such as arrays and PHP objects.

Apart from phpredis, there are more client API for languages as Perl, Python, Ruby and Erlang. You can find this and more at the Redis project homepage. Redis has been written by Salvatore Sanfilippo who I’m chuffed to bits with.

Octubre 30, 2008 at 12:00am

comentarios


Visualization of a Phing buildfile

Raphael Stolt published a method to get a visualization of a Phing buildfile a few days ago:

Out of the box the Phing -l option can be used to get a first overview of all available targets in a given buildfile but it doesn’t untangle the target dependencies and sometimes a picture is still worth a thousand words. Luckily the Ant community already provides several tools to accomplish the visualization of Ant buildfiles, reaching from solutions that apply a Xslt stylesheet upon a given buildfile.

He uses the ant2dot tool and the Graphiz library to show the XML from a buildfile into a graphic. The image represents the flow of the build.

Julio 29, 2008 at 12:00am

comentarios


Multiple Constructors in PHP

As you probably know, it’s possible to have multiple constructors in Java. They need to have the same name as the class, and they can only be distinguished by the number and type of arguments. In PHP5, you can only have one constructor. You can define it using the reserved word __construct. If the __construct function doesn’t exist, PHP5 will search for the old-style constructor function (by the name of the class). So if we cannot have multiple constructors, how could we create objects with different initial conditions? It’s not a big deal. There’s a pattern called Factory Method, which defines virtual constructors using static methods. Let’s see an example:

class Person
{
    private $name;
    private $email;

    public static function withName($name)
    {
        $person       = new Person();
        $person->name = $name;

        return $person;
    }

    public static function withEmail($email)
    {
        $person        = new Person();
        $person->email = $email;

        return $person;
    }

    public static function fullPerson($name, $email)
    {
        $person        = new Person();
        $person->name  = $name;
        $person->email = $email;

        return $person;
    }
}

We have a class called Person which contains 2 private attributes: name and email. It also has 3 static methods: withName, withEmail and fullPerson. These methods will behave like constructors.

So if we want to create a Person object just with the name value, we can do it using the following statement:

$person = Person::withName('Example');

About me

October 1986, Tacita de plata. I was born naked, wet and hungry. After that, I became a software engineer. I make stuff. My favourite shapes are spades, hearts, diamonds, clubs and hamburgers.
Alfonso Jiménez 2004 - 2012 | Creative Commons Attribution