[update]I’ve already implemented the third first steps  https://github.com/flopezluis/kvstore

The next step for my humble key value store is to be able to scale reads, the two typical solutions for that are sharding and replication, or even, in some cases, both of them.

In my case I’m going to start adding replication because I think this is going to lead me to learn more things about Distributed Systems. Supporting Replication means that I have to understand at least these things:

  • Types of Replication: Master Slave (leader based replication), MultiMaster Replication, Quorum-Based Replication…..  
  • Failover. What happens when a node crashes? What happens if your replication is Master/Slave and the master goes down?
  • How do you solve conflicts? is It possible to avoid conflicts?
  • Strong consistency,  Eventual consistency, Weak consistency.

For this first approach I’m going to implement Leader based replication, this is probably the most simple case of replication and once I’ve mastered it I’ll move forward to a more difficult model.

One of the advantages of this replication is that I don’t have to worry about conflicts as the Master is the only one accepting writes. This makes the implementation much much easier. When you have to control different versions of the data you have to start worrying about the order of the events and then, synchronization becomes part of your problem. After reading about that you realize that this is quite tricky and solutions like NTP are not going to solve the problem for you, which leads you to vector clocks or version vectors, which seems easy but they aren’t.

When you’re implementing replication one of the first decision you have to make is whether the replication is going to be asynchronous or synchronous.

  • If it’s synchronous the database can’t accept any more writes until all the replicas have confirmed the operation. This means that one simple node can stop the database from accepting writes. In exchange you have strong consistency.
    This model is also affects the performance of the database. The more replicas you have the more time it takes to complete the write operation and the more likely is to have a problem in a node.
  • With asynchronous replication the performance is not affected and the database continue accepting writes even if several replicas go down. The tradeoff is that the replicas can have stale data. t some point this data will be updated but you don’t have any guarantee of when that will happen. This is know as Eventual Consistency.
    This model has a big drawback, if the leader crashes and the replica take over, you can have data lost.

There is a mixed model in which the database has synchronous replication with one node and asynchronous replication with the rest. In case the leader goes down the asynchronous replica can take over.

In my case I decided to start implementing asynchronous replication.

Ok, so how do I implement replication?

One option would be statement-based replication where each update is sent to the replicas, then each replica applies the change and that’s it. However this presents some flaws:

  • What happen when a node couldn’t apply the changes due to a problem? e.g a connectivity problem.  In this case if the node just continues receiving the last change It would have inconsistent data, it wouldn’t have the changes that were sent while it was down.
  • If we just send the last change we couldn’t start new nodes on demand. As they will only have the data from the moment in which they joined the cluster.
  • In case of failover It would be really difficult to decide which node has to take over as they would have inconsistent data.

To solve these problems each node should receive the all the changes after the last one they have confirmed. With all this in mind it is clear that we need to store the changes and  we need to know the time order of the changes.

In addition to that as of today if the leader goes down there is no way to recover the data because everything is in memory. So I would also need the stored changes to recover a node from a crash.  In fact I would need this even if the database weren’t distributed.

The common way of doing this is using a write ahead log where every operation is stored in the log and then applied to the database. The file is append-only so operations are much faster.

So I’m going to kill two birds with one stone and implement something similar to BitCask for Riak, this will be used both for replication and crash recovery.

This is what my solution (on paper) looks like:

  1. We store every key and value in an append-only file, so that operations are much much faster and simple.
  2. The in-memory hashmap works as an Index for byte offsets. Every key in the hashmap points to an offset in the file.
  3. Every write that arrives will only do the above operations. No replication operations will be done here.
  4. Once a replica receives a change it will apply it to its storage and it will store the offset in the file. Remember that it is append-only so this data represents where this replica is in the feed of changes.
  5. There will be a background process polling each node every X ms:
    • Tell me you’re last offset
    • Send to the replica every change since that offset. This means that we need to do random reads to that file which will affect the performance. (Should I have an In-Memory cache for the last N changes?)

This solution has the advantage which is that we don’t even have to wait for the ack, as every X ms we will start again sending all the changes a replica needs.

There are quite a few things that BitCask does that I’m not going to implement for now, for example in my implementation the file grows for ever, I would have to do merge and compaction.


