diciembre 04, 2023

Colas

 Colas.

    Mientras que los grupos y publicación-suscripción proporcionan un estilo de comunicación de uno a varios, las colas de mensajes proporcionan un servicio punto a punto utilizando el concepto de cola de mensajes como una indirección, logrando así las propiedades deseadas de desacoplamiento de espacio y tiempo. Son punto a punto en el sentido de que el remitente coloca el mensaje en una cola y luego es eliminado por un solo proceso. Las colas de mensajes también se conocen como Middleware orientado a mensajes.

  Modelo de programación

    El modelo de programación, figura 1, que ofrecen las colas de mensajes es muy sencillo. Ofrece un acercamiento a la comunicación en sistemas distribuidos a través de colas. En particular, los procesos productores pueden enviar mensajes a una cola específica y otros procesos (consumidores) pueden recibir mensajes de esta cola. Se admiten tres estilos de recepción: 
  • una recepción con bloqueo, que se bloqueará hasta que esté disponible un mensaje apropiado; 
  • una recepción sin bloqueo (una operación de sondeo), que verificará el estado de la cola y devolverá un mensaje si está disponible, o una indicación de no disponible en caso contrario; 
  • una operación de notificación, que emitirá una notificación de evento cuando un mensaje esté disponible en la cola asociada. 
Figure 1: Modelo de Programación.



 Características

    Entre sus características: 
  • Varios procesos pueden enviar mensajes a la misma cola y, del mismo modo, varios receptores pueden eliminar mensajes de una cola.  
  • La política de colas es el primero en entrar, primero en salir (FIFO), pero la mayoría  de las implementaciones de colas de mensajes también admiten el concepto de prioridad, con los mensajes de mayor prioridad entregados primero. Los procesos de consumidor también pueden seleccionar mensajes de la cola según las propiedades de un mensaje.  
  • Un mensaje consta de un destino ( un identificador único que designa la cola de destino), metadatos asociados con el mensaje, incluidos campos como la prioridad del mensaje y el modo de entrega, y también el cuerpo del mensaje.  Los mensajes son persistentes, es decir, las colas de mensajes almacenarán los mensajes indefinidamente (hasta que se consuman) y también enviarán los mensajes al disco para permitir una entrega confiable. 
  • Cualquier mensaje enviado se recibe eventualmente (validez) y el mensaje recibido es idéntico al enviado, y ningún mensaje se entrega dos veces (integridad). Por lo tanto, los sistemas de cola de mensajes garantizan que los mensajes se entregarán (y se entregarán una vez), pero no pueden decir nada sobre el momento de la entrega.

 

Bibliografia:

[1] Sasu Tarkoma. Publish/Subscribe Systems: Design and Principles. Edited by Joe
Sventek David Hutchison Serge Fdida. 2012. 
[2]  George Coulouris et al. Distributed Systems: Concepts and Design. 5th. USA:
Addison-Wesley Publishing Company, 2011. ISBN: 0132143011 
[3] Roberto Vitillo. Understanding Distributed Systems. 2021

Implementar sistema Publicación Suscripción.

 Consideraciones para Implementar sistema Publicación Suscripción.

Centralizadas 


    El procesamiento de eventos y notificaciones se puede implementar fácilmente en editores y con un intermediario centralizado, ver Figura 1.
En la implementación centralizada, ocurre que: 
  • El enfoque más simple es centralizar la implementación en un solo nodo con un  servidor en ese nodo que actúa como un intermediario de eventos. 
  • Los publicadores publican eventos y (opcionalmente) envían anuncios al corredor, y  los suscriptores envían suscripciones al corredor y reciben notificaciones a cambio. 
  • La interacción con el corredor se realiza a través de una serie de mensajes punto a punto; esto se puede implementar mediante el paso de mensajes o la invocación remota.

Figura 1: Modelo  Publicación-Susbcripción centralizado.


    Este enfoque es sencillo de implementar, pero el diseño carece de resiliencia y escalabilidad, ya que el nodo centralizado representa un punto único de posibles fallas del sistema y es probable que sea un cuello de botella para el rendimiento.

