2 puntos por GN⁺ 2024-01-11 | 1 comentarios | Compartir por WhatsApp
  • La causa de la complejidad del backend no está tanto en defectos de productos específicos, sino en que la estructura conceptual que las bases de datos han mantenido durante mucho tiempo sigue restringiendo el diseño de aplicaciones
  • Las bases de datos se comportan como estado mutable global y hacen que los desarrolladores carguen con modelos de datos fijos, esquemas limitados y la tensión entre normalización y desnormalización
  • La alternativa propuesta combina event sourcing y vistas materializadas para separar los datos fuente de las vistas de índice, y trata los índices como estructuras de datos durables, no como modelos de datos
  • Rama, de Red Planet Labs, reúne en una sola plataforma la ingesta, procesamiento, indexación, consulta, despliegue y monitoreo de datos mediante depots, ETL, PStates y query topologies
  • En un caso de reimplementación de Mastodon a escala de Twitter, se compara que Rama se implementó con 10k líneas y 9 meses-persona, mientras que el producto de consumo equivalente de Twitter requirió 1M de líneas y alrededor de 200 años-persona

Punto de partida de la complejidad de las bases de datos

  • El foco del problema no está en las API, las dificultades operativas o las restricciones arbitrarias de un producto de base de datos específico, sino en la estructura conceptual colectiva que se ha mantenido hasta hoy
  • Los problemas del enfoque existente se vuelven más claros cuando aparece una mejor forma de hacer las cosas; como alternativa, se propone combinar event sourcing y vistas materializadas

Las bases de datos como estado mutable global

  • A los programadores se les enseña a minimizar el uso de variables globales, pero una base de datos también es, en esencia, estado mutable global
  • Las bases de datos tienen aspectos aún más difíciles de manejar que las variables globales comunes
    • Las interacciones están distribuidas entre varios sistemas, lo que dificulta razonar sobre el estado
    • Como el estado es durable, corregir un bug no restaura automáticamente los datos dañados
    • En algunos casos es difícil identificar con precisión el alcance del daño o corregirlo por completo
    • Volver a un respaldo o fusionar partes de un respaldo no es una solución óptima
  • Con event sourcing y vistas materializadas, las vistas pueden recalcularse a partir del log fuente, lo que abre la posibilidad de corregir estados de índice dañados

Límites de los modelos de datos fijos

  • Las bases de datos se diseñan alrededor de modelos de datos como key/value, document, relational, column-oriented o graph
  • Como es difícil que un único modelo de datos cubra todos los casos de uso, las empresas suelen usar varias bases de datos en conjunto
  • Una abstracción de índice más general no es un modelo de datos, sino una estructura de datos
    • Key/value: map
    • Document: map of maps
    • Relational: map of maps; los secondary indexes son maps adicionales
    • Column-oriented: map of sorted maps
  • Las estructuras de datos durables se almacenan en disco, pueden crecer muchísimo y también pueden representar estructuras de datos anidadas
  • Si los índices se especifican como combinaciones de estructuras de datos, se pueden crear no solo los modelos de datos existentes, sino formas de índices más variadas
  • Si la forma de almacenamiento puede adaptarse al modelo de dominio de la aplicación, en lugar de retorcer el modelo de dominio para que encaje en la base de datos, se reduce la complejidad de base

La tensión entre normalización y desnormalización

  • Los usuarios de bases de datos relacionales terminan enfrentándose a una elección entre normalización y desnormalización
  • El almacenamiento normalizado crea una fuente de verdad clara y reduce la posibilidad de inconsistencias, pero puede aumentar la cantidad de joins y elevar el costo de las consultas
  • Si por rendimiento se almacena la misma información de varias maneras, cuando hay bugs pueden aparecer inconsistencias de datos
  • La arquitectura de los RDBMS combina en el mismo datastore la fuente de verdad y el almacenamiento de índices para consultas rápidas
  • La solución es una estructura que separe ambos roles
    • Un subsistema representa la fuente de verdad
    • Otro subsistema materializa, a partir de esa fuente, la cantidad deseada de almacenes de índices
    • Si el segundo sistema puede recalcular los índices desde los datos fuente, puede corregir inconsistencias

