Skip to content

Apuntes de clase — Miércoles 14 de octubre de 2026 ​

Hashing distribuido, publicación/suscripción, multicast y primeros pasos con MPI ​

Contexto: Sistemas Distribuidos e IoT. La sesión repasa el consistent hashing, continúa con redes P2P, presenta publish/subscribe y MQTT, y termina con una introducción a la práctica 3 con MPI.

1. Hash distribuido en redes dinámicas ​

En una red distribuida, una función hash aplicada a la IP (o identificador) de una máquina determina su posición lógica; aplicada a una clave, ayuda a decidir dónde se almacenan sus datos. La clave debe identificar suficientemente el registro: un DNI puede ser único, mientras que un país puede corresponder a muchos registros y devolver un conjunto.

El esquema visto anteriormente asumía máquinas relativamente estables y una entidad que mantiene el mapa de la red. En redes abiertas o P2P —se citan Core y BitTorrent— los equipos entran y salen sin un administrador central que actualice continuamente una tabla global. Las máquinas se ordenan en un anillo lógico por su hash, aunque físicamente estén en cualquier lugar.

1.1. Finger table y coste de búsqueda ​

Si cada nodo solo conoce al sucesor, una búsqueda recorre en promedio aproximadamente N/2 nodos; en una red con un millón de participantes no es práctico. La finger table conserva referencias a nodos a distancias crecientes, normalmente potencias de dos: 1, 2, 4, 8, … saltos. Para 8 nodos bastan tres entradas para cubrir esas distancias.

Al buscar una clave, el nodo reenvía la petición al nodo conocido más próximo que no sobrepase la clave buscada. Por ejemplo, desde el nodo 0, para localizar la clave 7 se salta al 4; desde allí, entre las referencias 5, 6 y 0 se elige 6; el nodo 6 puede resolver la clave 7 en su sucesor. Así se reduce el recorrido a un número de saltos del orden de log₂(N), frente al recorrido lineal del anillo. Para un millón de nodos, la exposición compara alrededor de 20 saltos con medio millón en promedio; son cifras aproximadas del ejemplo.

1.2. Entrada, salida y consistencia eventual ​

Cuando una máquina entra, calcula su posición y se incorpora junto a su sucesor. El nodo que antes apuntaba directamente a ese sucesor puede quedar desactualizado. Los nodos consultan periódicamente a sus vecinos —por ejemplo, preguntan quién es el predecesor del sucesor— y actualizan sus referencias cuando detectan cambios.

Esta convergencia no es instantánea. Durante un intervalo puede haber referencias antiguas y alguna consulta puede dirigirse a un nodo que todavía no tiene la clave. El periodo de refresco es un compromiso: refrescar demasiado a menudo consume ancho de banda y recursos; hacerlo muy poco deja la estructura obsoleta durante más tiempo. La red no ofrece una vista global perfecta del estado de cada nodo, y los protocolos deben tolerar retrasos, fallos y mensajes perdidos.

La clase recuerda que la búsqueda de claves no reemplaza la replicación. Puede haber varias copias —se mencionan habitualmente tres en el ejemplo— para que la caída de uno o dos nodos no implique perder los datos. Las copias pueden reconstruirse o redistribuirse cuando los nodos vuelven. Ningún nivel finito de réplicas garantiza tolerar cualquier número de fallos; la disponibilidad y durabilidad son propiedades probabilísticas y de diseño.

2. De sockets a publicación/suscripción ​

Con sockets, dos procesos deben estar activos y conectados para intercambiar mensajes. El emisor conoce el destino y el mensaje puede esperar temporalmente en buffers mientras cruza la red. En IoT interesa reducir ese acoplamiento: no exigir que emisor y receptor coincidan en el tiempo ni que cada emisor conozca las direcciones de todos los receptores.

El patrón publish/subscribe introduce un broker. Los productores publican mensajes asociados a un tópico; los consumidores se suscriben a los tópicos que les interesan. El broker recibe, conserva o distribuye los mensajes según la configuración del sistema. El productor necesita conocer el broker y el contrato del mensaje, no las direcciones de cada consumidor.