Distribuidas


     En este esquema, el nodo centralizado es reemplazado por una red de corredores que cooperan para ofrecer la funcionalidad deseada. En la visión distribuida, el sistema pub-sub distribuido se implementa como una red de intermediarios o enrutadores en la capa de aplicación que se comunican mediante el uso de las primitivas de capa inferior, normalmente TCP/IP. En la Figura 2 se esquematiza una red pub-sub distribuida donde cada componente de la red de corredores son componentes intermediarios o enrutadores.

    Dicho enfoque tienen el potencial de sobrevivir a las fallas de los nodos y se ha demostrado que pueden funcionar bien en implementaciones a escala de Internet. Como alternativa, es posible tener una implementación completamente nodo-a-nodo (peer-to- peer)  de un sistema de publicación-suscripción. 
    En este enfoque, no hay distinción entre editores, suscriptores y corredores; todos los nodos actúan como intermediarios, implementando de manera cooperativa la funcionalidad de enrutamiento de los eventos requeridos

Figura 2: Publicación-Subscripción distribuido. Tomado de [2]



 Enfoques de Implementación 

Existe una variedad de enfoques de implementación [1] [2]:
  • Inundación (Flooding) el enfoque más simple se basa en Inundación. Opera de la siguiente manera:  
    • Se envía una notificación de evento a todos los nodos de la red y luego se realiza el emparejamiento con el suscriptor del evento. 
    • Como alternativa, la inundación se puede utilizar para enviar suscripciones a todos los posibles publicadores; la coincidencia se realiza en el publicador y los eventos coincidentes se envían directamente a los suscriptores relevantes mediante la comunicación punto a punto. La inundación se puede implementar utilizando una función de difusión o multidifusión subyacente.  
    • Alternativamente, los intermediarios pueden organizarse en un gráfico acíclico en el que cada uno envía notificaciones de eventos entrantes a todos sus vecinos.  
Este enfoque tiene el beneficio de la simplicidad, pero puede resultar en una gran cantidad innecesaria de tráfico de red. 


  • Filtrado : Se conoce como enrutamiento basado en filtrado. Los corredores envían notificaciones a través de la red solo donde hay una ruta a un suscriptor válido. Funciona así: 
    • La propagación de la información de suscripción se realiza a través de la red hacia los editores potenciales y luego se almacena el estado asociado en cada corredor. 
    •  Específicamente, cada nodo debe mantener una lista de vecinos que contenga a todos los vecinos conectados en la red de corredores, una lista de suscripción que contenga todos los suscriptores conectados directamente atendidos por este nodo, y una tabla de enrutamiento. Esta tabla de enrutamiento mantiene una lista de vecinos y suscripciones válidas para ese camino. 
    • Este enfoque exige una implementación de la coincidencia en cada nodo en la red de corredores: en particular, en la función de coincidencia lleva a cabo la notificación de eventos y una lista de nodo junto con la suscripción y las devoluciones asociadas en el conjunto de nodos donde la notificación coincide con la suscripción.  
El algoritmo específico para este enfoque de filtrado se captura en las Figura 3 y opera de la siguiente manera:
  • Cuando un corredor recibe en la solicitud de publicación de un nodo dado, debe pasar esta notificación a todos los nodos conectados donde hay una suscripción con coincidencia al evento y también decide dónde propagar este evento a través de la red de corredores.
  • Las  líneas 2 y 3 logran el primer objetivo al igualar el evento contra la lista de suscripción y luego reenviar el evento a todos los nodos con suscripciones coincidentes (la lista de coincidencias). 
  • Las  líneas 4 y 5 luego usan la función de coincidencia nuevamente, esta vez coincide con el evento contra la tabla de enrutamiento y reenvía solo a las rutas que conducen a una suscripción (la Lista FWD).  
  • Los corredores también deben lidiar con los eventos de suscripción entrantes.  Si el evento de suscripción es de un suscriptor inmediato conectado, entonces esta suscripción se registra en la tabla de suscripciones (líneas 7 y 8).  
  • De  lo contrario, el corredor es un nodo intermediario; Este nodo ahora sabe que existe un camino hacia esta suscripción y, por lo tanto, se agrega una entrada apropiada a la tabla de enrutamiento (línea 9).
  • En ambos casos, este evento de suscripción se pasa a todos los vecinos aparte del nodo de origen (línea 10).
Figura 3: Algoritmo de Filtrado. Tomado de [2]

 

  • Encuentros (Rendezvous) :