Esquemas limitados y representación del dominio

  • Las bases de datos difieren mucho según el producto en los tipos de valores que permiten almacenar
    • Algunas bases de datos solo permiten blobs como byte arrays
    • Otras permiten varios tipos, como enteros, punto flotante, cadenas y fechas
  • Es poco común almacenar la información anidada dentro de objetos de dominio como una representación de primera clase que pueda consultarse o agregarse directamente
  • Como el lenguaje de implementación de la base de datos y el lenguaje de la aplicación suelen ser distintos, la interoperabilidad es difícil; incluso extensiones como protobuf extension para Postgres son engorrosas y limitadas
  • Un ORM mapea entre la representación del dominio y la representación de la base de datos, pero la abstracción puede tener fugas y causar problemas
  • Si hay que indexar los datos de una forma distinta a la representación ideal del dominio, se necesita código adaptador, y también pueden limitarse las consultas que pueden ejecutarse eficientemente

Despliegues complejos y el modelo à la carte

  • Un backend completo no está compuesto solo por una base de datos; requiere muchos instrumentos en conjunto, como bases de datos, sistemas de procesamiento, herramientas de monitoreo y schedulers
  • Un backend a gran escala puede requerir combinar decenas de herramientas, y una actualización de la aplicación puede convertirse en una orquestación de migraciones, actualizaciones de código y cambios de infraestructura
  • Para estar listo para producción se necesita suficiente telemetría, pero cada herramienta recopila datos de forma distinta, por lo que reunir todo en un único dashboard de monitoreo también se vuelve una tarea de ingeniería aparte
  • El enfoque de desarrollo actualmente dominante se parece a un modelo à la carte, donde se elige y conecta la mejor herramienta para cada parte de la arquitectura
  • Hacer que herramientas diseñadas de forma independiente funcionen juntas ya es una gran tarea en sí misma; además, por los modelos de datos fijos y los esquemas limitados, se termina adaptando la aplicación a las herramientas en vez de adaptar las herramientas a la aplicación
  • El modelo à la carte se consolidó porque no había un modelo cohesivo para construir backends; en un modelo cohesivo aumentan las oportunidades de abstracción, automatización y reutilización

Un modelo simple para entender el backend

  • Las principales funciones de un backend son recibir datos nuevos y responder preguntas sobre esos datos
  • La consulta más general puede expresarse como ejecutar una función sobre todos los datos que recibió el backend
    • query = function(all data)
  • En la práctica, el dataset puede ser de 10PB y las respuestas a consultas pueden requerirse en milisegundos, por lo que un sistema práctico necesita índices
  • El modelo con índices agregados se expresa así
    • indexes = function(data)
    • query = function(indexes)
  • Los backends existentes implementan los componentes de este modelo dividiéndolos entre varias herramientas estrechas
    • Un backend con RDBMS puede usar el RDBMS para datos e índices, y usar una base de datos separada como ElasticSearch para indexación adicional
    • El cálculo suele hacerse en handlers de servidores API o en trabajos en segundo plano basados en colas y workers
    • Un backend a gran escala puede combinar herramientas como Cassandra, MongoDB, Neo4j, Kafka, Hadoop, Storm y Kafka Streams
  • Esto lleva a la conclusión de que, si existiera una herramienta que implementara todos los componentes de manera integrada y general, se podría evitar la complejidad anterior

Componentes de Rama y el caso de Mastodon

  • Rama es una plataforma de desarrollo backend diseñada con base en estos principios
  • Red Planet Labs anunció Rama el 15 de agosto con el tagline “the 100x development platform”
  • Como caso de reducción de costos, presentó el trabajo de reimplementar Mastodon a escala de Twitter
    • 100M de bots publican 3,500 veces por segundo
    • El fanout promedio es 403
    • Se compara con el producto de consumo equivalente de Twitter, que habría requerido 1M de líneas y alrededor de 200 años-persona
    • La implementación en Rama requirió 10k líneas y 9 meses-persona
    • La implementación es open-source y se presenta como complete, high-performance, production-ready
  • Se compara que Twitter, para alcanzar esa escala, creó bases de datos especializadas propias como una social graph database y una in-memory timeline database, y tuvo un despliegue complejo con más de 1M de líneas solo de configuración Puppet
  • Según el texto, la implementación basada en Rama resolvió problemas similares de rendimiento y escalabilidad combinando los elementos primitivos de Rama, en vez de crear infraestructura especializada nueva para cada subproblema
  • Los performance numbers de la implementación de Mastodon se presentan como iguales o mejores que las cifras de Twitter

