Hechos Clave
- La mayoría de las bibliotecas de consenso (Raft, Paxos) tratan la máquina de estado como una caja negra pura.
- Si un líder falla después del efecto secundario pero antes de confirmarlo, ocurren duplicados.
- Chr2 usa un Buzón Replicado: Los efectos secundarios se almacenan como 'pendientes' en el estado replicado.
- El Vallado Durable usa un manifiesto persistido vía tmp+fsync+rename atómico para detener líderes zombis.
- Chr2 es un sistema CP, priorizando la seguridad sobre la disponibilidad.
Resumen Rápido
Bibliotecas de consenso estándar como Raft y Paxos generalmente ignoran lo que sucede después de que una entrada de registro es confirmada. Tratan la máquina de estado como una caja negra, asumiendo que la aplicación maneja el resto. Esta suposición se rompe cuando la aplicación debe disparar acciones externas, como cobrar una tarjeta de crédito, disparar un webhook o enviar un correo electrónico. Si un líder falla después de realizar la acción pero antes de que la confirmación se finalice, el sistema a menudo pierde el rastro de la operación. Cuando un nuevo líder asume el control, puede reejecutar el mismo comando, llevando a efectos secundarios duplicados.
Para resolver esto, se desarrolló una nueva biblioteca nombrada Chr2 para tratar los efectos secundarios a prueba de fallos como una característica principal en lugar de un añadido posterior. La filosofía central es asegurar que los efectos secundarios no solo se registren sino que se gestionen a través de un estricto ciclo de vida de ejecución. La biblioteca introduce un mecanismo de Buzón Replicado. En lugar de ejecutarse inmediatamente, los efectos secundarios se almacenan como artículos 'pendientes' dentro del estado replicado. La ejecución está estrictamente controlada; solo el líder activo tiene permitido ejecutar estos efectos, y debe hacerlo bajo un token de vallado específico.
Prevenir líderes 'zombis' —líderes antiguos que vuelven a estar en línea e intentan actuar— es crítico. Chr2 usa Vallado Durable para gestionar esto. Un archivo de manifiesto persiste el número de vista más alto usando operaciones atómicas (tmp+fsync+rename). Esto asegura que un líder antiguo no pueda despertar y ejecutar efectos obsoletos. Para garantizar consistencia durante la recuperación o repetición, el sistema proporciona un Contexto Determinista. El código de la aplicación recibe una semilla determinista de Generador de Números Aleatorios (RNG) y el tiempo de bloque directamente del registro, asegurando que repetir el registro produzca transiciones de estado idénticas. Finalmente, el Registro de Escritura Anticipada (WAL) es estricto: las entradas son CRCeadas y encadenadas por hash. Si se detecta corrupción, el sistema está diseñado para detenerse en lugar de adivinar. Si bien estas medidas proporcionan una fuerte seguridad, el sistema está explícitamente diseñado como un sistema CP (Consistencia/Tolerancia a Particiones), priorizando la seguridad sobre la disponibilidad y aceptando que los efectos secundarios serán al-menos-una-vez en lugar de estrictamente exactamente-una-vez.
El Problema con el Consenso Estándar
Los algoritmos de consenso son la columna vertebral de los sistemas distribuidos, permitiendo que múltiples servidores acuerden una secuencia de comandos. Las bibliotecas que implementan Raft y Paxos se utilizan ampliamente para este propósito. Sin embargo, estas bibliotecas típicamente se centran únicamente en la replicación de registros y la consistencia. Aseguran que todos los nodos acuerden el orden de las operaciones, pero no gestionan las consecuencias de esas operaciones. Esto se describe a menudo como tratar la máquina de estado como una 'caja negra'. La capa de consenso pasa el comando a la capa de aplicación y considera que su trabajo está hecho.
Esta separación de responsabilidades se vuelve problemática cuando la aplicación necesita interactuar con el mundo exterior. Las operaciones comunes incluyen:
- Cobrar la tarjeta de crédito de un cliente.
- Enviar una notificación por correo electrónico.
- Disparar un webhook a un servicio externo.
El peligro surge durante una falla del líder. Imagina que un líder recibe un comando para 'Cobrar $50'. Lo pasa a la aplicación, la cual contacta la pasarela de pago y cobra la tarjeta exitosamente. Sin embargo, antes de que el líder pueda replicar la entrada de registro a una mayoría de seguidores y confirmarla, falla. Los seguidores no saben que la operación se completó. Cuando se elige un nuevo líder, ve la entrada no confirmada y la ejecuta nuevamente. Al cliente se le cobra dos veces. Esta es la mentira de 'exactamente-una-vez' mencionada en la documentación: la verdadera ejecución exactamente-una-vez es increíblemente difícil de garantizar en la capa de consenso sin ayuda de la aplicación o un mecanismo especializado.
Cómo Chr2 Garantiza Seguridad ante Fallos
Chr2 aborda el problema integrando la gestión de efectos secundarios directamente en el mecanismo de consenso. Se aleja del modelo de caja negra hacia un sistema donde los efectos secundarios son ciudadanos de primera clase. La biblioteca logra esto a través de una combinación de cuatro mecanismos técnicos específicos diseñados para trabajar en conjunto.
Buzón Replicado
El cambio fundamental en Chr2 es la introducción de un Buzón Replicado. En lugar de ejecutar un efecto secundario inmediatamente y esperar que la entrada de registro se confirme, Chr2 almacena la intención como un estado 'pendiente' en el registro replicado. Esto significa que la solicitud para realizar una acción se replica a otros nodos como cualquier otro cambio de estado. Sin embargo, la ejecución real está desacoplada de la entrada de registro inicial. Solo el líder designado tiene permiso para ejecutar estos efectos pendientes, y lo hace bajo la protección de un token de vallado. Este token actúa como una prueba de autoridad, asegurando que solo el líder actual válido pueda disparar acciones externas.
Vallado Durable y Prevención de Zombis
Un riesgo significativo en los sistemas distribuidos es el 'líder zombi'. Esto ocurre cuando un líder es particionado de la red, se presume muerto y luego reaparece repentinamente. Si todavía cree que es el líder, podría intentar ejecutar operaciones que ya han sido manejadas por su sucesor. Chr2 previene esto usando Vallado Durable.
El sistema mantiene un archivo de manifiesto que registra el número de 'vista' más alto (esencialmente el mandato del líder). Cuando un líder cambia, este manifiesto se actualiza usando una secuencia específica de operaciones: escribir en un archivo temporal, forzar la sincronización al disco (fsync) y luego renombrar el archivo al nombre final (reemplazo atómico). Esto asegura que incluso si se pierde la energía durante la actualización, el estado permanezca consistente. Un líder antiguo que intente despertará encontrará que su número de vista es menor que el manifiesto persistido y se negará a ejecutar efectos.
Contexto Determinista para Repetición
Repetir el registro es un requisito estándar para recuperarse de fallos. Sin embargo, los efectos secundarios a menudo dependen de variables como marcas de tiempo o números aleatorios. Si estos cambian durante la repetición, la máquina de estado podría terminar en un estado diferente al anterior. Chr2 resuelve esto proporcionando un Contexto Determinista. Cuando el código de la aplicación necesita realizar una acción, recibe entradas específicas de la capa de consenso:
- Una semilla determinista de Generador de Números Aleatorios (RNG).
- El tiempo de bloque exacto del registro.
Debido a que estas entradas están fijadas por el historial del registro, repetir el registro siempre producirá el mismo resultado. Esto asegura transiciones de estado 1:1.
Registro de Escritura Anticipada (WAL) Estricto
La integridad de datos es primordial. Chr2 emplea un WAL Estricto. Cada entrada escrita en el registro está protegida por un CRC (Comprobación de Redundancia Cíclica) y encadenada por hash a la entrada anterior. Esto crea una cadena de datos verificable. Si se detecta corrupción en medio del registro, el sistema está diseñado para detenerse inmediatamente en lugar de intentar adivinar qué podrían haber sido los datos faltantes. Este enfoque 'falla-cerrada' previene que la corrupción de datos se propague a través del sistema.
Los Compromisos
Los sistemas distribuidos a menudo se rigen por el teorema CAP, que establece que un sistema puede garantizar solo dos de las tres propiedades: Consistencia, Disponibilidad y Tolerancia a Particiones. Chr2 está explícitamente diseñado como un sistema CP (Consistencia/Tolerancia a Particiones). Esto significa que prioriza la seguridad y la consistencia de los datos sobre la disponibilidad continua del servicio.
Al aceptar efectos secundarios al-menos-una-vez, Chr2 admite que la duplicación puede ocurrir en casos extremos (como un fallo doble inusual), pero garantiza que nunca se pierda una acción y que el estado nunca se corrompa. La responsabilidad de la deduplicación estricta (si es necesaria) se delega a las capas de recepción de datos (sink-side deduplication), que son generalmente más adecuadas para manejar esa lógica de negocio específica.
Esta elección de diseño contrasta con sistemas que prometen exactamente-una-vez a cualquier costo, a menudo sacrificando latencia o aumentando la complejidad drásticamente. Chr2 ofrece una vía más segura y predecible para operaciones críticas en entornos de alta concurrencia.
Conclusión
Chr2 representa una evolución en el diseño de bibliotecas de consenso al tratar los efectos secundarios como un problema de primera clase. A través de mecanismos como el Buzón Replicado, el Vallado Durable y el Contexto Determinista, ofrece una solución robusta a los problemas de duplicación y corrupción de datos que plagaban las implementaciones anteriores. Para ingenieros que construyen sistemas financieros o de misión crítica, Chr2 ofrece una garantía de seguridad que es difícil de ignorar.