Para comprender este enfoque, es necesario ver el conjunto de todos los eventos posibles como un espacio de eventos y dividir la responsabilidad de este espacio de eventos entre el conjunto de agentes de la red. En particular, este enfoque define los nodos de encuentro, que son nodos intermediarios responsables de un subconjunto determinado del espacio de eventos. Para lograr esto, un algoritmo de enrutamiento basado en encuentros debe definir dos funciones: 
    • En primer lugar, SN toma una suscripción determinada, s, y devuelve uno o más nodos de encuentro que asumen la responsabilidad de esa suscripción. Cada uno de estos nodos de encuentro mantiene una lista de suscripción como en el método de filtrado anterior, y reenvía todos los eventos coincidentes al conjunto de nodos de suscripción. 
    • En segundo lugar, cuando se publica un evento e, la función EN(e) también devuelve uno o más nodos de encuentro, esta vez que corresponde a la coincidencia del evento e con las suscripciones en el sistema. 
    • Tenga en cuenta que tanto SN(s) como EN(e) devuelven más de un nodo si la confiabilidad es un problema.  
    • Tenga en cuenta también que este enfoque solo funciona si la intersección de SN(s) y EN(e) no está vacía para una e dada que coincide con s. El código correspondiente para el enrutamiento basado en citas se muestra en la Figura 4. 
Figura 4: Algoritmo de Encuentros. Tomado de [2]

Bibliografia:

[1] Sasu Tarkoma. Publish/Subscribe Systems: Design and Principles. Edited by Joe
Sventek David Hutchison Serge Fdida. 2012. 
[2]  George Coulouris et al. Distributed Systems: Concepts and Design. 5th. USA:
Addison-Wesley Publishing Company, 2011. ISBN: 0132143011 
[3] Roberto Vitillo. Understanding Distributed Systems. 2021

Publicación Suscripción

 Publicación - Suscripción

    Las principales entidades en un sistema publicación-suscripción son los editores y suscriptores de contenido [1]. Un publicador (publisher) detecta un evento y luego lo publica en forma de notificación. Una notificación encapsula información relacionada con el evento observado. La notificación denota que ha ocurrido un evento observado. Un evento representa cualquier transición de estado discreta que ha ocurrido y se señala desde una entidad a un número de otras entidades.

    Un suscriptor, por ejemplo, podría expresar interés en todos los eventos relacionados con este libro de texto, como la disponibilidad de una nueva edición o actualizaciones del sitio web relacionado. La tarea del sistema de publicación y suscripción es hacer coincidir las suscripciones con los eventos publicados y garantizar la entrega correcta de las notificaciones de eventos. Un evento dado se entregará potencialmente a muchos suscriptores y, por lo tanto, en publicación y suscripción se usan paradigmas de comunicaciones de uno a muchos.

Aplicaciones de los sistemas de publicación-suscripción

Los sistemas de publicación-suscripción se utilizan en una variedad de dominios de aplicación, en particular los relacionados con la difusión de eventos a gran escala. Ejemplos  incluyen [1]:

  • GUI, en las que los sistemas pub/sub se aplica como el pegamento que conecta los diversos componentes entre sí. Un ejemplo es el patrón de diseño MVC (Modelo Vista Controlador) muy utilizado en GUIs y su componente el patrón de observador.  
  • Push de información, en el que se publica el contenido al usuario. Este es un requisito para aplicaciones que dependen de datos en tiempo real o casi en tiempo real. 
  • Filtrado de información y entrega dirigida utilizada por los servicios de alerta y presencia (Google Alerts, etc.), tiendas de aplicaciones, servicios de corretaje de RSS, etc. Los ejemplos incluyen XMPP Pub/sub, Pubsubhubbub, Facebook  Messenger and Chat y Twitter.  
  • Plano de señalización, en el que pub/sub asegura que los eventos asíncronos se entregan en en tiempo real o casi en tiempo real desde la publicación de componentes hasta la suscripción de componentes. Las aplicaciones de ejemplo incluyen sistemas industriales y tácticos. DDS (Data Distribution Systems) es el estándar clave para estos sistemas.  
  • La arquitectura orientada a servicios (SOA) y las aplicaciones comerciales se basan en publicación/suscripción en el bus de servicios empresariales (ESB). El ESB normalmente se implementa con un broker de mensaje XML.  
  • Procesamiento de Eventos Complejos (CEP) para análisis de datos. CEP se utiliza ampliamente en varios aplicaciones comerciales, por ejemplo, comercio algorítmico y detección de fallas. 
  • Computación en la nube, en la que pub/sub y colas de mensajes se utilizan para conectar los componentes de la nube. 
  • Internet de las cosas, en el que pub/sub conecta los sensores y actuadores entre sí con recursos de Internet.  
  • Juegos multijugador en línea, en los que pub/sub se usa para sincronizar el estado del juego en jugadores y servidores

