Esta es una pregunta sobre sistemas distribuidos e involucra conceptos de ordenamiento temporal.
Gran parte de esto es contraintuitivo porque los humanos tienden a pensar que las cosas son instantáneas. Sin embargo, en el mundo de la informática, este es un problema común porque lleva tiempo que las cosas sucedan y más tiempo para que determinemos que realmente han sucedido. Lo exacerbamos en los sistemas informáticos porque utilizamos técnicas comunes para tratar “cosas que son lentas”: las ponemos en cola (o las publicamos) y permitimos que se procesen de forma asíncrona y las almacenamos en caché porque obtener la respuesta era costosa y no lo es Es probable que cambie.
Por ejemplo, en una CPU moderna hay varios niveles de información: registros, que están dentro de la CPU y la RAM, a los que se debe acceder a través de una interconexión física (un “bus”). Las operaciones en los registros son muy rápidas porque los datos ya están dentro de la CPU. Las operaciones en la memoria son más lentas porque la CPU debe buscar y / o almacenar los datos en la memoria. Entonces, una secuencia es el infame ciclo de lectura / modificación / escritura: lea un valor de la memoria en un registro, modifique el valor en el registro y vuelva a escribirlo en la memoria.
- Cómo restablecer un enrutador Zyxel
- ¿Por qué no tenemos un protocolo de mensajería para todos en lugar de solo varios clientes que están interconectados en una red?
- ¿Cuál es la diferencia entre seguridad de red y seguridad de infraestructura?
- ¿Por qué la arquitectura cliente-servidor sigue siendo el núcleo de la mayoría de las aplicaciones de red?
- Cuando un servidor ignora una solicitud, ¿qué hace después de eso?
Esa CPU moderna podría obtener el valor del caché , que es un tipo de memoria que está más cerca de la CPU (a menudo parte del paquete físico que contiene la CPU) y mucho más rápido pero más costoso y, por lo tanto, mucho más limitado. Cuando tiene varias CPU, cada una con sus propios registros y caché, deben coordinarse para garantizar que los cambios de una CPU sean visibles para la otra CPU. La forma más sencilla de hacer esto es siempre volver a escribir en la memoria. Desafortunadamente, aunque simple, esto limita significativamente el rendimiento. Entonces realmente no escribimos las cosas.
Esto lleva a una situación en la que el contenido de la memoria caché puede diferir entre las CPU. La mayoría de las veces esto no importa, a veces sí importa. A medida que aumenta el costo de la coordinación entre las CPU, el costo de esta coordinación también aumenta y el rendimiento disminuye.
Cuando separamos las CPU por una red, como en un sistema distribuido, agregamos aún más fallas potenciales, como la partición de la red. Una vez más, la mayoría de las veces nada de esto importa, nada de esto se convierte en un problema y en tales casos no hay necesidad de ninguna coordinación entre las CPU.
A veces lo hay. Cuando ese es el caso, establecemos las restricciones de orden de las operaciones. si A debe suceder antes que B , entonces tenemos una restricción de ordenamiento, una restricción de suceso anterior. Si A y B son independientes, no hay restricción. Para los sistemas distribuidos, esto se usa a menudo para describir la permanencia : la idea de que sabemos que una vez que hayamos visto algo, nunca veremos algún estado anterior del sistema.
Pero, ¿cómo sabemos el orden de las operaciones entre computadoras disjuntas? Una forma de hacerlo es usar marcas de tiempo . Una marca de tiempo es un valor monotónicamente creciente que indica cuándo se ha observado algún estado. Si bien es conceptualmente simple, la idea de un reloj global resulta ser notablemente difícil de implementar (mire el protocolo NTP si desea ver cuán difícil). Pero para nuestros propósitos de establecer un orden, todo lo que necesitamos saber es algún valor, no un valor universal . Si tenemos múltiples fuentes de eventos, necesitamos usar un solo valor universalmente creciente monotónicamente (Lamport Clock) o necesitamos describir un conjunto de valores monotónicamente crecientes que definen el estado del sistema (reloj vectorial).
Entonces podemos usar la marca de tiempo para determinar el orden correcto de los eventos. Mientras conservemos este orden dependiente, podemos repetir operaciones y saber que estamos viendo la misma secuencia de eventos.
¿Porque es esto importante? Porque en un mundo de operaciones asíncronas y almacenamiento en caché sin ordenamiento temporal impuesto, necesitamos algún mecanismo adicional para garantizar un ordenamiento (incluso con la penalización de rendimiento).
Lo mejor de esto es que cuando el orden no importa, no es algo que necesitemos describir en nuestra marca de tiempo. Cuando lo hace, podemos describirlo y podemos determinar un orden en el que ocurren los eventos específicos.
Falta esta discusión la necesidad de imponer a veces un orden en los eventos. Este es un espacio increíble lleno de problemas y cuestiones fascinantes a pesar de que la idea básica de proporcionar atomicidad, aislamiento, durabilidad y consistencia (las propensiones de ACID) es bastante sencilla. Muchos de los proyectos en los que he trabajado a lo largo de los años han “relajado” una o más de estas propiedades porque fomenta el rendimiento en los casos en que las propiedades no son necesarias para resolver la tarea en cuestión.