{"schemaVersion":1,"id":"https://lucioduran.com/es/blog/consensus-algorithms-raft-paxos-viewstamped","url":"https://lucioduran.com/es/blog/consensus-algorithms-raft-paxos-viewstamped","title":"Algoritmos de Consenso Comparados: Raft, Multi-Paxos, Viewstamped Replication y EPaxos","description":"Comparación enfocada en implementación de algoritmos de consenso distribuido, Raft, Multi-Paxos, Viewstamped Replication y EPaxos, cubriendo elección de líder, compactación de log, garantías de liveness, y los matices que sólo aparecen cuando los construís.","language":"es","datePublished":"2025-10-28","dateModified":"2026-11-10","contentFormat":"text/markdown","content":"Distributed Systems\n\n# Algoritmos de Consenso Comparados: Raft, Multi-Paxos, Viewstamped Replication y EPaxos\n\n2025-10-28Actualizado: 2026-11-1010 min lectura\n\n[Lucio Durán](<https://lucioduran.com/es>)\nC.T.O. en LOi\n\nTambién disponible en: [English](<https://lucioduran.com/blog/consensus-algorithms-raft-paxos-viewstamped>)\n\n## Por Qué el Consenso Es Difícil (Repaso Rápido)\n\nEl problema fundamental: N servidores necesitan ponerse de acuerdo en una secuencia de operaciones, incluso si hasta F de ellos crashean (donde N \\>= 2F + 1). Este acuerdo debe ser:\n\n- **Safe**: Todos los servidores no-fallados acuerdan la misma secuencia\n- **Live**: El sistema eventualmente avanza (asumiendo menos de F+1 crasheos y que la red eventualmente entrega los mensajes)\n\nEl resultado de imposibilidad FLP nos dice que no podemos tener ambos en una red asincrónica con incluso una sola falla por crash. Cada algoritmo de consenso práctico lo soluciona usando timeouts como detectores de fallas, lo cual técnicamente viola el modelo asincrónico, pero funciona en la práctica porque las redes reales tienen delays acotados-pero-desconocidos.\n\n## Raft: El Algoritmo Que Se Explica Solo\n\nRaft fue diseñado para ser entendible, y cumple esa promesa. El algoritmo se descompone en tres subproblemas: elección de líder, replicación de log, y safety. El enfoque a continuación son las partes que son más difíciles de implementar de lo que el paper sugiere.\n\n### Elección de Líder: Las Partes Sutiles\n\nEl mecanismo básico es simple: los candidatos incrementan su term, votan por sí mismos, y piden votos a los demás. Pero los detalles de implementación importan enormemente.\n\n```go\ntype RaftNode struct {\n mu sync.Mutex\n state NodeState\n currentTerm uint64\n votedFor *uint64\n log []LogEntry\n\n // Timing de elección - estos valores importan más de lo que considerars\n electionTimeout time.Duration\n heartbeatTimeout time.Duration\n lastHeartbeat time.Time\n\n // Protocolo pre-vote (Sección 9.6 de la disertación de Raft)\n preVoteEnabled bool\n}\n\nfunc (n *RaftNode) startElection() {\n n.mu.Lock()\n defer n.mu.Unlock()\n\n if n.preVoteEnabled {\n // Pre-vote: preguntar a los peers si votarían por nosotros SIN incrementar term\n // Esto previene disrupciones de nodos particionados\n n.runPreVote()\n return\n }\n\n n.currentTerm++\n n.state = Candidate\n n.votedFor = &n.id\n n.persistState() // DEBE ser durable antes de enviar RequestVote\n\n lastLogIndex, lastLogTerm := n.lastLogInfo()\n\n for _, peer := range n.peers {\n go func(p PeerID) {\n reply, err := n.sendRequestVote(p, &RequestVoteArgs{\n Term: n.currentTerm,\n CandidateID: n.id,\n LastLogIndex: lastLogIndex,\n LastLogTerm: lastLogTerm,\n })\n if err != nil {\n return\n }\n n.handleVoteResponse(reply)\n }(peer)\n }\n}\n```\n\nEl protocolo pre-vote es crítico y usualmente se omite en los tutoriales. Sin él, un nodo que se particiona del cluster sigue incrementando su term. Cuando se reconecta, su term artificialmente alto fuerza una nueva elección, rompiendo el cluster sano. Pre-vote pregunta \"¿votarías por mí?\" sin incrementar el term. Si la respuesta es no (porque el cluster ya tiene un líder sano), el nodo se queda eficiente.\n\n### Log Compaction: Donde Vive el Dolor\n\nLa instalación de snapshots y la recuperación necesitan tratamiento explícito más allá del resumen de compactación del log. El siguiente código es un esquema explicativo.\n\n```go\ntype SnapshotManager struct {\n stateMachine StateMachine\n raftLog *RaftLog\n snapshotDir string\n\n inProgress atomic.Bool\n lastIncluded struct {\n Index uint64\n Term uint64\n }\n}\n\nfunc (sm *SnapshotManager) TakeSnapshot() error {\n if !sm.inProgress.CompareAndSwap(false, true) {\n return ErrSnapshotInProgress\n }\n defer sm.inProgress.Store(false)\n\n // 1. Obtener snapshot point-in-time consistente de la state machine\n snapshot, appliedIndex, appliedTerm := sm.stateMachine.Snapshot()\n\n // 2. Escribir a archivo temporal primero (crash safety)\n tmpPath := filepath.Join(sm.snapshotDir, fmt.Sprintf(\"snap-%d.tmp\", appliedIndex))\n finalPath := filepath.Join(sm.snapshotDir, fmt.Sprintf(\"snap-%d.dat\", appliedIndex))\n\n f, err := os.Create(tmpPath)\n if err != nil {\n return err\n }\n\n header := SnapshotHeader{\n LastIncludedIndex: appliedIndex,\n LastIncludedTerm: appliedTerm,\n Size: uint64(len(snapshot)),\n Checksum: crc32.ChecksumIEEE(snapshot),\n }\n\n if err := binary.Write(f, binary.LittleEndian, header); err != nil {\n f.Close()\n os.Remove(tmpPath)\n return err\n }\n\n if _, err := f.Write(snapshot); err != nil {\n f.Close()\n os.Remove(tmpPath)\n return err\n }\n\n // Fsync antes del rename (crítico para crash safety)\n if err := f.Sync(); err != nil {\n f.Close()\n os.Remove(tmpPath)\n return err\n }\n f.Close()\n\n if err := os.Rename(tmpPath, finalPath); err != nil {\n return err\n }\n\n sm.raftLog.TruncateBefore(appliedIndex)\n sm.lastIncluded.Index = appliedIndex\n sm.lastIncluded.Term = appliedTerm\n\n return nil\n}\n```\n\nLas partes complicadas:\n\n1. **Tomar el snapshot no debe bloquear la aplicación de log.** Si tu state machine es un B-tree, se necesita semántica copy-on-write o un mecanismo de snapshot isolation. BoltDB te da esto gratis; un map in-memory naive no.\n2. **El RPC InstallSnapshot es chunked.** Cuando un follower está tan atrasado que el líder ya compactó su log, el líder manda su snapshot. Para state machines de multi-GB, esto tiene que ser chunked y resumable. El paper lo menciona en una oración.\n3. **El crash recovery intercala snapshots y logs.** Al reiniciar, cargás el último snapshot, después replayeás entries del log después del last included index del snapshot. Si crasheaste entre tomar un snapshot y truncar el log, es posible tener entries superpuestas. Tu lógica de recovery necesita manejar esto.\n\n## Multi-Paxos: Un Protocolo Sin Especificación Canónica\n\nAcá va el secreto sucio de Multi-Paxos: no hay un paper canónico de Multi-Paxos. El \"The Part-Time Parliament\" original de Lamport describe Paxos de un solo decreto. La extensión a multi-decreto (una secuencia de instancias de consenso) se describe informalmente, y cada implementación toma decisiones diferentes.\n\nLa optimización core de Multi-Paxos sobre Paxos básico: una vez que se establece un líder, puede saltear la fase Prepare para entries de log subsiguientes, yendo directo a Accept. Esto significa que las operaciones en estado estable solo requieren un round-trip en vez de dos.\n\n```go\nfunc (n *MultiPaxosNode) Propose(value []byte) (uint64, error) {\n if !n.proposerState.isLeader {\n return 0, ErrNotLeader\n }\n\n slot := atomic.AddUint64(&n.proposerState.maxSlot, 1)\n\n // Como líder establecido, saltear Phase 1 (Prepare)\n // Ir directo a Phase 2 (Accept)\n acceptMsg := &AcceptMessage{\n Ballot: n.proposerState.ballotNum,\n Slot: slot,\n Value: value,\n }\n\n ackCount := 1\n quorum := (len(n.peers) / 2) + 1\n\n for _, peer := range n.peers {\n go func(p PeerID) {\n reply, err := n.sendAccept(p, acceptMsg)\n if err != nil {\n return\n }\n\n if reply.Ballot > n.proposerState.ballotNum {\n n.stepDown(reply.Ballot)\n return\n }\n\n if atomic.AddInt32(&ackCount, 1) >= int32(quorum) {\n n.markChosen(slot, value)\n }\n }(peer)\n }\n\n return slot, nil\n}\n```\n\n### El Problema de los Gaps en los Slots\n\nEn Multi-Paxos, los slots se pueden elegir fuera de orden. El request del Cliente A puede caer en el slot 5, y el del Cliente B en el slot 7, mientras el slot 6 sigue pendiente. Cuando entregás comandos a la state machine, teners que entregarlos en orden. Esto significa que se necesita un mecanismo para rellenar gaps, ya sea con no-ops o re-proponiendo valores para slots vacíos.\n\nEsta lógica de gap-filling es donde la mayoría de las implementaciones de Multi-Paxos tienen bugs. La interacción entre gap-filling, cambios de líder, y la fase accept es sutil. Si un nuevo líder empieza a llenar gaps concurrentemente con los accepts del viejo líder que todavía están en vuelo, es posible terminar con un slot elegido con dos valores diferentes a menos que el mecanismo de ballot number esté correctamente implementado.\n\n## Viewstamped Replication: El Hijo del Medio Olvidado\n\nVR precede a Paxos en publicación y es notablemente similar a Raft en estructura, tiene un primary (líder), views (terms), y un log. Las diferencias clave están en el protocolo de view change y el mecanismo de reconfiguración.\n\n```\nOperación Normal (simplificada):\n1. Cliente → Primary: REQUEST(op, client-id, request-num)\n2. Primary: Asignar op-number, agregar al log\n3. Primary → Backups: PREPARE(view, op-number, op, commit-number)\n4. Backups: Agregar al log, responder PREPARE-OK\n5. Primary: Después de f+1 PREPARE-OKs, commit\n6. Primary → Cliente: REPLY(view, request-num, result)\n```\n\nLo interesante de VR es su protocolo de view change, que es más estructurado que la elección de Raft. Cuando un backup sospecha que el primary falló:\n\n1. Manda mensajes ` START-VIEW-CHANGE `\n2. Después de recibir f tales mensajes, un nodo manda ` DO-VIEW-CHANGE ` al nuevo primary (determinado por round-robin)\n3. El nuevo primary recolecta f+1 mensajes ` DO-VIEW-CHANGE `, selecciona el log con los datos más recientes, y arranca la nueva view\n\nLa selección determinista del primary (round-robin basado en el número de view) significa que no hay escenario de split-vote, no se necesita timeouts randomizados como Raft. El tradeoff es menos flexibilidad: no es posible preferir un nodo con mejor hardware o menor latencia a los clientes.\n\n### Donde VR Brilla\n\nEl protocolo de reconfiguración de VR (cambiar el set de réplicas) es significativamente más simple que el approach de joint consensus de Raft. En VR, la reconfiguración es simplemente una operación especial en el log. Cuando se commitea, la nueva configuración toma efecto en ese punto del log. Las réplicas viejas transfieren estado a las nuevas, y la transición es limpia.\n\n## EPaxos: La Promesa Leaderless\n\nEPaxos (Egalitarian Paxos) es el más intelectualmente ambicioso de los cuatro. En vez de canalizar todas las operaciones a través de un líder, cualquier réplica puede proponer comandos. Los comandos que no conflictúan se pueden commitear en un solo round-trip (el fast path), y los conflictos se resuelven a través de un grafo de dependencias.\n\n### El Grafo de Dependencias\n\nAcá es donde EPaxos se complica. Cada comando lleva un set de dependencias, otros comandos después de los cuales debe ejecutarse:\n\n```go\nfunc (r *EPaxosReplica) StartCommand(cmd []byte) {\n inst := &EPaxosInstance{\n Command: cmd,\n SeqNum: 0,\n Deps: make(map[InstanceID]uint64),\n Status: PreAccepted,\n }\n\n for id, other := range r.instances {\n if r.conflictsWithAny(cmd, other.Command) {\n inst.Deps[id] = other.SeqNum\n if other.SeqNum >= inst.SeqNum {\n inst.SeqNum = other.SeqNum + 1\n }\n }\n }\n\n superQuorum := (3*len(r.peers)/4) + 1\n replies := r.broadcastPreAccept(inst)\n\n if r.fastPathSucceeded(replies, inst, superQuorum) {\n inst.Status = Committed\n r.broadcastCommit(inst)\n } else {\n r.mergedDeps(inst, replies)\n inst.Status = Accepted\n r.broadcastAccept(inst)\n }\n}\n```\n\n### El Problema de la Ejecución\n\nCommitear es fácil. Ejecutar es difícil. Porque los comandos son commiteados por distintas réplicas con distintos sets de dependencias, se necesita un algoritmo determinístico para linearizar el grafo de dependencias. Esto usa el algoritmo de componentes fuertemente conectados de Tarjan:\n\n1. Construir el grafo de dependencias de instancias commiteadas\n2. Encontrar todas las componentes fuertemente conectadas (SCCs)\n3. Ejecutar SCCs en orden topológico inverso\n4. Dentro de cada SCC, ejecutar comandos en orden de número de secuencia\n\nEsto significa que no es posible ejecutar un comando en el momento que se commitea, teners que esperar hasta que todas sus dependencias también estén commiteadas, y después computar el orden de ejecución. En la práctica, esto agrega varianza de latencia que los ahorros del fast-path no siempre compensan.\n\n## Comparar implementaciones\n\nEl nombre del protocolo no determina su rendimiento. Compará implementaciones concretas con la misma durabilidad, carga, tasa de conflictos, política de lotes y condiciones de red. Publicá el arnés, las versiones y resultados repetidos antes de extraer conclusiones numéricas. Aquí no se aporta un benchmark reproducible.\n\n## Qué Elegiría Hoy\n\nPara la mayoría de los sistemas: **Raft con las optimizaciones de etcd** (pipelining, learner nodes, pre-vote, leader lease para reads). El ecosistema no tiene comparación, [etcd](<https://etcd.io/>), [CockroachDB](<https://www.cockroachlabs.com/>), [TiKV](<https://tikv.org/>), y [Consul](<https://www.consul.io/>) todos usan variantes de Raft, y sus implementaciones battle-tested están disponibles como librerías.\n\nPara sistemas geo-distribuidos con operaciones mayormente no conflictivas: **EPaxos**, pero solo si teners los recurse es de ingeniería para manejar la complejidad de implementación y la pesadilla de debugging que es la resolución de grafos de dependencias.\n\nPara aprender y construir intuición: implementá **Raft primero, después VR**. Las similitudes van a cristalizar tu entendimiento, y las diferencias en view change vs. election te van a enseñar por qué estas decisiones de diseño importan.\n\nMulti-Paxos es la respuesta correcta si se necesita máximo throughput en un solo líder y se está dispuesto a invertir en una implementación custom. Pero honestamente, llegado ese punto, probablemente deberías usar etcd o CockroachDB y enfocar tu esfuerzo de ingeniería en tu producto real.\n\n## Método editorial y alcance\n\nRevisado el 10 de noviembre de 2026. Se retiraron afirmaciones de experiencia personal en producción y resultados numéricos sin respaldo publicado. Los ejemplos restantes explican técnicas; su presencia no implica que se hayan ejecutado durante esta revisión. Esta revisión no valida de forma completa cada API, versión ni fragmento de código del artículo.\n\n## Preguntas frecuentes\n\n### ¿Qué algoritmo de consenso debería usar para un proyecto nuevo?\n\nRaft, a menos que tengas un motivo específico para no hacerlo. Es el más comprendido, tiene la mayor cantidad de implementaciones en producción, el mejor tooling de debugging, y la especificación más clara. Multi-Paxos puede ser más eficiente para workloads de alto throughput, pero la complejidad de implementación es significativamente mayor.\n\n### ¿EPaxos es realmente mejor que Raft en la práctica?\n\nDepende de tu workload. EPaxos elimina el bottleneck del líder y logra menor latencia para comandos no conflictivos en deployments geo-distribuidos. Pero la complejidad de implementación es un orden de magnitud mayor, el protocolo de recovery es notoriamente difícil de implementar bien, y los comandos conflictivos pueden causar degradación significativa de performance.\n\n### ¿Cuál es la diferencia entre Paxos y Multi-Paxos?\n\nPaxos clásico es un protocolo para acordar un solo valor. Multi-Paxos lo extiende a una secuencia de valores (un log replicado) eligiendo un líder estable que puede saltear la fase prepare para entries subsiguientes, amortizando el costo de la elección de líder a lo largo de muchas operaciones.\n\n## Tips\n\n1. **LuchoTip:** La optimización de leader lease de Raft (donde el líder sirve lecturas sin quorum) rompe la linearizabilidad si el clock skew supera la duración del lease. Se recomienda utilizar siempre ` ReadIndex ` o ` ReadOnlySafe ` para lecturas que deban ser linearizables.\n2. **LuchoTip:** Al implementar log compaction en Raft, es conveniente realizar el snapshot de la state machine en una goroutine/thread separada y utilizar una estructura copy-on-write. Bloquear el main loop durante el snapshot causa election timeouts en clusters grandes.\n3. **LuchoTip:** El fast-path de EPaxos requiere un super-quorum (⌊3F/4⌋+1 para F fallas). En un cluster de 5 nodos, son 4 de 5 nodos. Un solo nodo lento te mata el fast path, por eso EPaxos anda peor que Raft en redes heterogéneas a pesar de verse mejor en el papel.\n4. **LuchoTip:** Para Multi-Paxos, la distinción entre las fases ` prepare ` y ` accept ` es donde se esconden la mayoría de los bugs. Si tu líder se cae entre mandar accepts y recibir quorum de acks, la fase prepare del nuevo líder DEBE descubrir ese es accepts en vuelo. Se recomienda utilizar un log persistente, no un map en memoria.\n\n- raft\n- paxos\n- epaxos\n- consenso\n- sistemas-distribuidos\n- viewstamped-replication\n- eleccion-lider\n- replicacion-log\n\n[Volver al Blog](<https://lucioduran.com/es/blog>)","headings":[{"level":1,"text":"Algoritmos de Consenso Comparados: Raft, Multi-Paxos, Viewstamped Replication y EPaxos","url":"https://lucioduran.com/es/blog/consensus-algorithms-raft-paxos-viewstamped#title"},{"level":2,"text":"Por Qué el Consenso Es Difícil (Repaso Rápido)","url":"https://lucioduran.com/es/blog/consensus-algorithms-raft-paxos-viewstamped#por-qu-el-consenso-es-difcil-repaso-rpido"},{"level":2,"text":"Raft: El Algoritmo Que Se Explica Solo","url":"https://lucioduran.com/es/blog/consensus-algorithms-raft-paxos-viewstamped#raft-el-algoritmo-que-se-explica-solo"},{"level":3,"text":"Elección de Líder: Las Partes Sutiles","url":"https://lucioduran.com/es/blog/consensus-algorithms-raft-paxos-viewstamped#eleccin-de-lder-las-partes-sutiles"},{"level":3,"text":"Log Compaction: Donde Vive el Dolor","url":"https://lucioduran.com/es/blog/consensus-algorithms-raft-paxos-viewstamped#log-compaction-donde-vive-el-dolor"},{"level":2,"text":"Multi-Paxos: Un Protocolo Sin Especificación Canónica","url":"https://lucioduran.com/es/blog/consensus-algorithms-raft-paxos-viewstamped#multi-paxos-un-protocolo-sin-especificacin-cannica"},{"level":3,"text":"El Problema de los Gaps en los Slots","url":"https://lucioduran.com/es/blog/consensus-algorithms-raft-paxos-viewstamped#el-problema-de-los-gaps-en-los-slots"},{"level":2,"text":"Viewstamped Replication: El Hijo del Medio Olvidado","url":"https://lucioduran.com/es/blog/consensus-algorithms-raft-paxos-viewstamped#viewstamped-replication-el-hijo-del-medio-olvidado"},{"level":3,"text":"Donde VR Brilla","url":"https://lucioduran.com/es/blog/consensus-algorithms-raft-paxos-viewstamped#donde-vr-brilla"},{"level":2,"text":"EPaxos: La Promesa Leaderless","url":"https://lucioduran.com/es/blog/consensus-algorithms-raft-paxos-viewstamped#epaxos-la-promesa-leaderless"},{"level":3,"text":"El Grafo de Dependencias","url":"https://lucioduran.com/es/blog/consensus-algorithms-raft-paxos-viewstamped#el-grafo-de-dependencias"},{"level":3,"text":"El Problema de la Ejecución","url":"https://lucioduran.com/es/blog/consensus-algorithms-raft-paxos-viewstamped#el-problema-de-la-ejecucin"},{"level":2,"text":"Comparar implementaciones","url":"https://lucioduran.com/es/blog/consensus-algorithms-raft-paxos-viewstamped#comparar-implementaciones"},{"level":2,"text":"Qué Elegiría Hoy","url":"https://lucioduran.com/es/blog/consensus-algorithms-raft-paxos-viewstamped#qu-elegira-hoy"},{"level":2,"text":"Método editorial y alcance","url":"https://lucioduran.com/es/blog/consensus-algorithms-raft-paxos-viewstamped#mtodo-editorial-y-alcance"},{"level":2,"text":"Preguntas frecuentes","url":"https://lucioduran.com/es/blog/consensus-algorithms-raft-paxos-viewstamped#questions"},{"level":3,"text":"¿Qué algoritmo de consenso debería usar para un proyecto nuevo?","url":"https://lucioduran.com/es/blog/consensus-algorithms-raft-paxos-viewstamped#question-1"},{"level":3,"text":"¿EPaxos es realmente mejor que Raft en la práctica?","url":"https://lucioduran.com/es/blog/consensus-algorithms-raft-paxos-viewstamped#question-2"},{"level":3,"text":"¿Cuál es la diferencia entre Paxos y Multi-Paxos?","url":"https://lucioduran.com/es/blog/consensus-algorithms-raft-paxos-viewstamped#question-3"},{"level":2,"text":"Tips","url":"https://lucioduran.com/es/blog/consensus-algorithms-raft-paxos-viewstamped#article-tips"}],"sections":[{"heading":"Algoritmos de Consenso Comparados: Raft, Multi-Paxos, Viewstamped Replication y EPaxos","level":1,"url":"https://lucioduran.com/es/blog/consensus-algorithms-raft-paxos-viewstamped","content":"Distributed Systems"},{"heading":"Algoritmos de Consenso Comparados: Raft, Multi-Paxos, Viewstamped Replication y EPaxos","level":1,"url":"https://lucioduran.com/es/blog/consensus-algorithms-raft-paxos-viewstamped#title","content":"2025-10-28Actualizado: 2026-11-1010 min lectura\n\n[Lucio Durán](<https://lucioduran.com/es>)\nC.T.O. en LOi\n\nTambién disponible en: [English](<https://lucioduran.com/blog/consensus-algorithms-raft-paxos-viewstamped>)"},{"heading":"Por Qué el Consenso Es Difícil (Repaso Rápido)","level":2,"url":"https://lucioduran.com/es/blog/consensus-algorithms-raft-paxos-viewstamped#por-qu-el-consenso-es-difcil-repaso-rpido","content":"El problema fundamental: N servidores necesitan ponerse de acuerdo en una secuencia de operaciones, incluso si hasta F de ellos crashean (donde N \\>= 2F + 1). Este acuerdo debe ser:\n\n- **Safe**: Todos los servidores no-fallados acuerdan la misma secuencia\n- **Live**: El sistema eventualmente avanza (asumiendo menos de F+1 crasheos y que la red eventualmente entrega los mensajes)\n\nEl resultado de imposibilidad FLP nos dice que no podemos tener ambos en una red asincrónica con incluso una sola falla por crash. Cada algoritmo de consenso práctico lo soluciona usando timeouts como detectores de fallas, lo cual técnicamente viola el modelo asincrónico, pero funciona en la práctica porque las redes reales tienen delays acotados-pero-desconocidos."},{"heading":"Raft: El Algoritmo Que Se Explica Solo","level":2,"url":"https://lucioduran.com/es/blog/consensus-algorithms-raft-paxos-viewstamped#raft-el-algoritmo-que-se-explica-solo","content":"Raft fue diseñado para ser entendible, y cumple esa promesa. El algoritmo se descompone en tres subproblemas: elección de líder, replicación de log, y safety. El enfoque a continuación son las partes que son más difíciles de implementar de lo que el paper sugiere."},{"heading":"Elección de Líder: Las Partes Sutiles","level":3,"url":"https://lucioduran.com/es/blog/consensus-algorithms-raft-paxos-viewstamped#eleccin-de-lder-las-partes-sutiles","content":"El mecanismo básico es simple: los candidatos incrementan su term, votan por sí mismos, y piden votos a los demás. Pero los detalles de implementación importan enormemente.\n\n```go\ntype RaftNode struct {\n mu sync.Mutex\n state NodeState\n currentTerm uint64\n votedFor *uint64\n log []LogEntry\n\n // Timing de elección - estos valores importan más de lo que considerars\n electionTimeout time.Duration\n heartbeatTimeout time.Duration\n lastHeartbeat time.Time\n\n // Protocolo pre-vote (Sección 9.6 de la disertación de Raft)\n preVoteEnabled bool\n}\n\nfunc (n *RaftNode) startElection() {\n n.mu.Lock()\n defer n.mu.Unlock()\n\n if n.preVoteEnabled {\n // Pre-vote: preguntar a los peers si votarían por nosotros SIN incrementar term\n // Esto previene disrupciones de nodos particionados\n n.runPreVote()\n return\n }\n\n n.currentTerm++\n n.state = Candidate\n n.votedFor = &n.id\n n.persistState() // DEBE ser durable antes de enviar RequestVote\n\n lastLogIndex, lastLogTerm := n.lastLogInfo()\n\n for _, peer := range n.peers {\n go func(p PeerID) {\n reply, err := n.sendRequestVote(p, &RequestVoteArgs{\n Term: n.currentTerm,\n CandidateID: n.id,\n LastLogIndex: lastLogIndex,\n LastLogTerm: lastLogTerm,\n })\n if err != nil {\n return\n }\n n.handleVoteResponse(reply)\n }(peer)\n }\n}\n```\n\nEl protocolo pre-vote es crítico y usualmente se omite en los tutoriales. Sin él, un nodo que se particiona del cluster sigue incrementando su term. Cuando se reconecta, su term artificialmente alto fuerza una nueva elección, rompiendo el cluster sano. Pre-vote pregunta \"¿votarías por mí?\" sin incrementar el term. Si la respuesta es no (porque el cluster ya tiene un líder sano), el nodo se queda eficiente."},{"heading":"Log Compaction: Donde Vive el Dolor","level":3,"url":"https://lucioduran.com/es/blog/consensus-algorithms-raft-paxos-viewstamped#log-compaction-donde-vive-el-dolor","content":"La instalación de snapshots y la recuperación necesitan tratamiento explícito más allá del resumen de compactación del log. El siguiente código es un esquema explicativo.\n\n```go\ntype SnapshotManager struct {\n stateMachine StateMachine\n raftLog *RaftLog\n snapshotDir string\n\n inProgress atomic.Bool\n lastIncluded struct {\n Index uint64\n Term uint64\n }\n}\n\nfunc (sm *SnapshotManager) TakeSnapshot() error {\n if !sm.inProgress.CompareAndSwap(false, true) {\n return ErrSnapshotInProgress\n }\n defer sm.inProgress.Store(false)\n\n // 1. Obtener snapshot point-in-time consistente de la state machine\n snapshot, appliedIndex, appliedTerm := sm.stateMachine.Snapshot()\n\n // 2. Escribir a archivo temporal primero (crash safety)\n tmpPath := filepath.Join(sm.snapshotDir, fmt.Sprintf(\"snap-%d.tmp\", appliedIndex))\n finalPath := filepath.Join(sm.snapshotDir, fmt.Sprintf(\"snap-%d.dat\", appliedIndex))\n\n f, err := os.Create(tmpPath)\n if err != nil {\n return err\n }\n\n header := SnapshotHeader{\n LastIncludedIndex: appliedIndex,\n LastIncludedTerm: appliedTerm,\n Size: uint64(len(snapshot)),\n Checksum: crc32.ChecksumIEEE(snapshot),\n }\n\n if err := binary.Write(f, binary.LittleEndian, header); err != nil {\n f.Close()\n os.Remove(tmpPath)\n return err\n }\n\n if _, err := f.Write(snapshot); err != nil {\n f.Close()\n os.Remove(tmpPath)\n return err\n }\n\n // Fsync antes del rename (crítico para crash safety)\n if err := f.Sync(); err != nil {\n f.Close()\n os.Remove(tmpPath)\n return err\n }\n f.Close()\n\n if err := os.Rename(tmpPath, finalPath); err != nil {\n return err\n }\n\n sm.raftLog.TruncateBefore(appliedIndex)\n sm.lastIncluded.Index = appliedIndex\n sm.lastIncluded.Term = appliedTerm\n\n return nil\n}\n```\n\nLas partes complicadas:\n\n1. **Tomar el snapshot no debe bloquear la aplicación de log.** Si tu state machine es un B-tree, se necesita semántica copy-on-write o un mecanismo de snapshot isolation. BoltDB te da esto gratis; un map in-memory naive no.\n2. **El RPC InstallSnapshot es chunked.** Cuando un follower está tan atrasado que el líder ya compactó su log, el líder manda su snapshot. Para state machines de multi-GB, esto tiene que ser chunked y resumable. El paper lo menciona en una oración.\n3. **El crash recovery intercala snapshots y logs.** Al reiniciar, cargás el último snapshot, después replayeás entries del log después del last included index del snapshot. Si crasheaste entre tomar un snapshot y truncar el log, es posible tener entries superpuestas. Tu lógica de recovery necesita manejar esto."},{"heading":"Multi-Paxos: Un Protocolo Sin Especificación Canónica","level":2,"url":"https://lucioduran.com/es/blog/consensus-algorithms-raft-paxos-viewstamped#multi-paxos-un-protocolo-sin-especificacin-cannica","content":"Acá va el secreto sucio de Multi-Paxos: no hay un paper canónico de Multi-Paxos. El \"The Part-Time Parliament\" original de Lamport describe Paxos de un solo decreto. La extensión a multi-decreto (una secuencia de instancias de consenso) se describe informalmente, y cada implementación toma decisiones diferentes.\n\nLa optimización core de Multi-Paxos sobre Paxos básico: una vez que se establece un líder, puede saltear la fase Prepare para entries de log subsiguientes, yendo directo a Accept. Esto significa que las operaciones en estado estable solo requieren un round-trip en vez de dos.\n\n```go\nfunc (n *MultiPaxosNode) Propose(value []byte) (uint64, error) {\n if !n.proposerState.isLeader {\n return 0, ErrNotLeader\n }\n\n slot := atomic.AddUint64(&n.proposerState.maxSlot, 1)\n\n // Como líder establecido, saltear Phase 1 (Prepare)\n // Ir directo a Phase 2 (Accept)\n acceptMsg := &AcceptMessage{\n Ballot: n.proposerState.ballotNum,\n Slot: slot,\n Value: value,\n }\n\n ackCount := 1\n quorum := (len(n.peers) / 2) + 1\n\n for _, peer := range n.peers {\n go func(p PeerID) {\n reply, err := n.sendAccept(p, acceptMsg)\n if err != nil {\n return\n }\n\n if reply.Ballot > n.proposerState.ballotNum {\n n.stepDown(reply.Ballot)\n return\n }\n\n if atomic.AddInt32(&ackCount, 1) >= int32(quorum) {\n n.markChosen(slot, value)\n }\n }(peer)\n }\n\n return slot, nil\n}\n```"},{"heading":"El Problema de los Gaps en los Slots","level":3,"url":"https://lucioduran.com/es/blog/consensus-algorithms-raft-paxos-viewstamped#el-problema-de-los-gaps-en-los-slots","content":"En Multi-Paxos, los slots se pueden elegir fuera de orden. El request del Cliente A puede caer en el slot 5, y el del Cliente B en el slot 7, mientras el slot 6 sigue pendiente. Cuando entregás comandos a la state machine, teners que entregarlos en orden. Esto significa que se necesita un mecanismo para rellenar gaps, ya sea con no-ops o re-proponiendo valores para slots vacíos.\n\nEsta lógica de gap-filling es donde la mayoría de las implementaciones de Multi-Paxos tienen bugs. La interacción entre gap-filling, cambios de líder, y la fase accept es sutil. Si un nuevo líder empieza a llenar gaps concurrentemente con los accepts del viejo líder que todavía están en vuelo, es posible terminar con un slot elegido con dos valores diferentes a menos que el mecanismo de ballot number esté correctamente implementado."},{"heading":"Viewstamped Replication: El Hijo del Medio Olvidado","level":2,"url":"https://lucioduran.com/es/blog/consensus-algorithms-raft-paxos-viewstamped#viewstamped-replication-el-hijo-del-medio-olvidado","content":"VR precede a Paxos en publicación y es notablemente similar a Raft en estructura, tiene un primary (líder), views (terms), y un log. Las diferencias clave están en el protocolo de view change y el mecanismo de reconfiguración.\n\n```\nOperación Normal (simplificada):\n1. Cliente → Primary: REQUEST(op, client-id, request-num)\n2. Primary: Asignar op-number, agregar al log\n3. Primary → Backups: PREPARE(view, op-number, op, commit-number)\n4. Backups: Agregar al log, responder PREPARE-OK\n5. Primary: Después de f+1 PREPARE-OKs, commit\n6. Primary → Cliente: REPLY(view, request-num, result)\n```\n\nLo interesante de VR es su protocolo de view change, que es más estructurado que la elección de Raft. Cuando un backup sospecha que el primary falló:\n\n1. Manda mensajes ` START-VIEW-CHANGE `\n2. Después de recibir f tales mensajes, un nodo manda ` DO-VIEW-CHANGE ` al nuevo primary (determinado por round-robin)\n3. El nuevo primary recolecta f+1 mensajes ` DO-VIEW-CHANGE `, selecciona el log con los datos más recientes, y arranca la nueva view\n\nLa selección determinista del primary (round-robin basado en el número de view) significa que no hay escenario de split-vote, no se necesita timeouts randomizados como Raft. El tradeoff es menos flexibilidad: no es posible preferir un nodo con mejor hardware o menor latencia a los clientes."},{"heading":"Donde VR Brilla","level":3,"url":"https://lucioduran.com/es/blog/consensus-algorithms-raft-paxos-viewstamped#donde-vr-brilla","content":"El protocolo de reconfiguración de VR (cambiar el set de réplicas) es significativamente más simple que el approach de joint consensus de Raft. En VR, la reconfiguración es simplemente una operación especial en el log. Cuando se commitea, la nueva configuración toma efecto en ese punto del log. Las réplicas viejas transfieren estado a las nuevas, y la transición es limpia."},{"heading":"EPaxos: La Promesa Leaderless","level":2,"url":"https://lucioduran.com/es/blog/consensus-algorithms-raft-paxos-viewstamped#epaxos-la-promesa-leaderless","content":"EPaxos (Egalitarian Paxos) es el más intelectualmente ambicioso de los cuatro. En vez de canalizar todas las operaciones a través de un líder, cualquier réplica puede proponer comandos. Los comandos que no conflictúan se pueden commitear en un solo round-trip (el fast path), y los conflictos se resuelven a través de un grafo de dependencias."},{"heading":"El Grafo de Dependencias","level":3,"url":"https://lucioduran.com/es/blog/consensus-algorithms-raft-paxos-viewstamped#el-grafo-de-dependencias","content":"Acá es donde EPaxos se complica. Cada comando lleva un set de dependencias, otros comandos después de los cuales debe ejecutarse:\n\n```go\nfunc (r *EPaxosReplica) StartCommand(cmd []byte) {\n inst := &EPaxosInstance{\n Command: cmd,\n SeqNum: 0,\n Deps: make(map[InstanceID]uint64),\n Status: PreAccepted,\n }\n\n for id, other := range r.instances {\n if r.conflictsWithAny(cmd, other.Command) {\n inst.Deps[id] = other.SeqNum\n if other.SeqNum >= inst.SeqNum {\n inst.SeqNum = other.SeqNum + 1\n }\n }\n }\n\n superQuorum := (3*len(r.peers)/4) + 1\n replies := r.broadcastPreAccept(inst)\n\n if r.fastPathSucceeded(replies, inst, superQuorum) {\n inst.Status = Committed\n r.broadcastCommit(inst)\n } else {\n r.mergedDeps(inst, replies)\n inst.Status = Accepted\n r.broadcastAccept(inst)\n }\n}\n```"},{"heading":"El Problema de la Ejecución","level":3,"url":"https://lucioduran.com/es/blog/consensus-algorithms-raft-paxos-viewstamped#el-problema-de-la-ejecucin","content":"Commitear es fácil. Ejecutar es difícil. Porque los comandos son commiteados por distintas réplicas con distintos sets de dependencias, se necesita un algoritmo determinístico para linearizar el grafo de dependencias. Esto usa el algoritmo de componentes fuertemente conectados de Tarjan:\n\n1. Construir el grafo de dependencias de instancias commiteadas\n2. Encontrar todas las componentes fuertemente conectadas (SCCs)\n3. Ejecutar SCCs en orden topológico inverso\n4. Dentro de cada SCC, ejecutar comandos en orden de número de secuencia\n\nEsto significa que no es posible ejecutar un comando en el momento que se commitea, teners que esperar hasta que todas sus dependencias también estén commiteadas, y después computar el orden de ejecución. En la práctica, esto agrega varianza de latencia que los ahorros del fast-path no siempre compensan."},{"heading":"Comparar implementaciones","level":2,"url":"https://lucioduran.com/es/blog/consensus-algorithms-raft-paxos-viewstamped#comparar-implementaciones","content":"El nombre del protocolo no determina su rendimiento. Compará implementaciones concretas con la misma durabilidad, carga, tasa de conflictos, política de lotes y condiciones de red. Publicá el arnés, las versiones y resultados repetidos antes de extraer conclusiones numéricas. Aquí no se aporta un benchmark reproducible."},{"heading":"Qué Elegiría Hoy","level":2,"url":"https://lucioduran.com/es/blog/consensus-algorithms-raft-paxos-viewstamped#qu-elegira-hoy","content":"Para la mayoría de los sistemas: **Raft con las optimizaciones de etcd** (pipelining, learner nodes, pre-vote, leader lease para reads). El ecosistema no tiene comparación, [etcd](<https://etcd.io/>), [CockroachDB](<https://www.cockroachlabs.com/>), [TiKV](<https://tikv.org/>), y [Consul](<https://www.consul.io/>) todos usan variantes de Raft, y sus implementaciones battle-tested están disponibles como librerías.\n\nPara sistemas geo-distribuidos con operaciones mayormente no conflictivas: **EPaxos**, pero solo si teners los recurse es de ingeniería para manejar la complejidad de implementación y la pesadilla de debugging que es la resolución de grafos de dependencias.\n\nPara aprender y construir intuición: implementá **Raft primero, después VR**. Las similitudes van a cristalizar tu entendimiento, y las diferencias en view change vs. election te van a enseñar por qué estas decisiones de diseño importan.\n\nMulti-Paxos es la respuesta correcta si se necesita máximo throughput en un solo líder y se está dispuesto a invertir en una implementación custom. Pero honestamente, llegado ese punto, probablemente deberías usar etcd o CockroachDB y enfocar tu esfuerzo de ingeniería en tu producto real."},{"heading":"Método editorial y alcance","level":2,"url":"https://lucioduran.com/es/blog/consensus-algorithms-raft-paxos-viewstamped#mtodo-editorial-y-alcance","content":"Revisado el 10 de noviembre de 2026. Se retiraron afirmaciones de experiencia personal en producción y resultados numéricos sin respaldo publicado. Los ejemplos restantes explican técnicas; su presencia no implica que se hayan ejecutado durante esta revisión. Esta revisión no valida de forma completa cada API, versión ni fragmento de código del artículo."},{"heading":"Preguntas frecuentes","level":2,"url":"https://lucioduran.com/es/blog/consensus-algorithms-raft-paxos-viewstamped#questions","content":""},{"heading":"¿Qué algoritmo de consenso debería usar para un proyecto nuevo?","level":3,"url":"https://lucioduran.com/es/blog/consensus-algorithms-raft-paxos-viewstamped#question-1","content":"Raft, a menos que tengas un motivo específico para no hacerlo. Es el más comprendido, tiene la mayor cantidad de implementaciones en producción, el mejor tooling de debugging, y la especificación más clara. Multi-Paxos puede ser más eficiente para workloads de alto throughput, pero la complejidad de implementación es significativamente mayor."},{"heading":"¿EPaxos es realmente mejor que Raft en la práctica?","level":3,"url":"https://lucioduran.com/es/blog/consensus-algorithms-raft-paxos-viewstamped#question-2","content":"Depende de tu workload. EPaxos elimina el bottleneck del líder y logra menor latencia para comandos no conflictivos en deployments geo-distribuidos. Pero la complejidad de implementación es un orden de magnitud mayor, el protocolo de recovery es notoriamente difícil de implementar bien, y los comandos conflictivos pueden causar degradación significativa de performance."},{"heading":"¿Cuál es la diferencia entre Paxos y Multi-Paxos?","level":3,"url":"https://lucioduran.com/es/blog/consensus-algorithms-raft-paxos-viewstamped#question-3","content":"Paxos clásico es un protocolo para acordar un solo valor. Multi-Paxos lo extiende a una secuencia de valores (un log replicado) eligiendo un líder estable que puede saltear la fase prepare para entries subsiguientes, amortizando el costo de la elección de líder a lo largo de muchas operaciones."},{"heading":"Tips","level":2,"url":"https://lucioduran.com/es/blog/consensus-algorithms-raft-paxos-viewstamped#article-tips","content":"1. **LuchoTip:** La optimización de leader lease de Raft (donde el líder sirve lecturas sin quorum) rompe la linearizabilidad si el clock skew supera la duración del lease. Se recomienda utilizar siempre ` ReadIndex ` o ` ReadOnlySafe ` para lecturas que deban ser linearizables.\n2. **LuchoTip:** Al implementar log compaction en Raft, es conveniente realizar el snapshot de la state machine en una goroutine/thread separada y utilizar una estructura copy-on-write. Bloquear el main loop durante el snapshot causa election timeouts en clusters grandes.\n3. **LuchoTip:** El fast-path de EPaxos requiere un super-quorum (⌊3F/4⌋+1 para F fallas). En un cluster de 5 nodos, son 4 de 5 nodos. Un solo nodo lento te mata el fast path, por eso EPaxos anda peor que Raft en redes heterogéneas a pesar de verse mejor en el papel.\n4. **LuchoTip:** Para Multi-Paxos, la distinción entre las fases ` prepare ` y ` accept ` es donde se esconden la mayoría de los bugs. Si tu líder se cae entre mandar accepts y recibir quorum de acks, la fase prepare del nuevo líder DEBE descubrir ese es accepts en vuelo. Se recomienda utilizar un log persistente, no un map en memoria.\n\n- raft\n- paxos\n- epaxos\n- consenso\n- sistemas-distribuidos\n- viewstamped-replication\n- eleccion-lider\n- replicacion-log\n\n[Volver al Blog](<https://lucioduran.com/es/blog>)"}],"links":[{"text":"Lucio Durán","url":"https://lucioduran.com/es"},{"text":"English","url":"https://lucioduran.com/blog/consensus-algorithms-raft-paxos-viewstamped"},{"text":"etcd","url":"https://etcd.io/"},{"text":"CockroachDB","url":"https://www.cockroachlabs.com/"},{"text":"TiKV","url":"https://tikv.org/"},{"text":"Consul","url":"https://www.consul.io/"},{"text":"Volver al Blog","url":"https://lucioduran.com/es/blog"}],"structuredData":[{"@context":"https://schema.org","@graph":[{"@type":"Person","@id":"https://lucioduran.com/#person","name":"Lucio Durán","url":"https://lucioduran.com/"},{"@type":"WebSite","@id":"https://lucioduran.com/#website","url":"https://lucioduran.com/","name":"Lucio Durán","inLanguage":["en","es"],"publisher":{"@id":"https://lucioduran.com/#person"}},{"@type":"WebPage","@id":"https://lucioduran.com/es/blog/consensus-algorithms-raft-paxos-viewstamped#page","url":"https://lucioduran.com/es/blog/consensus-algorithms-raft-paxos-viewstamped","name":"Algoritmos de Consenso Comparados: Raft, Multi-Paxos, Viewstamped Replication y EPaxos | Lucio Durán","description":"Comparación enfocada en implementación de algoritmos de consenso distribuido, Raft, Multi-Paxos, Viewstamped Replication y EPaxos, cubriendo elección de líder, compactación de log, garantías de liveness, y los matices que sólo aparecen cuando los construís.","inLanguage":"es","author":{"@id":"https://lucioduran.com/#person"},"publisher":{"@id":"https://lucioduran.com/#person"},"isPartOf":{"@id":"https://lucioduran.com/#website"},"isAccessibleForFree":true,"datePublished":"2025-10-28","dateModified":"2026-11-10","mainEntity":{"@id":"https://lucioduran.com/es/blog/consensus-algorithms-raft-paxos-viewstamped#article"},"breadcrumb":{"@id":"https://lucioduran.com/es/blog/consensus-algorithms-raft-paxos-viewstamped#breadcrumb"}},{"@type":"BlogPosting","@id":"https://lucioduran.com/es/blog/consensus-algorithms-raft-paxos-viewstamped#article","mainEntityOfPage":{"@id":"https://lucioduran.com/es/blog/consensus-algorithms-raft-paxos-viewstamped#page"},"headline":"Algoritmos de Consenso Comparados: Raft, Multi-Paxos, Viewstamped Replication y EPaxos","description":"Comparación enfocada en implementación de algoritmos de consenso distribuido, Raft, Multi-Paxos, Viewstamped Replication y EPaxos, cubriendo elección de líder, compactación de log, garantías de liveness, y los matices que sólo aparecen cuando los construís.","datePublished":"2025-10-28","dateModified":"2026-11-10","author":{"@type":"Person","@id":"https://lucioduran.com/#person","name":"Lucio Durán","url":"https://lucioduran.com"},"publisher":{"@id":"https://lucioduran.com/#person"},"url":"https://lucioduran.com/es/blog/consensus-algorithms-raft-paxos-viewstamped","inLanguage":"es","isPartOf":{"@id":"https://lucioduran.com/es/blog#blog"},"articleSection":"Distributed Systems","keywords":"raft, paxos, epaxos, consenso, sistemas-distribuidos, viewstamped-replication, eleccion-lider, replicacion-log","wordCount":1900,"timeRequired":"PT10M","workTranslation":[{"@type":"BlogPosting","@id":"https://lucioduran.com/blog/consensus-algorithms-raft-paxos-viewstamped#article","inLanguage":"en","url":"https://lucioduran.com/blog/consensus-algorithms-raft-paxos-viewstamped"}],"isAccessibleForFree":true},{"@type":"Blog","@id":"https://lucioduran.com/es/blog#blog","url":"https://lucioduran.com/es/blog","name":"Blog","inLanguage":"es","author":{"@type":"Person","@id":"https://lucioduran.com/#person","name":"Lucio Durán","url":"https://lucioduran.com/"},"publisher":{"@id":"https://lucioduran.com/#person"},"isPartOf":{"@id":"https://lucioduran.com/#website"}},{"@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Inicio","item":"https://lucioduran.com/es"},{"@type":"ListItem","position":2,"name":"Blog","item":"https://lucioduran.com/es/blog"},{"@type":"ListItem","position":3,"name":"Algoritmos de Consenso Comparados: Raft, Multi-Paxos, Viewstamped Replication y EPaxos","item":"https://lucioduran.com/es/blog/consensus-algorithms-raft-paxos-viewstamped"}],"@id":"https://lucioduran.com/es/blog/consensus-algorithms-raft-paxos-viewstamped#breadcrumb"},{"@type":"FAQPage","mainEntity":[{"@type":"Question","name":"¿Qué algoritmo de consenso debería usar para un proyecto nuevo?","acceptedAnswer":{"@type":"Answer","text":"Raft, a menos que tengas un motivo específico para no hacerlo. Es el más comprendido, tiene la mayor cantidad de implementaciones en producción, el mejor tooling de debugging, y la especificación más clara. Multi-Paxos puede ser más eficiente para workloads de alto throughput, pero la complejidad de implementación es significativamente mayor."}},{"@type":"Question","name":"¿EPaxos es realmente mejor que Raft en la práctica?","acceptedAnswer":{"@type":"Answer","text":"Depende de tu workload. EPaxos elimina el bottleneck del líder y logra menor latencia para comandos no conflictivos en deployments geo-distribuidos. Pero la complejidad de implementación es un orden de magnitud mayor, el protocolo de recovery es notoriamente difícil de implementar bien, y los comandos conflictivos pueden causar degradación significativa de performance."}},{"@type":"Question","name":"¿Cuál es la diferencia entre Paxos y Multi-Paxos?","acceptedAnswer":{"@type":"Answer","text":"Paxos clásico es un protocolo para acordar un solo valor. Multi-Paxos lo extiende a una secuencia de valores (un log replicado) eligiendo un líder estable que puede saltear la fase prepare para entries subsiguientes, amortizando el costo de la elección de líder a lo largo de muchas operaciones."}}],"@id":"https://lucioduran.com/es/blog/consensus-algorithms-raft-paxos-viewstamped#questions","url":"https://lucioduran.com/es/blog/consensus-algorithms-raft-paxos-viewstamped#questions","inLanguage":"es","isPartOf":{"@id":"https://lucioduran.com/es/blog/consensus-algorithms-raft-paxos-viewstamped#page"},"author":{"@id":"https://lucioduran.com/#person"}}]}],"contentHash":"b15915a1b11e374c4de9226842fb7ad01d842f2f103486fef7133a263a8ebb28","provenance":{"method":"Deterministic serialization of the server-rendered main element","source":"https://lucioduran.com/es/blog/consensus-algorithms-raft-paxos-viewstamped","hashAlgorithm":"sha256","hashScope":"JSON document fields before contentHash and provenance","sourceHTMLBytes":81157,"contentBytes":16524}}