Modelo de Programación

    El modelo de programación en los sistemas de publicación-suscripción se basa en un pequeño conjunto de operaciones, ver Figura 1. Los editores difunden un evento e a  través de una operación de publicacion(e) y los suscriptores expresan su interés en un conjunto de eventos a través de suscripciones. En particular, logran esto a través de una operación de suscripcion( f ) donde f se refiere a un filtro, es decir, un patrón definido sobre el conjunto de todos los eventos posibles.

Figura 1: Paradigma Publicación Suscripción



    La expresividad de los filtros está determinada por modelo de la suscripción. Los suscriptores pueden revocar este interés mediante la correspondiente operación de cancelacion−suscripcion( f ). Cuando los eventos llegan a un suscriptor, los eventos se entregan usando una operación de notificacion(e).

    Algunos sistemas complementan el conjunto de operaciones anuncios. Con los anuncios, 
los editores tienen la opción de declarar la naturaleza de los eventos futuros a través de una operación de anuncios( f ). 

Modelo de Subscripción 

    La expresividad de los sistemas de publicación-suscripción está determinada por el modelo de suscripción, que cuentan con una serie de esquemas o filtros [1] [2]:

  • Basado en canales : en este enfoque, los editores publican eventos en canales con nombre y los suscriptores luego se suscriben a uno de estos canales para recibir todos los eventos enviados a ese canal. Este esquema es el único que se define en un canal físico. 
  • Basado en temas : se asume que cada notificación se expresa en términos de varios campos, con un campo que denota el tema. Las suscripciones se definen en función del tema de interés. Este enfoque es equivalente a los enfoques basados en canales con la diferencia de que los temas se definen implícitamente, pero se declaran como parte de un campo en el enfoque basados en temas. 
  • Basado en contenidos : son una generalización de enfoques basados en temas que permiten la expresión de suscripciones en una variedad de campos en solo una notificación del evento. Más específicamente, un filtro basado en contenido es una consulta definida en términos de composiciones de restricciones sobre los valores de los atributos del evento. Por ejemplo, un suscriptor podría expresar interés en eventos relacionados con el tema de los sistemas de publicación-suscripción, donde el sistema en cuestión es el Servicio de eventos CORBA y el autor es Tim Kindberg o Gordon Blair.  
  • Basado en tipo : las suscripciones se definen en términos de tipos de eventos y la coincidencia se define en términos de tipos o subtipos del filtro dado. Este enfoque puede expresar una variedad de filtros, desde un filtrado basado en nombres de tipo generales hasta consultas más detalladas que definen atributos y métodos de un objeto dado. Estos filtros detallados son similares en expresividad a los enfoques basados en contenido.

Bibliografia:

[1] Sasu Tarkoma. Publish/Subscribe Systems: Design and Principles. Edited by Joe
Sventek David Hutchison Serge Fdida. 2012. 
[2]  George Coulouris et al. Distributed Systems: Concepts and Design. 5th. USA:
Addison-Wesley Publishing Company, 2011. ISBN: 0132143011 
[3] Roberto Vitillo. Understanding Distributed Systems. 2021

Grupos

 Grupos.

    La comunicación grupal es una abstracción sobre la comunicación de multidifusión y se
puede implementar a través de multidifusión IP o una red de superposición equivalente,
teniendo como valor adicional la gestión de pertenencia al grupo, detección de fallas y
garantía de confiabilidad y pedidos, [1] [2].

Modelo de Programación

    En la comunicación grupal, el concepto central es el de un grupo con una membresía de