Una cola y un tópico tienen semánticas distintas:

PatrónQué ocurre con un mensajeUso típico
Cola de trabajoUn consumidor lo retira y lo consume; los demás no reciben esa misma instanciaRepartir tareas entre trabajadores
Tópico pub/subEl mensaje se distribuye a los suscriptores que coinciden con el tópicoDifundir una actualización o un evento a varios servicios

La clase advierte que un tópico no coordina por sí solo el reparto exclusivo de trabajo: si cincuenta consumidores están suscritos, pueden ejecutar todos la misma tarea. Para tareas compartidas hace falta una cola o un protocolo de coordinación apropiado.

El broker añade una dependencia central del flujo. Si cae, los productores y consumidores pueden perder conectividad o acumular mensajes según la configuración. En sistemas de negocio se preparan réplicas y mecanismos de conmutación por error; una interrupción prolongada puede, por ejemplo, dejar desactualizados los precios que consultan los carritos de compra. La redundancia y la recuperación también requieren diseño y operación.

2.1. Tópicos jerárquicos y filtros de MQTT ​

Los tópicos se organizan como rutas jerárquicas separadas por niveles, por ejemplo ciudad/ruido/sensor-7/raw. Los suscriptores usan filtros. En MQTT, + ocupa un único nivel y # puede abarcar los niveles restantes (y debe colocarse al final del filtro).

Ejemplos conceptuales:

  • ciudad/ruido/+ coincide con un nivel después de ciudad/ruido, como ciudad/ruido/sensor-7.
  • ciudad/# coincide con los tópicos bajo ciudad, incluidos los niveles descendientes.
  • ciudad/ruido/sensor-7 solo coincide con ese tópico exacto.

Los tópicos pueden ser cadenas que el sistema acepta al publicarse, o pueden estar sujetos a un catálogo/contrato más estricto. En ambos casos, emisores y consumidores necesitan acordar nombres y estructura del contenido.

2.2. QoS y mensajes de última voluntad ​

La clase presenta los tres niveles de QoS de MQTT como opciones según el coste de pérdida o duplicación:

QoSGarantía conceptualConsecuencia
0At most once: el emisor entrega una vez sin confirmación de entregaPuede perderse; adecuado para medidas periódicas cuya siguiente muestra reemplaza a la anterior
1At least once: se reintenta hasta recibir confirmaciónLlega, pero puede entregarse más de una vez; el consumidor debe tolerar duplicados
2Exactly once en el intercambio MQTT de esa entregaRequiere más mensajes/protocolo y coste; evita procesar dos veces la misma entrega dentro de las garantías del protocolo

La elección depende del dato. Perder una lectura ambiental periódica puede ser aceptable; para una medida crítica, como la temperatura de un núcleo de reactor en el ejemplo docente, se necesita más fiabilidad y probablemente QoS 1 o 2, además de controles de aplicación adecuados.

También se explica el Last Will and Testament (LWT): al conectarse, un cliente registra un mensaje que el broker publicará para sus suscriptores si detecta que la conexión del cliente termina de forma inesperada. Sirve para comunicar que un dispositivo desapareció o dejó de estar disponible.

3. Multicast frente a replicación y flooding ​

Enviar por unicast el mismo archivo a diez receptores requiere que el emisor transmita diez copias por su enlace de acceso. Con multicast, el emisor envía una copia al grupo y los routers replican el tráfico solo en las ramas que conducen a miembros del grupo. Los routers necesitan mantener información de qué grupos se alcanzan por cada interfaz.

Los hosts pueden anunciar su pertenencia a grupos multicast mediante IGMP (Internet Group Management Protocol); los routers también necesitan protocolos de encaminamiento multicast para construir la distribución entre ellos. La clase usa la televisión/streaming como ejemplo: un receptor se une al grupo del canal que quiere recibir.

Una alternativa conceptual es flooding: cada router retransmite el paquete por todos sus enlaces salvo aquel por el que llegó. Puede difundir información sin conocer de antemano todos los destinos, pero replica mucho tráfico y no equivale a la distribución selectiva de multicast.

