Cómo los nodos se ponen de acuerdo — la maquinaria detrás de Kafka, etcd y ZooKeeper
// Twitter Snowflake (2010) — ID de 64 bits ordenable // | 41 bits timestamp ms | 10 bits node ID | 12 bits sequence | // → ~4100 años · 1024 nodos · 4096 IDs/ms/nodo long snowflakeId = ((long) timestampMs << 22) | ((long) nodeId << 12) | sequence; // UUID v7 (2022, RFC 9562) — equivalente estándar moderno // | 48 bits unix_ts_ms | 4 bits version | 12 bits rand | 62 bits rand | // → lexicográficamente ordenable + incluye timestamp // En Java: use UUID7 via com.fasterxml.uuid UUID id = Generators.timeBasedEpochGenerator().generate(); // Ordenable en BD: INSERT ORDER ≈ CHRONOLOGICAL ORDER → menos fragmentación
| Sistema | Algoritmo/Modelo | Garantías | Cuándo usarlo |
|---|---|---|---|
| ZooKeeper | ZAB (Zookeeper Atomic Broadcast) ≈ Raft | CP · Linearizable · Quórum de mayoría | Configuración distribuida, leader election, service discovery (legado) |
| etcd | Raft | CP · Linearizable · MVCC | Config store de Kubernetes, distributed locks, feature flags críticos |
| Redis (Redlock) | Quórum sobre N instancias independientes | Eventual · No linearizable bajo fallo asimétrico | Locks de baja criticidad, idempotency keys, rate limiting. No usar para casos donde la correctitud es crítica. |
| Kafka | KRaft (Raft) · ISR quórum | CP por partición · At-least-once por defecto · Exactly-once con transacciones | Log de eventos, streaming, event sourcing. Orden garantizado dentro de partición. |
| Cassandra | Gossip + Dynamo-style quórum | AP por defecto · Tunable (ONE/QUORUM/ALL) | Escrituras masivas, series de tiempo, disponibilidad > consistencia |
// Redlock sobre Redis — útil para secciones críticas de baja duración // No usar para decisiones de alta integridad (ej: pagos) → usar etcd/ZooKeeper @Service public class InventoryService { private final RedissonClient redisson; public void reserveItem(String itemId) { RLock lock = redisson.getLock("inventory:lock:" + itemId); boolean acquired = lock.tryLock(3, 10, TimeUnit.SECONDS); // waitTime=3s, leaseTime=10s (auto-release ante crash) if (!acquired) throw new ConcurrentModificationException(); try { updateInventory(itemId); // sección crítica } finally { if (lock.isHeldByCurrentThread()) lock.unlock(); } } } // leaseTime previene deadlock si el proceso muere sin hacer unlock // isHeldByCurrentThread() previene unlock de lock expirado (race condition)
ConsistentRead=true: strongly consistent (R=mayoría, doble costo de lectura). Para transacciones multi-item: serializable via 2-phase commit interno. Ninguna es linearizable — DynamoDB prioriza latencia baja.