Estaba equivocado. El futuro es CRDT

Hace unas semanas, vi la presentación de Martin Kleppman sobre su enfoque de la edición en tiempo real a través de CRDT y sentí una desesperación ardiente. Su enfoque es tan bueno que supera todo mi trabajo durante la última década, y no habrá lugar para él en el futuro.



Pero empecemos de nuevo.



En 2010, trabajé en Google Wave, donde intentamos crear espacios editables colaborativos para reemplazar el correo electrónico, Google Docks, foros, mensajería instantánea y muchas otras aplicaciones de una sola tarea. Entre mis herramientas, me gusta especialmente el entorno de propósito general, en ningún otro lugar como en Wave, la funcionalidad no se formuló en ese momento. A diferencia de la mayoría de las otras herramientas, el entorno de propósito general no impone su propio flujo de trabajo, por lo que puede usarlo para planificar vacaciones, crear wikis, jugar juegos de mesa con amigos, programar reuniones de trabajo y mucho más.



Internamente, la coedición de Wave funciona sobre una Transformada Operacional (OT), y ha existido durante días en ese momento: nuestro algoritmo se basó en una charla de Júpiter de 1995. Para cada documento, el algoritmo mantiene una lista cronológica separada de cambios, “Tipo H en la posición 0”, “Tipo i en la posición 1”, etc. En la mayoría de los casos, los usuarios cambian la última versión del documento y el registro parece una secuencia de cambios; sin embargo, cuando somos coautores, nos enfrentamos a ediciones simultáneas.



En este caso, la primera edición que llega al servidor se registra como de costumbre, y la siguiente, si resulta estar desactualizada, se compara con el registro de eventos para determinar los objetivos iniciales del usuario. (La mayoría de las veces, todo se reduce a actualizar las posiciones de los caracteres). Luego, el algoritmo, supuestamente "este es el resultado que el usuario quería", agrega una nueva operación, como git-rebase en tiempo real.



Con el cierre de Google Wave, porté el modelo OT a ShareJS . En ese momento, node se sentía nuevo y extraño, y si mal no recuerdo, comencé ShareJS incluso antes de que se lanzara npm. Un simple coeditor requería solo mil líneas de código, y en la demostración coedité el documento en el navegador y en la aplicación.



En esencia, OT es un bucle for () adornadocon múltiples funciones de ayuda para actualizar el desplazamiento de caracteres. En la práctica, la TO es simple, fácil de entender, se pone en funcionamiento rápidamente y funciona muy bien. (10-100 mil operaciones por segundo en javascript no optimizado, 1-20 millones en C optimizado ). El registro de eventos puede consumir más memoria de lo habitual, pero se puede reducir si se desea, aunque no funcionará para combinar ediciones especialmente antiguas. La asignación global de operaciones requerirá un servidor centralizado, pero la mayoría de los sistemas ya tienen tal servidor o base de datos, ¿no es así?



Servidores centralizados



Un problema de OT importante es su dependencia de un servidor centralizado. ¿Alguna vez te has preguntado por qué, al permitir el acceso a un documento de Google Docs a través de las redes sociales, te encontraste con un mensaje extraño como "Este documento está sobrecargado y su edición está deshabilitada"? La razón (en mi opinión) es la siguiente: cuando abre un documento, se selecciona un servidor específico para procesar todas sus ediciones, y cuando una multitud de usuarios se abalanza sobre el documento, el sistema tiene que esforzarse mucho para no sobrecargar el servidor.



Hay varias formas de solucionar este problema: además de la fragmentación de subdocumentos (como en Google Docks), puede realizar ediciones a través de un bucle de reintento, omitiendo las transacciones de la base de datos, de modo que el problema de serialización sea asumido por la misma base de datos (así es como funciona Firepady ShareDB ).