Bitcask http://docs.basho.com/riak/1.3.0/tutorials/choosing-a-backend/Bitcask/

Designing Data Intensive Application http://dataintensive.net/

An Introduction to Distributed Systems http://webdam.inria.fr/Jorge/html/wdmch15.html

Eventually Consistent http://www.allthingsdistributed.com/2007/12/eventually_consistent.html

Conflict Resolution http://pl.atyp.us/wordpress/index.php/2010/03/conflict-resolution/

The trouble with timestamps https://aphyr.com/posts/299-the-trouble-with-timestamps

Why vectors clock are hard http://basho.com/posts/technical/why-vector-clocks-are-hard/

Dynamo http://www.allthingsdistributed.com/files/amazon-dynamo-sosp2007.pdf

At ShuttleCloud, we’ve developed a distributed platform than can handle very high loads. This has given me a good knowledge of distributed systems from the perspective of the practitioner. We’re using, for example,CouchDb, pacemaker and corosync, Amazon RDS, Rabbitmq, etc.

However, implementing this kind of software is a completely different beast. It’s a broad and complex field.  Most tech people I admire and follow on twitter are working in that field and you can see that is really difficult to keep up. There are too many things to learn! :D

Lately I’ve been reading a lot about the subject, but reading is not enough. If you want to learn something, you had better start using it. That’s why I’ve decided to implement an In-Memory key-value Store (a very simple one).

The objective is to learn things like:

  • Should I implement a Write-ahead log so that the DB can recover from a crash?
  • Should I implement a Log-structured to store the values so that the database is not limited by the RAM (well, keys have to fit in memory)?
  • How can the database scale reads? and writes? Do I need sharding? Replicas? Should it be a Leader based replication?…..
  • How can the data be replicated in different machines?
  • How does it know when the Leader has a failure?
  • ….

My idea is to write post about my decisions on those questions and to publish the implementation in this repo, so that I can learn from other people.


“¿Pero que tontería dices?”

“Toda la razón”

Cualquiera que sea tu respuesta creo que te interesa esto.

En ShuttleCloud como en casi todos los sitios tenemos fuegos, tenemos más trabajo del que podemos hacer y mucha presión. Creo que se puede entender estando en producción en Gmail y moviendo 6 TB por día…. de hecho salimos a producción en Abril y desde entonces nuestra API ha estado up todo el tiempo. Y no solo tenemos Gmail, tenemos clientes bastante grandes como Time Warner, Comcast, hemos sacado un API que ya están usando clientes grandes y que tiene un mucho de experimentar e investigar.

En ShuttleCloud intentamos potenciar que la gente aprenda y crezca profesionalmente, lo hacemos poniendo a su alcance herramientas e intentando que la cultura anime a hacerlo. Entre las cosas que damos o hacemos están:

  • Cualquier libro relacionado que se quiera leer, se compra.
  • Se paga la asistencia eventos. No solo las entradas, viaje, hotel, comida, etc
  • Organizamos eventos y damos todas las facilidades para organizarlos.
  • Realizamos lightning talks y talleres cada semana, o casi cada semana :D.
  • Se anima a la gente a asistir a cursos que pueden ayudarles a mejorar, y claro los paga la empresa :D.
  • Promocionamos que la gente dedique tiempo en su día a día a leer, investigar, etc.
  • Hay un seguimiento individual para intentar que la empresa conozca y ayude a la gente a que crezca profesionalmente.

Con todo eso, el viernes tuvimos una charla todo el equipo para intentar que la gente aproveche más estas oportunidades porque habíamos detectado que no estaba ocurriendo. La cuestión es que cuando tienes mucha presión y mucho trabajo la tendencia es ver solo eso y olvidar que el trabajo que no deja de crecer y que hay que entender que no se puede hacer todo. Sí, ya sé pero que metodología usáis? hacéis prácticas ágiles? ese no es el problema. El problema es que siempre hay cosas que mejorar y que haciendo integración, mover datos en la nube es de lo que va, pues requiere de mucho trabajo no planeado. También que en la cabeza de la gente están todas las cosas que hay en el backlog.