Modelo de programación de Rama

  • Los conceptos de Rama corresponden directamente al modelo de backend presentado antes
    • Depots: logs distribuidos que contienen datos arbitrarios y corresponden a data
    • PStates: abreviatura de partitioned state, y corresponden a índices
    • ETLs: corresponden a function(data)
    • Queries: corresponden a function(indexes)
  • Los PStates pueden crearse en la cantidad necesaria como combinaciones arbitrarias de estructuras de datos durables
  • Los ETL y las queries se expresan mediante una API de dataflow Turing-complete, y el cálculo puede ejecutarse de forma distribuida
  • Rama ofrece en su documentación tutoriales de la API Java, y también cuenta con una API Clojure

Cómo Rama reduce la complejidad de las bases de datos

  • Los PStates de Rama cumplen un rol similar al de una base de datos, pero solo pueden escribirse desde la ETL topology que posee ese PState
    • Como todas las escrituras están en el mismo código ETL, es más fácil razonar sobre el estado
    • Los PStates funcionan como vistas materializadas sobre logs de event sourcing
    • Como los depot data son la fuente de verdad, los PStates pueden recalcularse
  • Las restricciones del modelo de datos se abordan especificando los PStates como estructuras de datos
    • La implementación de Mastodon usa 33 PStates solo para profiles, statuses y timelines
    • Algunos PStates manejan 10 casos de uso, mientras que otros soportan solo un caso de uso
  • Los PStates tienen propiedades durable, partitioned e incrementally replicated
    • incremental replication significa que, si falla una leader partition, hay otra partition lista para hacer takeover
    • Se garantiza que lo visible en el leader actual también será visible en el leader posterior
  • El problema de normalización y desnormalización se aborda separando explícitamente depots y PStates
  • El problema de los esquemas limitados se mitiga usando directamente la representación del dominio
    • Estructuras de datos comunes como hash map y list
    • Protocol Buffers
    • Definiciones de objetos anidados
    • Los tipos que Rama no conoce se manejan registrando un custom serializer

Despliegue, integración y monitoreo

  • Las aplicaciones de Rama se llaman modules, y un module puede incluir varios depots, ETLs, PStates y query topologies
  • Rama ofrece mecanismos integrados para desplegar, actualizar y escalar modules, y se afirma que cada acción se realiza con un one-liner en la terminal
  • Rama no es una herramienta “all or nothing”, sino que está diseñada para facilitar la integración con otros sistemas, de modo que puede incorporarse gradualmente en arquitecturas existentes
  • Al ser una plataforma integrada, también realiza su propio monitoreo
    • Recopilación de datos de monitoreo
    • Procesamiento
    • Indexación
    • Visualización
  • La cluster UI telemetry se usa para entender el rendimiento de los modules, detectar y diagnosticar problemas, y decidir cuándo escalar

Aprendizaje y ruta de adopción

