Ande yo caliente, ríase la gente

Me encuentro con ciertas preguntas recurrentes en toda charla que doy sobre la arquitectura y tecnología de Ducksboard. Una de ellas es cómo demonios hemos acabado usando la base de datos de una manera tan… original. Otras, y éstas son las interesantes, van en la línea de:

¿Y por qué Python y no Ruby?
¿Y por qué PostgreSQL en vez de MongoDB?
¿Y por qué Backbone.js si mola más Ember.js?
¿Y por qué <ducks-tecnología-X> y no <yo-prefiero-tecnología-Y>?

Nuestra elección de tecnología sigue una serie de criterios. Lo que sigue es una explicación de algunos de ellos para responder a todas esas preguntas, así del tirón. Once and for all, que decía aquel.

El tema tiene su importancia, claro. Cuando uno arranca una startup para crear un producto tecnológico, la elección de las tecnologías de base es un asunto sensible. Afecta a la velocidad de desarrollo, a la calidad del producto, a la construcción del equipo, etc. En definitiva, tiene una incidencia directa en el éxito o fracaso del proyecto. Como para pensar un rato en ello antes de hacer locuras, ¿no? Hay millones de opciones para las distintas capas del producto, que se mezclan en trillones de combinaciones, y hemos de decidirnos por una de ellas, pero ¿cuál?

Aquí cada cual tendrá su lista de factores para medir cada opción, yo os voy a contar cuales son los míos y los voy a ilustrar con ejemplos reales de, por decir algo, Ducksboard (y además titulados con refranes, que mola más :)).

Más vale malo conocido que bueno por conocer

Para mí la regla de oro en todo este asunto. Lo primordial al escoger una tecnología es que el equipo sea productivo con ella. Y, por lo general, la gente es más productiva en aquello en que tiene experiencia. La razón es bien sencilla: nuestro aprendizaje es iterativo. Cada vez que hacemos algo obtenemos información extra que usamos las siguientes veces para hacerlo mejor, construimos sobre nuestra experiencia. Es la base de nuestra educación, de las prácticas de conducción o del entrenamiento en un deporte. Con las tecnologías pasa exactamente lo mismo. Alguien que lleva años programando en un lenguaje de programación conoce detalles, trucos, problemas con sus soluciones, etc., que un recién llegado ha de aprender a base de tortazos. La experiencia es un grado.

Así pues, ¿por qué en Ducksboard usamos Python y no Ruby? Fácil, porque Jan y yo conocíamos bien Python, era el lenguaje con el que trabajamos durante años en Flumotion. Sin duda con Ruby puede hacerse lo mismo, pero mi experiencia con Python me permite avanzar más rápido, escribir un producto más sólido, y afrontar posibles problemas con muchas más garantías. Lo mismo puedo decir de PostgreSQL, del que Jan es un colaborador habitual y por tanto un experto. Somos capaces de prever mucho mejor tiempos de desarrollo, posibles problemas y otras muchas sutilezas que con tecnologías que desconocemos no podríamos. Simplemente por nuestra experiencia.

Si estás en posición de poder dedicar 6 meses a formar un equipo antes de empezar a producir nada, entonces ignora todo este punto :).

Cada oveja con su pareja

O sobre la idoneidad de una herramienta para una tarea. El diseñador de una solución tecnológica ha de conocer y comprender muy profundamente el problema que trata de solucionar. Antes de pensar siquiera en lenguajes, librerías o herramientas, ha de plantearse cosas más genéricas como si su aplicación tiene como cuello de botella la comunicación de red o el uso de CPU porque hace cálculo intensivo, si ha de dar servicio a un usuario o a un millón, o si ha de ofrecer alguna característica lo bastante raruna como para no poder implementarse en las herramientas típicas para la tarea.

¿Cómo aplica eso a Ducksboard? Un ejemplo sencillo es el uso de Python en todo el backend de obtención de datos: no necesitamos un lenguaje más rápido porque el cuello de botella está en la comunicación con webservices externos. Usar C (por ejemplo) sería ralentizar mucho el desarrollo para tener una ganancia en velocidad o consumo de recursos despreciable. Un ejemplo más complejo es PostgreSQL. Queremos una base de datos relacional porque nuestro datos son relacionales. Un widget va vinculado a una fuente de datos que va vinculada a un usuario. Esa relación ha de estar asegurada y ser irrompible, y aunque yo cometa un error en código la base de datos ha de asegurar que un usuario jamás va a ver datos de otro. En nuestra aplicación, eso es más importante que la velocidad o escalabilidad más sencillas que pueda ofrecernos MongoDB.