Sin embargo, OT no es perfecto. Queríamos reemplazar el correo electrónico con Wave, pero el correo admite la fusión, una cadena de letras puede extenderse a través de muchas empresas y, de alguna manera, todo funciona correctamente. Además, a diferencia de los mensajes de Facebook, el correo electrónico se puede enviar a las empresas mencionadas en la columna "copiar". Si queremos que Wave reemplace el correo, también necesitará la funcionalidad de enviar mensajes sin acceso a la red externa, por ejemplo, cuando le envío una carta a mi colega en la mesa de al lado. Pero, ¿cómo se puede implementar todo esto además de OT? De alguna manera logramos configurar tal proceso, pero resultó ser demasiado complejo y lleno de errores: creamos un diagrama, en el que cada protocolo de ondas estableció un árbol de servidores de ondas para transferir operaciones en ambas direcciones, pero nunca funcionó por completo. Hace poco menos de diez años, en la Wave Protocol Summit, di una presentación sobre cómo crear y configurar dicha red, pero a pesar de toda mi preparación y todas las comprobaciones preliminares, la estricta adherencia a cada paso de la presentación en sí falló y la red nunca funcionó. Todavía no sé por qué sucedió esto, pero cualesquiera que sean los errores, casi nunca se corrigieron en la versión pública, fue demasiado difícil.



Despegue CRTD



Como ya mencioné, el algoritmo principal de Wave se creó hace bastante tiempo, en 1995, y ni siquiera recuerdo tener Internet en casa en ese momento. Desde entonces, los investigadores han trabajado incansablemente para mejorar el rendimiento de OT y, en la dirección más prometedora, utilizan CRTD (tipos de datos replicados sin conflictos). Este enfoque es algo diferente al habitual y le permite editar archivos en tiempo real sin la necesidad de un servidor central. La presentación de Martin describe su trabajo mejor de lo que yo podría describirlos, así que omitiré los detalles.



La gente ha estado pidiendo mi opinión sobre CRTD durante años, y mi respuesta siempre suena así:



Son bonitos y me alegra que la gente esté trabajando en ellos, sin embargo:


  • . . , 100 Delta-CRTD . (: B4.)
  • - CRTD , , 100 automerge master 83 . , , , , . ( automerge 1.1 .)
  • Durante años, la funcionalidad presente en OT ha estado ausente en CRDT, por ejemplo, nadie ha creado todavía un CRDT con soporte para / object move / (transferir algo de una parte del árbol JSON a otra). Estos procedimientos son necesarios para aplicaciones como Workflowy, y OT hace un gran trabajo con ellos .
  • Los CRDT son complejos en sí mismos y difíciles de razonar.
  • Lo más probable es que ya tenga un servidor / base de datos centralizado.


A pesar de todas mis críticas, ignoré el CRDT, pero al hacerlo ignoré la literatura relevante, y para mi sorpresa, extrañé la mejora silenciosa e imperceptible del CRDT. En su presentación (que merece su atención), Martin aborda los puntos principales:



  • : CRDT (Automerge / RGA Y.js / YATA) [log(n)] . ( .)
  • : - , 54- . automerge , Y.js, Y.js 100 160 3 . .
  • : , .
  • : , CRDT OT. , automerge .


El razonamiento de la velocidad no me convenció, así que para probar la idea, implementé y probé CRDT de forma independiente en Rust a través de un árbol B utilizando ideas de automerge. Carecía de funcionalidad (borrar caracteres, conflictos), pero podía manejar 6 millones de ediciones por segundo . (Cada iteración realizó 2000 ediciones en un documento en blanco por dos usuarios alternos, lo que tomó 330 microsegundos en total, o 6.06 millones de ediciones por segundo). Así que los CRDT realmente han mejorado y la diferencia de velocidad entre ellos y OT es ahora incluso menor que entre Rust y Javascript.



Todas estas correcciones han estado en la sección "próximamente" de la rama de rendimiento de automerge durante mucho tiempo, pero después de todo, automerge no es el único CRDT. Y.js demuestra ser digno y fácilmente pasa por alto la versión actual de automerge en sus pruebas . Carece de la funcionalidad que me interesa, pero en general es más fácil arreglar la implementación existente que crear un nuevo algoritmo.