grupo asociada y con los procesos de unirse o salir del grupo ver Figura 1. Los procesos pueden enviar un mensaje a este grupo y hacer que se propague a todos los miembros (o a un miembro) del grupo con ciertas garantías en términos de confiabilidad y orden. Así, la comunicación de grupo implementa la comunicación de multidifusión, así como también la comunicación unidifusión.


    El uso de una única operación de envío permite un uso eficiente del ancho de banda. También es relevante en términos de garantías de entrega del mensaje ya que la operación de envío del mensaje se asocia a un proceso. Si ocurre una falla y algún mensaje no se entrega, se puede implementar el reenvio de mensajes. 

Figure 1: Modelo de Programación. Adaptado de [2]



 Membresía del Grupo

Un servicio de membresía grupal tiene cuatro tareas principales:
  • Interfaz para cambios de membresía de grupo : el servicio de membresía proporciona operaciones para crear/destruir grupos de procesos y para agregar/retirar un proceso hacia o desde un grupo. En la mayoría de los sistemas, un solo proceso puede pertenecer a varios grupos al mismo tiempo (grupos superpuestos ).  
  • Detección de fallas : el servicio monitorea a los miembros del grupo no solo en caso de que se bloqueen, sino también en caso de que se vuelvan inaccesibles debido a una falla de comunicación. El detector marca los procesos como sospechosos o no sospechosos. El servicio utiliza el detector de fallas para tomar una decisión sobre la situación de la membresía del grupo: excluye un proceso de la membresía si se sospecha que ha fallado o si se ha vuelto inalcanzable. 
  • Notificación de cambios en la membresía del grupo : el servicio notifica al los miembros del grupo cuando se agrega un proceso, o cuando se excluye un proceso (por falla o cuando el proceso se retira deliberadamente del grupo). 
  • Difusión de direcciones de grupo : cuando un proceso difunde un mensaje en forma múltiple, proporciona el identificador de grupo en lugar de una lista de procesos del grupo. El servicio de administración de membresía expande el identificador a la membresía del grupo actual para su entrega. El servicio puede coordinar la entrega de multidifusión con cambios de membresía controlando la expansión de direcciones. Es decir, puede decidir sistemáticamente dónde enviar un mensaje determinado, aunque la membresía pueda cambiar durante la entrega

Características de la arquitectura de Grupos

  • Grupos de procesos La mayor parte del trabajo en servicios grupales se centra en grupos donde las entidades comunicantes son Procesos. El nivel de servicio proporcionado por los grupos de procesos es similar al de los sockets. 
  • Grupos de objetos Es una colección de objetos (instancias de la misma clase) que procesan el mismo conjunto de invocaciones al mismo tiempo, y cada una devuelve respuestas. Los clientes invocan operaciones en un único objeto local, que actúa como proxy del grupo. El proxy utiliza un sistema de comunicación grupal para enviar las invocaciones a los miembros del grupo de objetos. Los parámetros de objeto y los resultados se empaquetan como en RMI y las llamadas asociadas se envían automáticamente a los objetos/métodos de destino. 
  • Grupos abiertos Un grupo está abierto si los procesos fuera del grupo pueden enviarle mensajes, Figura 2. Los grupos abiertos son útiles, por ejemplo, para entregar mensajes a grupos de procesos interesados.  
  • Grupos cerrados Se dice que el grupo está cerrado si solo los miembros del grupo pueden enviar mensajes multidifusión. Un proceso en un grupo cerrado se entrega a sí mismo cualquier mensaje que difunde al grupo, ver Figura 2. Los grupos cerrados de procesos son útiles, por ejemplo, para servidores que cooperan para enviarse mensajes entre sí que solo ellos deberían recibir.  
  • Grupos Superpuestos Entidades (procesos u objetos) pueden ser miembros de varios grupos  
  • Grupos no Superpuestos Implican que la membresía no se superpone (es decir, cualquier proceso pertenece como máximo a un grupo)
Figure 2: Grupos cerrados y abiertos. Adaptado de [2]



Confiabilidad y ordenamiento en multidifusión