Para mi hay dos problemas uno en la empresa y otro en cada uno de nosotros. Empiezo por el segundo, como developers creo que debemos ponernos como parte de nuestro día a día leer e investigar. Ya no solo leer los avances del framework, lenguaje que usas, sino también prácticas, nuevos lenguajes, frameworks, conocimiento base, etc. Y esto va a parte de la empresa, lógicamente deberías trabajar en una empresa en la que estén alineados, pero esto tienes que entenderlo como parte de tu rutina. Si no puedes hacer esto porque el trabajo diario te lo impide, deberías poner medidas, como quejarte y ser muy pesado :D

Desde el punto vista de empresa, el problema es que se debe intentar poner medidas para que la gente entre en esa dinámica de querer aprender, crear una cultura en la que la gente comparta su ilusión y lo que aprende. Y estar vigilante para que si alguien está en la dinámica de dejarse ahogar por el trabajo, cambiar esa situación. Para eso lo mejor en mi opinión es hablar con la gente, bueno el verbo no es hablar es escuchar. Por eso es importante tener reuniones individuales con la gente para ver como se sienten y como quiere evolucionar. Aunque no hay nada como trabajar codo con codo durante un tiempo.

Siento el ladrillo ;)

Hoy he ordenado mi armario y han salido como 15 camisetas de diferentes eventos de los últimos 2 años o así.

En mi caso estas camisetas acaban casi siempre como pijamas y finalmente como trapos. Recuerdo un tweet (no lo he encontrado por eso no pongo link) que decía algo como que las conferencias cumplían una función social que era dotarnos de pijamas para el resto del año.

Tengo tantas que ya no sé que hacer con ellas, así que las voy a llevar a caritas. Entiendo que allí les darán mejor uso que yo y eso me ha llevado a preguntarme, ¿por qué no hacemos esto directamente en los eventos?.

Cuando te registras en un evento estaría bien marcar una opción parecida a esta:

– No quiero merchandising, prefiero que ese dinero se done a alguna causa benéfica.

No creo que sea mucha pasta pero algo es algo, y es posible que en muchos eventos las camisetas sean baratas por el hecho de hacer muchas, así que simplemente no tiene sentido hacer menos, pero bueno incluso en ese caso los del evento podrían quedarse las camisas y donarlas a alguna ONG, donde seguro hay gente que las necesita más que nosotros.

Revisión anual

diciembre 26, 2014

Llega final de año y como es tradicional la gente hace una revisión de lo que ha sido su año, no suelo hacer esto, pero he tenido un año tan memorable para mi que espero que esto me sirva como un lugar donde volver y mirar la suerte que tengo.

Empecé el año trabajando mucho mucho en el libro que íbamos a sacar. Finalmente salió en Febrero y 11 meses después no me puedo quejar de como va, llevamos según la editorial exactamente 999 copias vendidas xD. Muchos me han preguntado que tal fue mi experiencia escribiendo y la respuesta es sencilla, mala :D El trabajo que lleva es muchísimo y eso que estamos hablando de un libro muy pequeño, también es cierto que no es en mi idioma nativo. De todas formas, mis respetos a la gente que escribe libros de calidad y con una buena amplitud de contenidos.