Inventar el futuro



Me preocupa mucho avanzar. ¿Qué sería de extraño no tener en uso en cien años? Obviamente, tendremos edición en tiempo real, pero ya no estoy seguro de su implementación a través de OT y de todo el trabajo que he realizado al respecto, lo que no puede dejar de entristecerme.



JSON y REST son omnipresentes en estos días. Digamos que en 15 años la coedición en tiempo real será omnipresente. ¿Cuál sería el equivalente de JSON en términos de coautoría para una fácil transferencia a su proyecto? En este futuro glorioso, necesitaremos una implementación de CRDT de alta calidad, ya que para algunas aplicaciones OT simplemente no funcionará, no funcionará para crear una versión en tiempo real de GIt a través de él o una simple variación de Google Wave. Pero si ya tenemos una buena implementación de CRDT, ¿también necesitamos una implementación de OT? Creo que no, porque no será difícil transferir toda la funcionalidad de OT a CRDT (incluidas, por cierto, las operaciones de corte), mientras que lo contrario no es cierto. Las personas inteligentes no están de acuerdo conmigo, pero en mi opinión, dado que tenemos un CRDT bueno y rápido para cada idioma,la necesidad de OT desaparecerá por completo.



Una de las ventajas de OT es que se puede implementar fácilmente en sistemas centralizados, como la mayoría de las aplicaciones modernas, pero los algoritmos distribuidos están igualmente bien implementados. (Eche un vistazo a Github, por ejemplo). En mi opinión, un CRDT de alta calidad en wasm es más rápido que una implementación de OT en JS. Y si solo le preocupan los sistemas centralizados, recuerde: las restricciones de OT llevaron a Google a problemas de escalado en Google Docs.



Entonces me parece que ahora es el momento de cambiar a un CRDT pequeño y rápido. En su mayor parte, el trabajo académico ya se ha realizado, queda la cuestión para implementaciones exitosas.



Que sigue



Cada vez me preocupa menos el mundo de las aplicaciones centralizadas. Las aplicaciones interactúan con mis datos, en mis dispositivos, y sería hora de que estas aplicaciones reaccionen a tales conexiones en consecuencia. Quiero que mi computadora portátil y mi teléfono puedan transferirse datos entre sí a través de wifi y no mediante la carga de mis datos en servidores en otro país. Especialmente si estos servidores están financiados por los gigantes publicitarios que compiten por mi atención .



Filosóficamente, cuando edito un documento en Google Docs, mi computadora le pide permiso a Google para editar el archivo (porque si por alguna razón el servidor dice que no, pierdo todas mis ediciones). Por comparación, cuando git pushen GitHub, acabo de notificargithub sobre ediciones en mi código. Mi repositorio todavía me pertenece, al igual que todos los datos y hardware en los que se encuentra, y así es como deberían funcionar mis aplicaciones. Gracias a personas como Martin, ahora sabemos cómo hacer buenos CRDT. Sin embargo, antes de que se acepten las solicitudes locales como base, será necesario escribir más líneas de código.



Con todo, es hora de decir adiós a la transformación operativa. Lo pasamos muy bien juntos, de todo lo que escribí, el código de transformación operativa fue uno de los más difíciles e interesantes. Eres inteligente e increíble, OT, pero CRDT puede hacer algo que nunca podrás. Y necesito CRDT. Creo que con algunas buenas implementaciones podemos lograr algo realmente especial.



Lamento todo el trabajo que hice en OT a lo largo de los años, pero OT ya no encaja en mi visión del futuro. CRDT nos permitirá reconstruir Wave más fácil y rápido y crear aplicaciones que traten a los usuarios como ciudadanos digitales en lugar de campesinos digitales. Y esto es importante.



Es hora de crear.



All Articles