La sesión cierra esta comparación distinguiendo acoplamiento temporal y espacial: una cola requiere conocer el punto de acceso y sus consumidores toman mensajes cuando están disponibles; multicast se dirige a un grupo y los receptores deben estar activos para recibir; pub/sub permite desacoplar productores y consumidores mediante el broker y los tópicos, a cambio de operar esa infraestructura. Los servicios de conveniencia trasladan complejidad a los protocolos y a quienes mantienen la plataforma.

4. Introducción a MPI para la práctica 3 ​

MPI (Message Passing Interface) permite ejecutar un mismo programa en varios procesos y ofrece operaciones de comunicación y coordinación. A diferencia de un fork que identifica procesos mediante PID del sistema operativo, MPI asigna a cada proceso un rank dentro de un comunicador. En el comunicador habitual MPI_COMM_WORLD, los ranks van de 0 a size - 1; size es el número total de procesos.

La clase anuncia para la práctica un ejemplo sencillo de anillo y repasa el esqueleto de un programa MPI en C:

  1. Incluir mpi.h y las cabeceras necesarias, como stdio.h.
  2. Llamar a MPI_Init antes de usar otras operaciones de MPI.
  3. Obtener el rank con MPI_Comm_rank y el tamaño con MPI_Comm_size, usando MPI_COMM_WORLD.
  4. Cada proceso ejecuta el mismo cuerpo, pero puede actuar de forma distinta según su rank. Como ejemplo, cada proceso calcula el cuadrado de su rank.
  5. Usar comunicaciones punto a punto (MPI_Send/MPI_Recv) cuando corresponda, o una operación colectiva como MPI_Reduce para combinar valores de varios procesos. La suma de los cuadrados es el ejemplo explicado; también existen operaciones como mínimo y máximo.
  6. Limitar la salida para evitar que las impresiones concurrentes se mezclen; el orden de ejecución y de salida no está garantizado. El ejemplo imprime el resultado agregado desde rank 0.
  7. Cerrar el entorno con MPI_Finalize.

La reducción ilustra una operación colectiva: cada proceso aporta un valor y el grupo aplica una operación, como suma, para producir un resultado. Es una abstracción de alto nivel que oculta el protocolo de intercambio necesario. La sesión también recuerda que existen variantes bloqueantes y no bloqueantes de comunicación, cuyos parámetros y efectos deben revisarse en el material de la práctica.

El lanzamiento se hace con el ejecutor de MPI y un número de procesos solicitado. La salida puede aparecer en distinto orden; si todos imprimen, conviene incluir el rank y entender que las operaciones de impresión pueden intercalarse. La transcripción no permite recuperar con fiabilidad todos los comandos ni la grafía exacta de algunas funciones mencionadas; por ello estos apuntes registran el flujo, no un listado de comandos ejecutables.

Ideas clave ​

  • El consistent hashing ubica nodos y claves en un anillo lógico; las finger tables reducen búsquedas de coste lineal a coste logarítmico aproximado.
  • Las redes dinámicas convergen con actualizaciones periódicas y requieren asumir fallos, retrasos y replicación.
  • Colas y tópicos resuelven necesidades distintas: consumo exclusivo de tareas frente a difusión a suscriptores.
  • MQTT ofrece filtros jerárquicos, distintos niveles QoS y LWT; cada opción tiene coste y semántica propios.
  • Multicast distribuye a grupos replicando en routers; flooding replica indiscriminadamente.
  • MPI identifica procesos por rank en un comunicador y ofrece comunicación punto a punto y operaciones colectivas como MPI_Reduce.

Referencias relacionadas ​

Nota sobre la fuente ​

Apuntes elaborados a partir de clase-iot-1410.json (audio de unos 67 min 57 s según la marca temporal del archivo). La transcripción automática altera repetidamente siglas y nombres de API; se han normalizado términos inequívocos como finger table, MQTT, QoS, IGMP y MPI. Se omiten pasajes logísticos o ininteligibles y no se reconstruyen comandos MPI que no se oyen con claridad.