Poco tiempo después salimos a producción con Gmail, este proyecto es sin duda el proyecto más grande en el que he trabajado nunca. Por si alguno no lo conoce, algo muy probable teniendo en cuenta lo mal que nos vendemos xD, Gmail ha integrado nuestra tecnología dentro de su web para que los usuarios puedan migrar sus emails y contactos de otros proveedores a Gmail ( https://support.google.com/mail/answer/164640?hl=en). Estos son algunos de los datos de este proyecto a día de hoy:

  • Hemos migrado:
    • 1.3 millones de cuentas de contactos, lo que significa 400 millones de contactos.
    • 1.2 millones cuentas de email. 7000 millones de emails.
  • Movemos 170 GB/h, lo que es más de un 1 terabyte cada 6 horas 24/7
  • Nuestro sistema está up 99%
  • Somos la única empresa integrada en Gmail, para evitar problemas como éste, es mejor decir que somos la única empresa en la que Gmail se ha integrado con nosotros.

Poco después de esto me seleccionaron para entrar en http://insightdatascience.com/ el simple hecho de que te elijan es para mi suficiente para estar contento, pero bueno además de eso, pasé las entrevistas, de la que más orgulloso estoy es de la prueba de código, había que programar un black jack. Supongo que será por ser developer :D 

Al final no salió, principalmente por un problema con el visado y la fecha en la que el curso tiene lugar, me pidieron que volviera a pasar el proceso para evitar este problema en la edición de Febrero pero la verdad la entrevista final me decepcionó completamente, a mi que alguien evalúe a una persona en base a una de esas típicas preguntas técnicas de entrevista me dice mucho y malo de ellos.

Después de esto me invitaron a dar una charla para contar nuestra arquitectura en Dallas en la SpringOne  (http://www.infoq.com/presentations/data-migration-rabbitmq-spring?utm_source=infoq&utm_medium=QCon_EarlyAccessVideos&utm_campaign=SpringOne2GX2014)

Para mi esta experiencia es una de las mejores de mi vida. La charla surgió gracias a @old_sound,  él fue quien movió todo para que se hiciese realidad. La experiencia fue espectacular, me tocó currar mucho para preparar la charla, es un evento que atrae mucha atención y quieres hacerlo bien. Pero la experiencia fue increíble sobre todo por @old_sound, como la charla era conjunta con él pasamos toda la semana juntos y me dio tiempo para conocerle bien. Álvaro es una de esas pocas personas que sorprende tanto por lo que sabe como por su forma de ser, he conocido muy poca gente en este sector (y llevo más de 13 años) que tengan el ego más pequeño que el conocimiento y él es uno de ellos.

Por último, estos dos últimos meses han supuesto un gran win en mi vida profesional, siempre he tenido gente a mi cargo pero estos dos últimos meses me he echado a la espalda a todo el equipo técnico de ShuttleCloud, su forma de trabajar, de interactuar con el resto de la empresa, etc.

Esto ha llevado a un cambio importante en mi role en la compañía que espero poder comunicar oficialmente pronto.

Estamos trabajando en muchas cosas muy chulas con compañías muy importantes que esperamos que salgan pronto, aunque nuestro objetivo como podéis ver en nuestra web http://shuttlecloud.com/ es que todos los developers puedan usarlo.

A 2015 solo le pido salud, del resto ya me encargo yo.


Update (6/3/2014):

Visto que este post ha creado un poco de polémica  en la mencionada lista matizo unas cosas de cosas:

  1. No crítico la lista, sino a los trolls que la pululan.
  2. Mucha gente me ha dicho que simplemente ignore a estos personajes. Prefiero intentar cambiar las cosas y decir lo que no veo bien.
  3. “Deberías quitar el post”. Prefiero pensar que vivimos en un mundo donde podemos opinar libremente.
  4. Me llama la atención que cuando empezó el trolleo a la oferta, nadie de los que ahora se rasgan las vestiduras dijera nada de nada.

Y ahora el texto de la polémica:

Hoy publicábamos una oferta para Junior , decidimos publicarla en la lista de correo de python porque aunque no requerimos experiencia, la gente que provenga de esta lista puede que ya este familiarizada con el lenguaje. Un camino menos que recorrer.

Publicamos la  oferta más honesta que pudimos, intentando dejar claro qué hacemos, qué ofrecemos, qué esperamos del candidato y todas las condiciones que damos. Sinceramente creo que la oferta es muy muy buena, ya me hubiera gustado tener una oferta así cuando empecé.

Hemos recibido bastantes candidatos y de mucho nivel, de hecho algunos tienen demasiado :D Pero me quedé con muy mal sabor de boca, la primera respuesta que recibimos en la lista de python fue una crítica absurda, intentando desmontar nuestra integración con Gmail, con el argumento simple e infantil de yo no lo veo. La verdad es que me lo pensé tres y cuatro veces antes de publicar la oferta porque de todos es sabido que este tipo de personajes pululan por las listas.

No paro de darle vueltas a lo absurdo de la situación, a lo absurda que se está volviendo la comunidad.  De verdad es necesario estar intentando todo el día dejar a otros compañeros mal, estar todo el día intentando demostrar lo inteligente que eres, lo hipster, hacker o lo que sea? en serio? No hay nada mejor, nada que puedas aportar? Ni tan siquiera tomarte una birra? llamar a un amigo?

Por desgracia mi tiempo lo tengo muy limitado y será por eso que lo valoro tanto, antes de meterme en una lista a atizar a otros, prefiero leer un artículo, tocar la guitarra, bueno destrozarla :D, leer, tomarme una birra, un té, un café, hasta leche joder!

La verdad es que cansa mucho que siempre haya gente dispuesta a dar lecciones con cada sentencia que sale de su boca, yo ya ni lucho, me agotan demasiado estas luchas sin sentido.

Esto también viene a colación con dos podcast (uno y otro) que escuchaba hace poco sobre si estamos haciendo algo como Developers para mejorar la sociedad.
Sinceramente, no somos tan importante como pensáis algunos, no estamos cambiando la vida de nadie. El software en conjunto si lo es, pero los developers de forma individual NO, un médico hace mucho más que nosotros por la sociedad, es mucho más importante. Un activista de una ONG hace mucho más, se involucra en hacer cambios mucho más. Seguro que habrá algunos que sí, pero estoy seguro que no son los del ego gordo. Conozco muy poca gente que haga software que sirva para algo que realmente mejore la sociedad. Y por el contrario después de muchos años currando en esto, conozco a mucha mucha gente con un ego enorme.

Algunos os habéis aferrado a la etiqueta developer y habéis perdido por el camino las etiquetas más valiosas: empatía, compañerismo, humildad….

Equipos 4×4

noviembre 22, 2013

Recientemente en la empresa ha surgido el debate de si en un equipo (Scrum) todos los componentes deben saber hacer todas las tareas que surjan. Nuestros equipo está formado por 6 personas pero por distintos productos o partes de productos. Hay frontend, varios backends, dentro de los backends hay muchas matices, tenemos un plataforma que su punto fuerte es que es distribuida, otros que son meramente endpoints que integran servicios, etc. hay mucho de devops, etc. En tecnologías tenemos ruby, python, java, Spring Integration, Django, RabbitMQ, redis, couchdb, mysql y seguro que me dejo alguna.

De primeras para mi esto no es un equipo 100% scrum, sino que debería haber equipos separados por producto, proyecto, pero siendo tan pocos acabaríamos teniendo reuniones con nosotros mismos :D

Veo muy complicado que un equipo pueda ser productivo en todo, llevo más de 11 años trabajando en esto y todas las veces que lo he intentado ha fallado. Para mi, el problema es que una persona puede adquirir conceptos e ideas de otros proyectos y tecnologías pero si son demasiadas cosas, básicamente lo que se consigue es tener a una persona que no es productiva y que esta frustrada, más si pensamos que a una persona no le guste o no se encuentre cómoda en una tecnología o producto. 

Los que defienden este enfoque suelen decir que con el tiempo la gente ganará soltura y podrá ayudar y que haciendo pairing eso se consigue. Pero yo veo muy complejo que alguien llegue a ser tan productivo en algo como otro que lleva tiempo en eso y que le gusta, además de las aptitudes de cada uno. Me parece mucho presuponer pensar que alguien pueda ser igual de productivo que otro sin más. En mi opinión se corre el riesgo de acabar siendo aprendiz de todo y maestro de nada. 

Para mi es raro, por ejemplo imagina que tienes a Guido (http://www.python.org/~guido/) y le tienes haciendo frontend, si le gusta y quiere ir hacia ese camino perfecto, pero sino… estás desaprovechando demasiado lo que tienes en el equipo.

Además el tema del pairing, para mi ya se parece a las curas milagro,  es otra cosa que hecho en todas las empresas, y creo que funciona pero no es nada mágico ni nada para hacer a todas horas. Muchas de las veces que estoy haciendo pairing sé que los dos que estamos haciendo pairing podríamos avanzar más y mejor por separado y luego hacer pairing al final, para mergear o implementar las partes que se tocan.

La idea del post es básicamente conocer otras experiencias para intentar cambiar un poco mi forma de verlo, cambiar mi experiencia negativa para construir algo más productivo, así que ¿Cual es vuestra experiencia?


Recibe cada nueva publicación en tu buzón de correo electrónico.