Los sistemas distribuidos son difíciles. Tienen muchas partes móviles con interacciones complejas y son intrínsecamente multihilos. Para que funcionen, a menudo hay alguna forma de consistencia eventual en juego. Aceptar esto puede facilitar el desarrollo de software.
Pero para abrazarlo, puede que primero tenga que convencerse de que muchas aplicaciones no necesitan una consistencia estricta. Esta no es la mentalidad normal de un desarrollador de software. Cuando los datos están cambiando, tendemos a pensar que nuestros usuarios siempre están obteniendo los últimos valores. En realidad obtienen datos viejos todo el tiempo debido a la latencia!
Por ejemplo, supongamos que un usuario accede a una página web que muestra cuántos «gustos» tiene en su contenido.justo antes de su solicitud, el número de «gustos» pasó de 100 a 101.La solicitud llega al servidor web y el código obtiene un número de la base de datos.pero entonces, antes de que el valor pueda ser devuelto al navegador del usuario, se registra algún otro «gusto» y aumenta el valor a 102.Cuando el usuario ve su número de gustos, ya está desactualizado.
Cuando utilizamos una base de datos ACID (por ejemplo, una base de datos relacional SQL), el usuario obtendrá 101 de vuelta y tendemos a decir: «Está bien, porque ese era el valor cuando se produjo la consulta». Pero si utilizamos una base de datos BASE (como Cassandra), es posible que puedan obtener un valor de 100 de vuelta. Esto suele incomodar a los desarrolladores, pero en realidad, hay muchos casos en los que eso es suficiente.
¿Qué tan bueno es lo suficientemente bueno?
Los sistemas coherentes no proporcionan datos aleatorios. Todos los valores que se pueden recuperar son válidos en algún momento. Por lo tanto, la clave para determinar lo que es «suficientemente bueno» reside en determinar la sensibilidad temporal de cada dato. O dicho de otro modo, ¿cuánto tiempo está dispuesto a esperar para que un valor sea coherente?
En el ejemplo anterior, el número de gustos de un usuario es un dato que probablemente pueda tolerar una variación del orden de los segundos, si no de los minutos.
Algunos sistemas eventualmente consistentes son capaces de trabajar dentro de estos estrechos marcos de tiempo. Aquí en , hemos usado Cassandra para algunas cosas que normalmente se harían en una base de datos relacional. Tratar con Cassandra ha cambiado la forma en que hacemos algunas de estas operaciones, pero ha valido la pena por su mayor disponibilidad.
La consistencia eventual no tiene por qué significar lentitud. Significa que hay que entender la diferencia entre el caso medio y los percentiles superiores. Determine la ventana de tiempo que importa para su aplicación y luego actúe en consecuencia.
Beneficio de la Consistencia Eventual
Una vez que haya descubierto las tolerancias aceptables, podrá aprovecharlas y empezar a tomar decisiones en su código que pueden facilitar el desarrollo. La mayor disponibilidad que viene junto con la mayoría de los sistemas eventualmente consistentes puede ayudar a su tiempo de funcionamiento. El complicado código síncrono puede ser reemplazado a menudo por un código asíncrono más simple.
Por ejemplo, tomemos una solicitud de datos en la que el servidor necesita llamar a alguna otra API para refrescar una caché de datos caducada. En lugar de un código complicado que tiene que lidiar con la espera de la llamada a la API y el manejo de los fallos de forma elegante, se podría optar por devolver los datos caducados y poner en marcha una tarea asíncrona separada para llamar a la API. (Esta es básicamente la idea de la curación fuera de banda sobre la que Matt ha escrito.) Si hay varias API para consultar o una lógica de procesamiento complicada, el beneficio aumenta drásticamente.
Otro ejemplo es utilizar la búsqueda de eventos para corregir las transacciones que no se han realizado. Los usuarios pueden ver los datos a medida que los reciben, pero los cálculos importantes pueden diferirse a períodos de tiempo más largos. Los créditos y débitos de una cuenta pueden mostrarse a medida que se reciben, pero las penalizaciones por saldo negativo no se ejecutan hasta que haya transcurrido el tiempo suficiente para tener la certeza de que no hay una transacción de crédito que falte.
Añadir alguna consistencia eventual podría ser incluso tan simple como usar un componente eventualmente consistente, como una base de datos o un agente de mensajes.
Como con todas las cosas en el desarrollo de software, inclinarse hacia una eventual consistencia es un ejercicio de compensaciones. Algunas cosas se vuelven más fáciles, pero otras más difíciles. Hacer más simples las piezas individuales de código puede ser una gran victoria, pero estás cambiando eso por la complejidad en la comprensión de todo el sistema. Usar una base de datos altamente disponible puede darte un gran tiempo de funcionamiento, pero puede hacer que el desarrollo contra esa base de datos sufra. Optimiza para el sistema en lugar de un solo equipo o servicio.
Por eso me gusta la frase de inclinarse hacia la consistencia eventual.Idealmente encuentras lugares donde ya está presente en tu sistema y lo aprovechas.Aquí en , hemos encontrado que adoptar estratégicamente la consistencia eventual puede producir un desarrollo más rápido de piezas más simples.Trabajando juntos, esas piezas simples y bien probadas se combinan para hacer cosas complejas.
Categorías: prácticasTags: arquitectura, mensajería