1 comentarios

 
GN⁺ 2024-01-11
Opiniones de Hacker News
  • “Como explicaré más adelante, un mejor enfoque es event sourcing y vistas materializadas”, o sea que al final la solución es aumentar la complejidad. Claro, cómo no.

    • Si se hace bien, en realidad simplifica mucho la arquitectura del backend. Incluso las apps de baja escala suelen usar varias bases de datos, como Postgres y ElasticSearch, además de una cola y workers para tareas en segundo plano.
      Nuestra implementación de Mastodon a escala de Twitter es un ejemplo directo. Para construir la misma funcionalidad a escala, literalmente tiene 100 veces menos código que el que Twitter habría tenido que escribir, y también más de 40% menos código que la implementación oficial de Mastodon. No es que la hayamos diseñado mejor por ser la segunda vez con las mismas herramientas, sino porque está hecha con una abstracción fundamentalmente mejor.
    • La complejidad no desaparece, solo se mueve a otro lugar. Para muchas tareas, los trade-offs de esta solución pueden ser malos.
      Pero al pasar cierta escala, todo se convierte en un problema de ingeniería de datos, y en el contexto del sistema completo este enfoque a veces termina siendo una solución relativamente simple. El consejo de “solo usa mySQL/SQLite/Postgres” es excelente solo hasta que llega el momento en que deja de ser válido.
    • ¿Que aumenta más la complejidad? El autor lo hizo muy simple. Basta con usar su producto, Rama.
    • En todas las empresas donde trabajé, event sourcing + vistas materializadas derivó en un caos extremo, más bugs y caídas más largas. Soluciones más simples como MySQL o PostGres, o Redis/DynamoDB, funcionaron mejor en todos los casos.
      Sinceramente creo que habría sido mejor para todos si el artículo original de Martin Fowler sobre event sourcing nunca se hubiera escrito. Me parece una mala idea en el 99% de los casos.
    • Si el dominio del programa requiere una complejidad esencial X, de todos modos hay que implementar esa complejidad. Puedes dejarla en manos de código de otras personas que ya fue escrito y probado en producción, o puedes volver a hacerlo tú mismo; lo segundo puede tomar mucho tiempo y dar peores resultados. No hay almuerzo gratis.
  • No sé si se me pasó algo, pero parece que el artículo omite por completo conceptos como concurrencia, aislamiento y restricciones. Y eso de “topología de consulta” no parece declarativo y da la impresión de trasladar al autor la responsabilidad de la planificación/optimización de consultas. ¿De verdad consideran que esto es una mejor experiencia de desarrollo?

    • Estos temas están cubiertos suficientemente en la documentación. Este artículo trata sobre la complejidad del desarrollo backend y cómo Rama la aborda, no pretende explicar por completo todos los aspectos de Rama. Si explicara todo, sería demasiado largo. Si profundizas más en Rama, verás que sus propiedades y garantías son muy sólidas.
      Y sí, la forma de hacer consultas en Rama es un enfoque muy superior. La necesidad de un planificador de consultas complejo suele venir de las limitaciones en la forma de indexar los datos, especialmente de la tensión entre normalización y desnormalización. En Rama es fácil materializar de forma robusta varias vistas ya preparadas con la forma que necesitan las consultas.
      Aquí hay un tutorial que presenta suavemente los conceptos de Rama: https://redplanetlabs.com/docs/~/tutorial1.html
  • Sobre la afirmación de que “ningún modelo de datos único puede soportar todos los casos de uso”, en teoría no existe ningún dominio, ni conjunto finito de dominios, que no pueda modelarse con precisión mediante tuplas y relaciones de cosas.
    En la práctica, el alcance de una base de datos/esquema específico suele limitarse a un solo negocio o área de problema, pero eso tampoco es gran cosa siempre que los tipos no se solapen de manera inadecuada. Si se tiene cuidado con los nombres, se puede meter a un minorista web y a una aseguradora en el mismo esquema y funcionará suficientemente bien.
    Poner todo exactamente en una sola base de datos es un superpoder. La razón principal por la que lo defiendo con tanta fuerza es para evitar transacciones distribuidas entre varios almacenes de datos. Si todo el negocio ocurre dentro de un solo sistema transaccional, la semántica se simplifica drásticamente.

    • Estoy especialmente de acuerdo con la idea de que “poner todo en una sola base de datos es un superpoder”.
      Cuando la gente empieza a usar datos de verdad, un servidor de base de datos grande de 1 millón de dólares es mucho más barato que un arreglo redundante de bases de datos baratas. Todos ahorran tiempo, ya sean desarrolladores, analistas o directivos; quizá la única excepción sean algunos DBA.
    • Las bases de datos grandes no son algo nuevo. Si eso fuera todo, la gente habría seguido haciéndolo así durante los últimos 40 años. Pero no siempre funcionó, y a veces fue frecuentemente horrible.
      Incluso si en teoría eso fuera todo, otro problema persistente es la implementación. Hoy la mayoría de los desarrolladores no entiende bien cómo funcionan las bases de datos ni cómo deberían usarse, así que las usan pésimamente. Por eso, para escapar de ese hecho, se crearon nuevas bases de datos como NoSQL, intentando pensar menos y escribir más código de pegamento. Eso también resultó ser horrible.
      Pronto la corriente volverá a cambiar y “simplemente una gran base de datos” dejará de estar de moda otra vez, y aparecerá otro paradigma de “simplicidad”. Como ocurrió con los microservicios, puede que en vez de “una gran base de datos” se considere simple tener “muchas bases de datos pequeñas”. Si no entendemos la historia, estamos condenados a repetirla.
    • Decir que un caso de uso puede modelarse con tuplas y relaciones no significa que la base de datos pueda satisfacer los requisitos de rendimiento de ese caso de uso. Si no puede cumplirlos, entonces ese caso de uso no está soportado.
      Es lo mismo que en la programación general: una sola estructura de datos, o combinación de estructuras de datos, no puede soportar todos los casos de uso. A veces se necesita un mapa, a veces una lista, un conjunto, una combinación, o algo completamente distinto.
    • Estoy de acuerdo con que “poner todo en una sola base de datos es un superpoder”. Mi empresa anterior tenía una configuración de microservicios cargo cult en la que cada app tenía su propia DB, y eso la volvió innecesariamente compleja y cara, sin beneficios de negocio. Seguramente sí tenía beneficios para llenar el CV. No hay que complicar las cosas hasta que sea obligatorio hacerlo.
    • Es una idea de ensueño y realmente hermosa, pero en la práctica no funciona. ¿Alguien ha tenido éxito con esto? Llevado al extremo, implica que necesitaríamos una sola base de datos unificada para todo el mundo y un solo sistema de permisos de usuario.
      Por supuesto, las estructuras de datos son diversas, también se necesita rendimiento, y se convierten en cuellos de botella demasiado importantes como para que cualquiera las toque; todos los cambios deben ser extremadamente seguros. También está la seguridad. ¿Qué pasa si alguien encuentra una forma de pasar de la sección de bugs de desarrollo a la sección financiera exclusiva de RR. HH. o de ejecutivos? Cualquiera que haya implementado un sistema ERM general sabe lo difícil y doloroso que es un sistema integrado.
      Dicho eso, este es un caso extremo. Me da curiosidad hasta dónde ha llegado la gente persiguiendo este ideal y cómo lo hizo. Nunca he visto un negocio que funcione con un solo sistema. ¿Y los sistemas personales de gestión del conocimiento? ¿Todo encaja ahí? ¿No se siguen usando hojas de cálculo para tareas rápidas y archivos de texto para contenido de formato libre?
  • Parece una colección de buzzwords. Llevo años trabajando con bases de datos en una de las empresas más grandes del mundo y nunca he oído la palabra topología.
    Aunque con esto se pudiera ahorrar tiempo, se iría en aprender Java y este framework. No hay nada malo con las bases de datos en sí.

    • Hay una implementación de Mastodon lista para producción con funcionalidad equivalente a escala Twitter, hecha con 100 veces menos código que el que escribió Twitter, así que me cuesta estar de acuerdo con la crítica de que es una “colección de buzzwords”: https://github.com/redplanetlabs/twitter-scale-mastodon
    • A mí me parece un ejemplo de este tipo de publicidad.
      Intenté hacer una tabla de texto aquí, pero la visualización de la página se rompió por completo, así que la subí como captura: https://imgur.com/a/XtwSkyx
  • ¿Cómo le explicarías Rama a un niño de cinco años? La documentación también me confundió: https://redplanetlabs.com/docs/~/index.html
    Preferiría que omitieran palabras de moda como “cambio de paradigma” o “plataforma”. Si hace falta un diagrama, me gustaría leer un texto que lo explique con más claridad.

    • Es una plataforma de desarrollo backend que puede manejar las necesidades de recopilación, procesamiento, indexación y consulta de datos de una aplicación a cualquier escala. En vez de armar un backend mezclando varias bases de datos, sistemas de procesamiento, colas y planificadores, se puede hacer todo dentro de una única plataforma llamada Rama.
      Rama se ejecuta como un clúster, y varias aplicaciones se despliegan en ese clúster en forma de “módulos”. También trae integrada telemetría profunda y detallada.
      El modelo de programación de Rama es event sourcing y vistas materializadas. Al crear una aplicación Rama, materializas tantos índices como necesites, en la forma que quieras, como combinaciones de varias estructuras de datos persistentes. Los índices se materializan mediante una API de flujos de datos distribuida.
      Rama es tan distinto de lo que ya existía que esta es la explicación de alto nivel que puedo dar. El mejor material para aprender lo básico es rama-demo-gallery, que contiene ejemplos breves, completos y con comentarios detallados que aplican Rama a varios casos de uso. Todos son escalables y tolerantes a fallas: https://github.com/redplanetlabs/rama-demo-gallery
    • Según lo que leí, es una arquitectura Kappa, es decir, una variante de event sourcing.
      Hay un log de eventos de solo agregado llamado “Depot”, sobre el cual se crean vistas arbitrarias llamadas “P-States”. El software Rama promete actualizaciones de baja latencia para esas vistas. Las aplicaciones construidas encima consultan las vistas y envían nuevos eventos/comandos al Depot.
    • Parece una base de datos de event sourcing. Básicamente, en lugar de escribir directamente, escribes mensajes y puedes crear tablas de solo lectura que se actualizan según esos mensajes. En ciertos dominios esto ya se hace hoy, pero definitivamente es más complejo que una base de datos tradicional.
    • Parece otro intento de NoSQL. “¡Pero esta vez es diferente!”.
  • Hice un proyecto de un año para construir un motor flexible de vistas materializadas sobre datasets de eventos en vivo de 1 a 10 TB, y antes de pasarme a otro proyecto nuestra arquitectura también estaba convergiendo más o menos hacia la idea de enviar el código donde están los índices.
    Rama me resulta bastante atractivo, pero por una razón completamente irracional probablemente no lo adoptaría por la JVM. Simplemente no me gusta Java/JVM. Me gustaría que esta arquitectura se portara a otros entornos.

  • En mi trabajo separamos el modelo de lectura y el modelo de escritura. El modelo de escritura, es decir, la fuente de verdad, es un modelo de dominio relacional tradicional con invariantes/restricciones, y creo que para la mayoría de los desarrolladores familiarizados con un ORM no es difícil razonar sobre él.
    Casi todos los comandos también generan eventos y los publican en una cola compartida de eventos de dominio. Los modelos de lectura los construyen workers que consumen eventos de la forma que cada uno necesita, y también pueden reconstruirse. Por ejemplo, el servicio de administración de usuarios es la fuente de verdad, y otros servicios son servicios de vistas para mostrar una UI compleja; construyen sus propios modelos de lectura/índices a partir de eventos del servicio de usuarios y de otros servicios. Sin esto, habrían hecho falta joins enormes o llamadas API lentas entre servicios.
    Técnicamente es posible reproducir eventos. De hecho, una vez reprodujimos todos los eventos de los últimos 3 años por un bug en el código de la plataforma. Pero creo que casi nunca lo hemos necesitado de verdad. A veces hay que reconstruir una vista por un bug, pero normalmente lo manejamos con programas ad hoc, como scripts especiales o migraciones SQL. No sé exactamente cómo se llama nuestra arquitectura, y nunca escuché que nadie la llamara “event sourcing”.
    Al final es MySQL + RabbitMQ de toda la vida y algo de código de pegamento. Pero hacerlo bien no es tan trivial por cosas como el patrón transactional outbox, garantías de entrega al menos una vez, consistencia eventual, mantener el orden correcto de procesamiento de eventos, versionado de datos de eventos, administración de la DB, qué hacer cuando muere un handler de eventos, etc. Dado que ya es una configuración probada en producción e independiente del lenguaje, con productores/consumidores tanto en PHP como en Go, me pregunto qué nos estamos perdiendo sin Rama y cómo resuelve Rama los problemas de la lista anterior. Rama parece estar más orientado al mundo Java.

    • Parece que diseñaron una muy buena forma de gestionar la complejidad usando un RDBMS. Hay algunas cosas que Rama ofrece por encima de eso.
      Los índices de Rama son mucho más flexibles. Por ejemplo, si necesitas un conjunto anidado con 100 millones de elementos, es algo trivial. Un ejemplo común es un índice de grafo social del tipo ID de usuario → conjunto de IDs de seguidores. Lo mismo con índices de series temporales divididos por granularidad, es decir, entidad → granularidad → bucket de tiempo → estadísticas.
      No hay restricciones sobre los tipos de datos que se almacenan en Rama. Las consultas de Rama son muy potentes, y es fácil hacer consultas distribuidas en tiempo real bajo demanda sobre una parte o la totalidad de un índice. También trae integrada telemetría profunda y detallada para toda la aplicación, así que no hace falta construirla ni administrarla por separado.
      El despliegue también está integrado. Con el enfoque actual, una actualización de la aplicación puede abarcar varios sistemas, como código de workers y migraciones de esquema, y se vuelve una tarea de ingeniería bastante difícil, sobre todo si quieres cero downtime. Como Rama integra de punta a punta cómputo y almacenamiento, lanzar, actualizar y escalar aplicaciones se puede hacer con una sola línea en la terminal.
      Rama es mucho más escalable. Eso es Rama visto desde el punto de vista de funcionalidades, y es difícil expresar con palabras cuánta diferencia hace que al programar con Rama no haya desajuste de impedancia; hay que probarlo para entenderlo. Rama es para la JVM, así que puede usarse con cualquier lenguaje de la JVM, y actualmente ofrece APIs para Java y Clojure.
    • Para un comando como “actualizar dirección del cliente”, ¿se ejecuta SQL y luego un trigger del RDBMS envía el evento a RabbitMQ, o el ORM envía el SQL y publica en RabbitMQ?
      ¿Dónde y en qué formato se almacenan los eventos? Me gustaría escuchar más detalles.
      Lo que parece faltar ahora es un nombre atractivo para todo el ecosistema.
  • Materializar los datos en el momento del cambio puede ser beneficioso cuando el producto necesita hacer una sola cosa muy rápido. Pero se vuelve problemático en cuanto aparecen transacciones complejas que deben actualizarse juntas con escrituras atómicas, o cuando se intenta agregar una nueva función que requiere organizar los datos de otra manera.
    También resulta muy insatisfactorio que, en la parte sobre construir aplicaciones, se pase por alto con ligereza diciendo algo como “solo hay que agregar un índice”. Un índice es estado global; simplemente se movió una capa más abajo.

    • Precisamente porque “simplemente se movió una capa más abajo”, lo crucial es que ya no hay que administrarlo directamente. Lo único que hay que hacer es decirle al sistema qué indexar. Eso no es estado ni datos, es código.
  • Incluso leyendo este documento, no queda claro quién es el público objetivo ni qué problema intenta resolver: https://redplanetlabs.com/docs/~/why-use-rama.html#gsc.tab=0
    Sería útil tomar un caso real y mostrar cómo se transforma con RAMA, y qué tan fácil y eficiente resulta.

    • Hemos publicado muchos ejemplos.
      El primero es una implementación de Mastodon a escala de Twitter, con 100 veces menos código que el que Twitter escribió para construir lo mismo a escala. Esto considera solo el producto de consumo. Incluso tiene más de 40% menos código que la implementación oficial de Mastodon, que no es escalable: https://github.com/redplanetlabs/twitter-scale-mastodon
      El repositorio rama-demo-gallery también incluye muchos ejemplos breves, independientes y comentados en detalle que aplican Rama a casos de uso muy distintos. Incluyen gestión de perfiles de usuario, análisis de series temporales y transferencias bancarias atómicas y tolerantes a fallas: https://github.com/redplanetlabs/rama-demo-gallery
  • Si en realidad no operan un sitio web con 40 millones de usuarios diarios, no parece posible afirmar que esto quedó demostrado con un “cliente de Mastodon a escala de Twitter”. Es imposible simular un entorno real, los cambios de código e infraestructura que eso implica, usuarios reales, uso de red, etc.