Apuntes de clase — Miércoles 30 de septiembre de 2026
Contexto: Sistemas Distribuidos e IoT. Inicio del Bloque 2, con una sesión centrada en replicación, escalabilidad y consistencia.
La clase desarrolla cómo las copias de los datos pueden aumentar la capacidad de lectura y ayudar a mantener el servicio cuando falla una máquina. El coste aparece al escribir: las réplicas deben coordinarse y un cliente puede encontrarse con versiones distintas del mismo dato. El desarrollo ordenado del bloque está en Elasticidad y escalabilidad.
1. Escalabilidad y elasticidad
La scalability (escalabilidad) describe la capacidad de atender más carga al añadir recursos. La carga puede medirse como peticiones por unidad de tiempo, almacenamiento u otra métrica pertinente. En un caso ideal, duplicar las máquinas duplicaría la capacidad; en la práctica el crecimiento suele ser inferior porque quedan operaciones secuenciales, recursos compartidos o cuellos de botella.
La fracción serie de una aplicación es la parte que no puede ejecutarse en paralelo. Aunque el sistema tenga varios procesadores, esa parte sigue limitando cuánto mejora el rendimiento. También puede limitarlo una decisión de diseño o una implementación que no aprovecha los recursos disponibles. Este concepto se relaciona con la clasificación MIMD vista en la clase del 14 de septiembre.
La elasticity (elasticidad) añade la idea de ajustar la capacidad a la demanda: aumentar recursos cuando sube la carga y retirarlos cuando baja. El ajuste puede afectar a máquinas virtuales, contenedores, procesos worker o conexiones. Para que el sistema siga la demanda, el ajuste debe llegar a tiempo; poder añadir una máquina después de varias horas no resuelve un pico que dura unos minutos.
2. Qué aporta la replicación y qué problema introduce
La replication (replicación) mantiene el mismo dato en varias máquinas. Las copias permiten acercar las lecturas a los clientes, repartir solicitudes y conservar datos disponibles si una máquina falla. En el ejemplo de clase, un cliente puede consultar una réplica cercana en Tokio en vez de esperar a una copia situada en Madrid o Bogotá.
Las lecturas son relativamente sencillas de repartir porque no modifican el dato. Las escrituras sí requieren coordinación: una copia puede haberse actualizado y otra conservar todavía el valor anterior. Por eso, la replicación no consiste únicamente en guardar varias copias; el sistema debe decidir cómo se propagan las escrituras y qué versión puede observar cada cliente.
Actualización perdida
Supongamos que una cuenta tiene 200 € y llegan dos operaciones concurrentes, cada una para incrementar el saldo un 10 %. Si se ejecutan en orden, el saldo pasa de 200 a 220 € y después a 242 €. Si ambas operaciones leen 200 antes de escribir, las dos calculan 220; una escritura puede sobrescribir la otra y dejar el saldo en 220 €.
El estado final puede parecer válido y no generar un error técnico. Sin embargo, se ha perdido una actualización. En sistemas distribuidos, la demora de red hace que estas intercalaciones sean normales y hay que tratarlas explícitamente.
3. Réplica primaria y propagación de escrituras
Una estrategia es designar una primary replica (réplica primaria) para recibir y ordenar las escrituras. El primario asigna versiones u otro identificador ordenable y propaga cada cambio a las demás réplicas. Esto reduce el riesgo de que varias copias acepten escrituras incompatibles, aunque concentra la capacidad de escritura en el primario.
| Propagación | Comportamiento | Coste o riesgo |
|---|---|---|
| Síncrona | El primario espera confirmaciones de las réplicas requeridas antes de confirmar la escritura al cliente. | Aumenta la latencia; una réplica lenta o inaccesible puede retrasar la operación hasta el timeout. Una lectura posterior puede ver el valor recién escrito si se confirmó que todas las copias consultables exigidas están al día. |
| Asíncrona | El primario confirma sin esperar a que todas las réplicas reciban el cambio. | La escritura responde antes, pero puede haber replication lag: una lectura desde una copia retrasada devuelve un valor antiguo. Si el primario falla antes de propagar el cambio, la actualización puede perderse. |
Con propagación asíncrona, una aplicación puede dirigir al primario las lecturas que deban ver inmediatamente una escritura reciente, en particular las del cliente que acaba de escribir. Las demás lecturas pueden aceptar una versión temporalmente antigua solo si el comportamiento de la aplicación lo permite.
Un timeout no permite saber por sí solo si el servidor remoto está caído o simplemente responde con lentitud. Repetir cada petición de inmediato puede cargar aún más la red y los servidores. La clase relacionó este problema con las colisiones de Ethernet: los reintentos deben limitarse y espaciarse, por ejemplo con esperas crecientes y variación aleatoria, para reducir nuevas colisiones.
4. Locks, espera e interbloqueos
Un lock (bloqueo) concede acceso exclusivo a un dato o recurso mientras se ejecuta una sección crítica. Si una escritura ya tiene el bloqueo, otra escritura espera en una cola. Así se evita que ambas operaciones modifiquen simultáneamente el mismo valor, pero aumenta la espera y puede reducir el rendimiento.
Puede aparecer un deadlock (interbloqueo) cuando dos operaciones retienen recursos que la otra necesita. Por ejemplo, T mantiene bloqueado A y espera B, mientras U mantiene B y espera A. El ciclo de espera impide que ninguna continúe.
Dos enfoques mencionados en clase son:
- Prevenir el ciclo: limitar los recursos que puede pedir una operación o imponer un orden global para solicitarlos, por ejemplo, siempre pedir primero la tabla
alumnosy despuésprofesores. - Detectar y resolverlo: construir o analizar el grafo de espera y abortar una operación cuando se detecta un ciclo. La operación abortada debe poder volver a un estado seguro y reintentarse.
Si una operación se reintenta tras un conflicto, usar siempre la misma espera puede hacer que vuelva a coincidir con otra. Una espera aleatoria y creciente reduce esa posibilidad, aunque los reintentos deben tener límites y una política de recuperación.
5. Control optimista por versiones
El optimistic concurrency control (control optimista de concurrencia) permite que las operaciones lean y calculen sin bloquearse de antemano. Cada dato tiene una versión. Al escribir, el cliente indica la versión sobre la que calculó el nuevo valor; el servidor acepta la operación solo si esa versión sigue siendo la actual.
Si dos operaciones leen el valor 200 en la versión 7, la primera puede guardar 220 como versión 8. Cuando la segunda intenta escribir su resultado calculado desde la versión 7, el servidor la rechaza porque el dato ya está en la versión 8. El cliente vuelve a leer, recalcula sobre el valor vigente y reintenta.
Este método evita mantener bloqueos mientras se calcula y funciona bien cuando los conflictos son poco frecuentes. Si muchos escritores compiten por el mismo dato, habrá más rechazos y cálculos repetidos.
6. Quórums y resolución de cambios concurrentes
En un sistema de quorum (quórum), el diseñador define:
N: número de réplicas.W: confirmaciones que debe reunir una escritura.R: respuestas que debe reunir una lectura.
Cuando R + W > N, cualquier conjunto de R réplicas consultadas y cualquier conjunto de W réplicas que confirmó la escritura comparten al menos una réplica. Por ejemplo, con N = 5, R = 3 y W = 3, ambos conjuntos se solapan. El sistema puede comparar versiones y escoger la más reciente. El solapamiento por sí solo no define toda la consistencia: también importa cómo se ordenan las versiones y se reparan las copias.
Con valores de R y W cuya suma no supera N, los conjuntos pueden no solaparse, por lo que la lectura podría devolver un valor antiguo. El número de respuestas exigido intercambia latencia y disponibilidad por garantías de lectura; la elección depende del efecto que tendría un dato desactualizado en la aplicación.
La clase ilustró también la fusión de versiones con un carrito de compra replicado. Unir los elementos presentes en dos copias puede conservar adiciones concurrentes, pero una eliminación requiere recordar que el elemento se borró. Esa marca se denomina tombstone: si se elimina antes de que las demás réplicas conozcan el borrado, una copia antigua podría hacer reaparecer el elemento.
No hay una política adecuada para todos los datos. Una aplicación que recoge temperaturas frecuentes puede tolerar pequeñas diferencias temporales; un saldo bancario o un sistema crítico necesita garantías acordes con las consecuencias de un valor incorrecto. La consistencia aceptable forma parte de los requisitos de la aplicación.
Ideas clave
- La replicación puede mejorar lecturas y tolerancia a fallos, pero hace que las escrituras y la consistencia requieran coordinación.
- Un valor incorrecto puede quedar almacenado sin que haya un fallo técnico visible; la actualización perdida del saldo es un ejemplo.
- Réplica primaria, locks, control optimista y quórums ofrecen distintos intercambios entre latencia, capacidad, disponibilidad y consistencia.
- Las lecturas antiguas y la fusión de cambios solo son aceptables cuando la aplicación puede manejarlas.
Continuación anunciada
El docente indicó que la siguiente sesión continuará con sharding y recordó al grupo B el laboratorio del día siguiente.