Más sabe el diablo por viejo que por diablo

¡La juventud, siempre tan impetuosa! No dejan de aparecer nuevos productos la mar de interesantes. Bases de datos no-relacionales que van como un tiro, lenguajes de programación que prometen la velocidad de desarrollo de Ruby y la velocidad de ejecución de C, librerías que hacen posible escribir un servidor web que sirva chorrocientos trillones de peticiones por segundo en 2 líneas de código. El progreso, señores, el progreso. Me encanta el progreso, estoy al día de todos estos asuntos, de todas estas herramientas. Estaré encantado de usarlas… mañana. Sí, mañana, cuando estén maduras, probadas, bien documentadas, y no nos inunden posts de gente llorando porque la base de datos súper rápida del momento se ha merendado todos sus datos de facturación, y no quiere escupir la tía.

Muchos me preguntan que dónde voy usando SQL si ahora NoSQL es lo más y lo último. Y siempre les respondo lo mismo: mi negocio son los datos de mis clientes, son sagrados en Ducksboard. SQL lleva usándose exitosamente en bancos y otras industrias críticas 30 años para almacenar y consultar esos datos. NoSQL lleva dando guerra un par de años. ¿A cual le confío el alma de mi negocio? Para mí está claro. Pasa lo mismo con Twisted (que usamos en Ducksboard) versus Node.js. Hacen más o menos lo mismo, pero el primero tiene casi 10 años de desarrollo a sus espaldas, con incontables proyectos que han servido para hacerlo un producto robusto, y el segundo tiene un par de primaveras. Mi negocio, si puedo evitarlo, no va a ser beta-tester de nada que no sea nuestro propio código.

La avaricia rompe el saco

Los ingenieros/desarrolladores/programadores (nunca sé que palabra usar) solemos cometer un error muy típico: el matar moscas a cañonazos. Para cualquier cosa que haya que implementar, por sencilla que sea, tratamos de ofrecer una solución future-proof: hace lo que nos han pedido y otras 200 cosas que no, por si las acaban pidiendo. Y ninguna bien, por cierto. Abracemos el principio de sencillez: si ha de hacerse una cosa, usemos una herramienta que sólo hace esa cosa, la hace bien, y sin artificios innecesarios. Nos va a ahorrar tiempo de desarrollo, tiempo de mantenimiento, y va a hacer nuestro producto más comprensible para la gente que vaya uniéndose al equipo en el futuro.

En su momento nos planteamos en Ducksboard usar la base de datos como cola de mensajería también (PostgreSQL soporta ese modelo), pero finalmente optamos por lo sencillo: la cola de mensajería es un RabbitMQ que sólo hace eso. Gracias a eso es más fácil determinar de donde vienen los errores, podemos escalar la plataforma de manera más flexible, y usamos para cada necesidad una herramienta líder. Tan sencillos queremos ser, que en vez de meternos en la frondosa selva de los locos RPCs para comunicar procesos entre ellos (SOAP, te miro a ti), tiramos de HTTP de toda la vida. Y la mar de contentos, oiga, limpio, sencillo y además funciona. ¡Y sólo JSON en todas partes!

No por mucho madrugar amanece más temprano

En fin, y a modo de resumen, si he de escoger una tecnología entre varias para dar solución a una necesidad concreta del producto, trato de escoger aquella con el enfoque necesario y en que el equipo sea ágil. Si es un tema nuevo y no tenemos la experiencia, voy a fiarme de soluciones probadas y sencillas. Si no existe una alternativa que cumpla con esos requisitos, quizás sea el momento de plantearse desarrollar una propia :).

En algunos casos no queda otra que romper con las directrices generales, claro está. Con el uso de WebSocket lo hicimos: un protocolo tan nuevo que no estaba ni terminado (implementamos los borradores antes de ser oficial). Pero teníamos una buena razón: la inexistencia de una alternativa válida para tener comunicación bidireccional en tiempo real en web. Y, no hay sorpresas aquí, nuestro sufrimiento nos ha costado: re-implementar el servidor varias veces para soportar nuevas versiones, incompatibilidades con navegadores, versiones actuales de los mismos que dejan de ir de golpe, etc. No hay milagros.