Otras características atribuida a los grupos esta la confiabilidad y el ordenamiento de los
mensajes:
  • Confiabiliad La confiabilidad en la comunicación se ha definido en términos de las siguientes propiedades:
    • Integridad El mensaje recibido es el mismo que el enviado, y no se entregan dos veces. Validez Cualquier mensaje saliente es eventualmente entregado. La interpretación de multidifusión confiable se basa en estas propiedades, con integridad definida en términos de entregar el mensaje correctamente como máximo una vez, y la validez interpretado como que garantiza que un mensaje enviado finalmente será entregado. 
    • Acuerdo Para extender la semántica y cubrir la entrega a múltiples receptores, la propiedad acuerdo indica que si el mensaje se entrega a un proceso, entonces se entrega a todos los procesos del grupo. 
  • Ordenamiento Además de las garantías de fiabilidad, la comunicación grupal exige garantías adicionales en términos del orden relativo de los mensajes entregados a múltiples destinos. Para contrarrestar los retrasos y desorden en la entrega, los servicios de comunicación grupal ofrecen multidifusión ordenada, con la opción de una o más de las siguientes propiedades: 
    • Orden FIFO : ordenamiento primero en entrar, primero en salir (FIFO) se ocupa de preservar el pedido desde la perspectiva del remitente del proceso, en el sentido de que si un proceso envía un mensaje antes que otro, se entregará en este orden en todos los procesos del grupo.  
    • Ordenamiento causal : el ordenamiento causal tiene en cuenta las relaciones causales entre mensajes, en el sentido de que si un mensaje ocurre antes que otro mensaje en el sistema distribuido, esta relación causal se conservará en la entrega de los mensajes asociados en todos los procesos  
    • Ordenamiento total : En el orden total, si un mensaje se entrega antes que otro mensaje en un proceso, se conservará el mismo orden en todos los procesos.

Bibliografia:

[1] M van Steen and A.S. Tanenbaum. Distributed Systems. Edited by Pearson Prentice
Hall. Third. distributed-systems.net, 2017 
[2]  George Coulouris et al. Distributed Systems: Concepts and Design. 5th. USA:
Addison-Wesley Publishing Company, 2011. ISBN: 0132143011 
[3] Roberto Vitillo. Understanding Distributed Systems. 2021

Comunicación Indirecta.

Comunicación Indirecta. 

    En la comunicación indirecta la naturaleza del intermediario y del acoplamiento varían de
un enfoque a otro y entre sistemas: se puede establecer conceptos de acoplamiento tanto
temporal como espacial que determinan como el receptor y el emisor coinciden o no en el
tiempo y en espacio.

    En la tabla 1 se plasman las posibles variantes en este tipo de enfoque. Por ejemplo,
las técnicas consideradas hasta ahora se basan en un acoplamiento directo o sistemas fuertemente
acoplado, como las arquitecturas clientes-servidor. Son arquitecturas acopladas en tiempo y espacio. Por otra parte, las aplicaciones como el correo electrónico, son arquitecturas desacopladas en tiempo y acopladas en espacio, ver descripción en la parte superior, derecha de la tabla 1.

Tabla 1. Acoplamiento en Espacio y Tiempo. Adaptado de [2]



    Mientras que la multidifusión puede catalogarse como arquitecturas acoplada en tiempo,
desacopladas en espacio, descrita en la parte inferior e izquierda de la tabla 1. Y las arquitecturas que calzan en la categoría de desacoplamiento en espacio y tiempo, como las arquitecturas Pub-sub y colas de mensajes, ubicada en la parte inferior, derecha.

Acoplamiento

    El acoplamiento se define como la fuerza de la interconexión entre dos módulos de software:
cuanto mayor es la fuerza de la interconexión, mayor es el acoplamiento. Para que el software sea más fácil de entender, corregir y mantener, un sistema debe estar dividido de modo que el acoplamiento entre los módulos sea lo más flojo o débil posible.

    Un sistema débilmente acoplado es aquel sistema donde  cada componente tiene poco o ningún conocimiento de las partes internas de los otros componentes. Por su parte,  el sistema tiene acoplamiento fuerte si cada componente de un sistema tiene conocimiento de partes de los otros componentes, como memoria común, almacenamiento secundario, entrada y salida de datos.

    El concepto de Acoplamiento fue propuesto por Yourdon y Constantine en su libro,
Structured Design: Fundamentals of a Discipline of Computer Program and Systems
Design.


Bibliografia:

[1] M van Steen and A.S. Tanenbaum. Distributed Systems. Edited by Pearson Prentice
Hall. Third. distributed-systems.net, 2017 
[2]  George Coulouris et al. Distributed Systems: Concepts and Design. 5th. USA:
Addison-Wesley Publishing Company, 2011. ISBN: 0132143011 
[3] Roberto Vitillo. Understanding Distributed Systems. 2021