Mi consejo, no caer nunca en el cargo cult. El que otros estén usando el proyecto X o Y no los convierte necesariamente en las mejores opciones para mi producto. Tengo un equipo distinto, una arquitectura distinta, y un producto distinto. Lo que para otros funciona muy bien puede ser un desastre en mi contexto. La elección de la tecnología ha de adaptarse a la realidad del equipo y al enfoque del producto, y no al revés. Es necesario de buen principio disponer de una persona con conocimiento real sobre las alternativas disponibles en el mercado para tomar esas decisiones con cabeza, porque si se toman en base a buzz, el producto y la empresa van a sufrirlo. Y si no, al tiempo.

Advertisements

22 thoughts on “Ande yo caliente, ríase la gente

  1. Gracias Aitor por tan detallado post.

    Da gusto conocer las particularidades técnicas de un proyecto, el por qué de una determinada elección y qué otras opciones se han valorado.

    Aunque siempre se pueden aplicar nuevas tecnologías en siguientes fases de refactorización, avanzar sobre una tecnología conocida es siempre el mejor camino.

    Un saludo

  2. Sinceramente, no me he enterado de casi nada. Los patos habláis super raro y lo único que me queda claro del post es que usáis Pifón como lenguaje y PatoWC como base de datos. Y lo del cargo cult ya me ha matado, deberías escribir un post solo dedicado a eso.

    1. Pitón, pitón. Las palabrejas raras van enlazadas a la Wikipedia, que es posiblemente la peor opción porque escriben los artículos para ser incomprensibles :)

      Lo del cargo cult es un tema muy curioso. Me parece encantador en su contexto original de tribus en la selva y tal, pero algo menos cuando pasa con gente dedicada a nuevas tecnologías.

  3. No has hablado de porqué habéis escogido backbone en el frontend en lugar de spine, ember, etc. Al ser tecnologías más recientes, tu método no es tan válido en el frontend. A no ser, claro, que tengáis algún experto en la tecnología en concreto, no?

    1. Muy cierto, buena observación. Uno de mis compañeros en Ducksboard (David) me lo ha hecho antes de publicar.

      Todo tiene su trampa: tengo pendiente un artículo (posiblemente este fin de semana) centrada exclusivamente en la elección e integración de Backbone. Y esa es la razón :)

  4. De acuerdo en la mayoría de comentarios, pero alguno se puede matizar. Sobre todo el relativo a “…base de datos súper rápida del momento se ha merendado todos sus datos de facturación..” que imagino te refieres a redis, habría que preguntarles si tenían configurado algún snapshot y mecanismos de backup de éste, al igual que tenemos en cualquier base de datos Oracle. De todas formas para datos de facturación personalmente usaría una clásica relacional pero si me apuras incluso podrían haber usado otra instancia redis con persistencia en este caso, al revés de la operativa, y mayor frecuencia de snapshot.

    Lo que comentas cada tecnología tiene su uso, Redis para determinados usos es la ideal, pero no universal.

    De todas formas muchas gracias por compartir la información con todos nosotros, pocos lo hacéis de forma tan clara.

    Te habla un mercenario de la tecnología, no me apasiona ninguna en general.
    “Only a fool blame the tool”

    1. De hecho me refería a MongoDB, en su momento salieron algunos posts porque se corrompían los datos en algunos circunstancias. Siempre que digo que usamos PostgreSQL la gente se extraña y propone MongoDB, de ahí el ejemplo.

      Por descontado cada tecnología tiene su aplicación, y de hecho nos planteamos incluir Redis para una función específica en la arquitectura, pero, como comento en el post, cada herramienta ha de usarse para el fin para el que se diseñó, sino se puede liar parda.

  5. Interesante artículo.

    “Esa relación ha de estar asegurada y ser irrompible, y aunque yo cometa un error en código la base de datos ha de asegurar que un usuario jamás va a ver datos de otro.”
    ¿Cómo gestionáis esto con postgres?

    PD: El título de la primera sección está mal (más vale malo conocido…), salvo que fuese una puyita a ruby, que no lo parece. ;)

    1. En postgres la integridad de los datos la aseguramos con claves foráneas y constraints. No se puede insertar o modificar filas que rompan una constraint o un clave foránea.

      Efectivamente estaba mal escrito el primer refrán, arreglado, gracias!

      1. Esto no me deja responder a comentarios de tercer nivel, que remedio :)

        Me refería a no poder introducir valores de un cliente vinculados a otro cliente por error. En una DB de documentos, como CouchDB o MongoDB, podría por error crear un documento diciendo que el id de cliente es 45, cuando en realidad es 47, y no hay nada del lado de la DB que vaya a comprobar que eso no es posible. A eso me refería :)

      2. Ya es entrar algo más en detalle en el esquema de Ducksboard, pero la idea es que los valores numéricos van vinculados a fuentes de datos, que a su vez van vinculadas a servicios, que a su vez van vinculados a un usuario. Efectivamente, un esquema relacional sólo me asegura que vinculo filas a otras existentes, pero como las claves foráneas son compuestas y empujamos las columnas importantes (como la de usuario) a varias tablas, tiene que acabar dándose el caso de que meto datos en una combinación de fuente de datos + servicio + usuario válida. La probabilidad de que un error de código dé una combinación válida de esas varias dimensiones es muy inferior a la de simplemente poner un id de usuario inválido en un documento.

        Pero como comentas, la integridad referencial sólo va a comprobar que la relación existe, no hay concepto de autorización. Ese concepto lo “forzamos” en parte empujando columnas a las claves foráneas de varias tablas. Sacrificamos simplicidad del esquema por algo más de robustez, básicamente.

  6. Con este artículo, has recuperado el crédito que habías perdido al no saber pasar de la pantalla de login de JIRA… :P

    Bromas aparte, tu y yo SIEMPRE estamos de broma -tirándonos puyitas con tolleadas sobre si Java necesita toneladas de XML sólo para ejecutar un Hola Mundo o si Python sólo sirve para hacer juguetes- porque los dos sabemos que pensamos justo lo contrario: La tecnología no es un fin, sino un camino.

    Los técnicos debemos encontrar la mejor solución para conseguir algo en tiempos y costes, sin más. Nuestro objetivo nunca puede ser “estar a la última” o crear una solución que pueda arrastrar por eventos, congresos, bodas y bautizos, sino proporcionarle el mejor servicio a nuestros usuarios e intentar que los accionistas de nuestra empresa ganen el máximo dinero con ello.

    Ya sabes que yo cada vez estoy más cerca del lado oscuro. Ese que está lleno de Excel y Powerpoints, pero aún no me he vuelto tan tonto como para no apreciar la valentía y la experiencia que hay detrás de este artículo. La verdad es que da gusto leer algo así entre tanta idiotez de Java vs. Ruby vs. PHP vs. Python vs. lo-que-se-lleve-ahora

    Tienes que hablar más a menudo con Jeroclo el espartano, sois de la misma escuela de pensamiento. Si vieras el framework web Java con el que estamos programando Otogami alucinas… es tan simple que, cualquier idiota sería productivo con el. No es cool, ni revolucionario, ni siquiera bonito.

    Ni falta que hace. lo que importa es el producto, aunque muchos aún no se hayan dado cuenta.

    ¡Enhorabuena por el post!

    1. Tendrás que presentarme al ilustre Jeroclo, el hombre que a base de buen gusto ha evitado que te rindas completamente al yugo del pogüerpoint!

      1. Me encantan estos articulos, siempre me sirven para conocer la forma de trabajo de gente con mas experiencia y que quizas algun día puedan ser de gran utilidad para mi trabajo. Aunque ojala mi empresa empezara a actualizar los frameworks de trabajo…

        Por cierto David Bonilla, ¿de que framework web java hablas? Ya por curiosidad xD

      2. Para Kisco: ningún framework Java cumplía los requisitos de flexibilidad que Jeroclo buscaba para cumplir las absurdeces que yo le voy pidiendo a nivel de negocio (ahora cambiamos todas las URLs para mejorar el SEO, ahora cambiamos la estructura de navegación…) así que, se ha creado uno propio, Funsteroid. Con un par.

  7. Aún cuando leído suena tan normal, qué bien sienta ver que elegisteis con sentido común: dentro de las tecnologías con las que estabais cómodos, en cada lugar, la más productiva de las posibles. Un buen ejemplo de cómo hacer las cosas! :-)

  8. Para mi, lo mas interesante es disponer de un mecanismo RPC para comunicar procesos/modulos homogéneo en toda la arquitectura, sea este HTTP+JSON o cualquier otro. De esta manera el resto de tecnologias se convierten “simplemente” en un medio para encaminar información entre componentes que podrás sustituir sin demasiados problemas cuando alguna no cumpla expectativas ( Python->Clojure ?? xDD ). Tiempo de reacción.

  9. Pingback: Noticias 31-05-2012 - La Web de Programación

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s