Arquitectura de software distribuida - transacciones distribuidas TCC y SAGA

asuntos de TCC

TCC es otro mecanismo común de transacciones distribuidas, es la abreviatura de " Try-Confirm-Cancel

Aunque la cola de mensajes confiable presentada anteriormente puede garantizar que el resultado final sea relativamente confiable y que el proceso sea lo suficientemente simple (en comparación con TCC), todo el proceso no tiene aislamiento en absoluto y el aislamiento es irrelevante en algunas empresas, pero hay algunos negocios donde la falta de aislamiento puede causar muchos problemas. Por ejemplo, en el ejemplo de escenario de este capítulo, un problema obvio causado por la falta de aislamiento es la "sobreventa": es muy posible que dos clientes hayan comprado con éxito el mismo producto en un corto período de tiempo y sus respectivas cantidades de compra. Ninguno de ellos supera el inventario actual, pero la suma de sus compras supera el inventario. Si este asunto está en una transacción rígida y el nivel de aislamiento es suficiente, se puede evitar por completo. Por ejemplo, el escenario anterior requiere el nivel de aislamiento de "Lectura repetible" para garantizar que las transacciones enviadas más tarde no estén disponibles porque los bloqueos causan fallas. , pero las colas de mensajes confiables no pueden garantizar esto. Esta parte pertenece al conocimiento de las transacciones locales de la base de datos, y puede consultar las explicaciones anteriores. Si el negocio requiere aislamiento, el arquitecto generalmente debe centrarse en el esquema TCC, que naturalmente es adecuado para transacciones distribuidas que requieren un fuerte aislamiento.

En términos de implementación específica, TCC es relativamente engorrosa. Es una solución de transacción intrusiva para el negocio que requiere que el proceso de procesamiento comercial se divida en dos subprocesos: "reservar recursos comerciales" y "confirmar/liberar recursos de consumo". Como el nombre de TCC indica, se divide en las siguientes tres fases.

  • Intente: en la etapa de intento de ejecución, complete todas las verificaciones ejecutables comerciales (garantice la consistencia) y reserve todos los recursos comerciales necesarios (garantice el aislamiento).
  • Confirmar: confirme la fase de ejecución, no realice ninguna verificación comercial y use directamente los recursos preparados en la fase Probar para completar el procesamiento comercial. La fase Confirmar puede ejecutarse repetidamente, por lo que las operaciones realizadas en esta fase deben ser idempotentes.
  • Cancelar: Cancela la fase de ejecución y libera los recursos de negocio reservados en la fase Try. La fase Cancelar puede ejecutarse repetidamente y debe ser idempotente.

De acuerdo con nuestro ejemplo de escenario, el proceso de ejecución de TCC debería ser como se muestra en la figura.
inserte la descripción de la imagen aquí

  1. El usuario final envía una solicitud de transacción a la librería de Fenix: compre una copia de "Comprensión profunda de la máquina virtual de Java" por valor de 100 yuanes.
  2. Cree una transacción, genere un ID de transacción, regístrelo en el registro de actividad e ingrese a la fase de prueba :
  • Servicio al usuario: verifique la viabilidad del negocio. Si es factible, configure los 100 yuanes del usuario en el estado "congelado" y notifique el siguiente paso para ingresar a la etapa Confirmar; si no es factible, notifique el siguiente paso para ingresar Cancelar escenario.
  • Servicio de almacén: compruebe la viabilidad del negocio, si es factible, configure una copia de "Comprensión profunda de la máquina virtual de Java" en el almacén en el estado "congelado" y notifique el siguiente paso para ingresar a la etapa Confirmar; si no es factible, notifique el siguiente paso para ingresar a la etapa Cancelar.
  • Servicios para comerciantes: Verifique la viabilidad comercial sin congelar recursos.
  1. Si todos los negocios en el paso 2 informan que el negocio es factible, registre el estado en el registro de actividad como Confirmar e ingrese a la etapa Confirmar :
  • Servicio al usuario: operaciones comerciales completas (deducir los 100 yuanes congelados).
  • Servicio de almacén: completar la operación comercial (marcar el 1 libro congelado como fuera de almacén, y descontar el inventario correspondiente).
  • Servicio comercial: completar la operación comercial (pago de 100 yuanes).
  1. Si se completa el tercer paso, la transacción se declarará como normal. Si ocurre alguna anomalía en el tercer paso, ya sea una anomalía comercial o una anomalía de la red, se repetirá la operación Confirmar del servicio de acuerdo con los registros en el registro de actividad, es decir, el trabajo duro máximo para entregar.
  2. Si alguna de las partes informa que el servicio no es factible en el paso 2, o si se agota el tiempo de espera de alguna de las partes, registre el estado del registro de actividad como Cancelar e ingrese a la fase Cancelar :
  • Servicio al usuario: cancelar la operación comercial (liberar los 100 yuanes congelados).
  • Servicio de almacén: cancelar operación comercial (liberar 1 libro que está bloqueado).
  • Servicios de comerciantes: cancelar operaciones comerciales (no es fácil consolar a los comerciantes para ganarse la vida después de un gran grito).
  1. Si se completa el paso 5, la transacción finalizará con una reversión de falla.Si ocurre alguna anomalía en el paso 5, ya sea una anomalía comercial o una anomalía de la red, la operación Cancelar del servicio se repetirá de acuerdo con los registros en el registro de actividad. Es decir, entrega de mejor esfuerzo.

Se puede ver en el proceso de operación anterior que TCC es en realidad un poco similar a la fase de preparación y la fase de envío de 2PC, pero TCC se encuentra en el nivel de código de usuario en lugar de en el nivel de infraestructura, lo que aporta una gran flexibilidad a su implementación. y se puede implementar según sea necesario Diseñe la granularidad del bloqueo de recursos. TCC solo opera recursos reservados durante la ejecución del negocio, apenas involucra bloqueos y contención de recursos, y tiene un alto potencial de rendimiento. Pero TCC no es puramente beneficioso. También trae mayores costos de desarrollo e intrusión comercial, lo que significa mayores costos de desarrollo y costos de reemplazo para reemplazar las implementaciones de transacciones. Por lo tanto, generalmente no confiamos completamente en la codificación simple. Para implementar TCC, se realiza en base a algunos middleware de transacciones distribuidas (como Seata , que es de código abierto de Ali), para reducir la carga de trabajo de codificación tanto como sea posible .

Asuntos SAGA

Las transacciones TCC tienen un fuerte aislamiento y evitan el problema del "overbooking", y su rendimiento es generalmente el más alto entre los varios modos de transacción flexibles mencionados en este artículo, pero aún no puede satisfacer todos los escenarios. La principal limitación de TCC es que su negocio es muy intrusivo. Esto no es para repetir la carga de trabajo que trajo la cooperación de desarrollo y codificación mencionada en la sección anterior, sino más bien para referirse a la controlabilidad técnica sobre la que requiere restricciones. Por ejemplo, modifique nuestro escenario de la siguiente manera: Debido a la creciente popularidad del pago en línea en China, los usuarios y comerciantes pueden optar por no abrir una cuenta de recarga en el sistema de la librería, al menos no se verán obligados a recargar del banco al sistema antes del consumo Se permite pagar directamente a través de U-shield o código de escaneo al comprar, y transferir el pago a la cuenta bancaria. Este requisito está totalmente en consonancia con el estado prevaleciente del pago en línea en China, pero agrega restricciones adicionales al diseño de transacciones del sistema: si el saldo de la cuenta de los usuarios y comerciantes es administrado por el banco, su autoridad de operación y estructura de datos no pueden definirse libremente. Por lo general, es imposible completar operaciones como congelar fondos, descongelar y deducir, porque los bancos generalmente no cooperarán con sus operaciones. Por lo tanto, la primera etapa Try en TCC a menudo es imposible de implementar. Solo podemos considerar otra solución de transacción flexible: la transacción SAGA. SAGA significa "larga historia, larga narrativa, larga serie de eventos" en inglés. Las transacciones SAGA se basan en la compensación de datos en lugar de la reversión .

El modelo de transacción SAGA tiene una historia muy larga y fue anterior al concepto de transacciones distribuidas. Se originó a partir de un artículo " SAGAS " publicado en ACM por Héctor García-Molina y Kenneth Salem de la Universidad de Princeton en 1987 . Este documento propone un método para mejorar la eficiencia operativa de la "Transacción de larga duración". La idea general es descomponer una transacción grande en una serie de conjuntos de subtransacciones que se pueden intercalar. Originalmente, el propósito de SAGA era evitar que las transacciones grandes bloquearan los recursos de la base de datos durante mucho tiempo. Más tarde, se convirtió en un patrón de diseño que descompone las transacciones grandes en un entorno distribuido en una serie de transacciones locales.

SAGA consta de dos partes de la operación.

  1. Dividir varias subtransacciones Una
    transacción grande divide varias transacciones pequeñas y descompone toda la transacción distribuida T en n subtransacciones, denominadas T1, T2, ..., Ti, ..., Tn. Cada subtransacción debe ser o puede ser considerada atómica. Si la transacción distribuida puede enviarse normalmente, su impacto en los datos (consistencia final) debe ser equivalente al envío continuo y secuencial de Ti.
  2. Diseñar acciones de compensación para cada subtransacción
    Diseñar acciones de compensación correspondientes para cada subtransacción, denominadas como C1, C2, ..., Ci, ..., Cn. Ti y Ci deben cumplir las siguientes condiciones:
    Tanto Ti como Ci son idempotentes.
    Ti y Ci cumplen la ley conmutativa (Conmutative), es decir, tanto si se ejecuta primero Ti como si primero se ejecuta Ci, el efecto es el mismo.
    Ci debe poder enviarse correctamente, es decir, independientemente de la situación en la que Ci no pueda enviarse y se revierta, si ocurre, debe continuar intentándolo hasta que tenga éxito o se requiera una intervención manual.
    Si T1 a Tn se envían con éxito, la transacción se completa con éxito; de lo contrario, se debe adoptar una de las siguientes dos estrategias de recuperación:
  • Recuperación hacia adelante (Recuperación hacia adelante) : si la transacción Ti no se confirma, se volverá a intentar Ti hasta que tenga éxito (entrega con el mejor esfuerzo). Este método de recuperación no requiere compensación y es adecuado para escenarios en los que la transacción finalmente debe tener éxito Por ejemplo, si el dinero se deduce de la cuenta bancaria de otra persona, debe enviarse a otra persona. El modo de ejecución de la recuperación directa es: T1, T2, ..., Ti (fallo), Ti (reintento), ..., Ti+1, ..., Tn.
  • Recuperación inversa (recuperación hacia atrás) : si la transacción de Ti no se confirma, ejecute Ci para compensar a Ti hasta que tenga éxito (entrega de mejor esfuerzo). Aquí se requiere que Ci se ejecute con éxito (después de reintentos continuos). El modo de ejecución de la recuperación inversa es: T1, T2, ..., Ti (fallo), Ci (compensación), ..., C2, C1.

En comparación con TCC, SAGA no necesita diseñar el estado congelado y las operaciones de descongelamiento de los recursos, y las operaciones de compensación suelen ser mucho más fáciles de implementar que las operaciones de congelamiento. Por ejemplo, en el escenario donde el saldo de la cuenta mencionada anteriormente se mantiene directamente en el banco, el pago se transfiere del banco al sistema de la Librería Fenix, este paso es para incitar al banco a brindar servicios a través de la operación de pago del usuario ( código de escaneo o protector USB); si la operación comercial posterior falla, aunque no podemos pedirle al banco que revoque la operación de transferencia de usuario anterior, es completamente factible que el sistema de la Librería Fenix ​​transfiera el pago a la cuenta del usuario como un medida de compensación.

SAGA debe asegurarse de que todas las subtransacciones se comprometan o compensen, pero el propio sistema SAGA puede colapsar, por lo que debe diseñarse como un mecanismo de registro similar a la base de datos (llamado SAGA Log) para garantizar que las subtransacciones puedan rastrearse después. el sistema se restablece Estado de ejecución, como qué paso se ha ejecutado o qué paso se ha compensado. Además, aunque las operaciones de compensación suelen ser más fáciles de implementar que la congelación/revocación, se requiere mucho esfuerzo para garantizar que los procesos de recuperación hacia adelante y hacia atrás se puedan llevar a cabo de manera rigurosa, por ejemplo, a través de la orquestación de servicios y colas de eventos confiables . Por lo general, las transacciones no se implementan directamente mediante codificación simple y, por lo general, se completan sobre la base del middleware de transacciones.El Seata mencionado anteriormente también es compatible con el modo de transacción SAGA .

La idea de reemplazar la reversión basada en la compensación de datos también se puede aplicar a otros esquemas de transacciones. No abriré secciones separadas para estos esquemas, y los explicaré juntos aquí. Para dar un ejemplo específico, por ejemplo, el "modo de transacción AT" propuesto por Ali's GTS (Global Transaction Service, Seata es código abierto de GTS) es una aplicación de este tipo.

en asuntos

En general, la transacción AT se implementa con referencia al protocolo de compromiso de dos etapas XA, pero por el defecto de XA 2PC, es decir, en la etapa de preparación, el coordinador debe esperar a que todas las fuentes de datos arrojen un resultado exitoso antes que el coordinador. puede emitir el comando Commit de manera uniforme Efecto de cubo (todos los bloqueos y recursos involucrados deben esperar hasta que se complete la transacción más lenta antes de que puedan liberarse de manera uniforme) y se diseña una solución específica.

El enfoque general es

  • Intercepte automáticamente todo el SQL cuando se envíen datos comerciales, guarde instantáneas del SQL antes y después de la modificación de datos, genere bloqueos de fila y envíelos a la fuente de datos operativos a través de transacciones locales, lo que equivale a registrar automáticamente el registro de rehacer y devolver Roll.
  • Si la transacción distribuida se envía correctamente, basta con limpiar los datos de registro correspondientes en cada fuente de datos; si es necesario revertir la transacción distribuida, genere automáticamente "SQL inverso" para obtener una compensación basada en los datos de registro.
  • Según este método de compensación, cada fuente de datos involucrada en una transacción distribuida se puede enviar por separado y luego los bloqueos y los recursos se liberan de inmediato. Este modo de envío asincrónico mejora en gran medida el nivel de rendimiento del sistema en comparación con 2PC.

El precio es que se sacrifica mucho el aislamiento, e incluso se afecta directamente la atomicidad .
Porque bajo la premisa de la falta de aislamiento, la sustitución de la reversión por compensación no siempre puede tener éxito.
Por ejemplo, después de que se confirme la transacción local y antes de que se complete la transacción distribuida, otras operaciones modifican los datos antes de compensarlos, es decir, se produce una escritura sucia (escritura sucia). esta vez, es imposible La compensación se realiza a través de SQL inverso automático, que solo puede manejarse mediante intervención manual.
En términos generales, se debe evitar la escritura sucia.Todas las bases de datos relacionales tradicionales aún deben bloquearse en el nivel de aislamiento más bajo para evitar la escritura sucia, porque una vez que se produce la escritura sucia, es realmente difícil para los humanos manejarla de manera efectiva. Por lo tanto, GTS agrega un mecanismo de **"Bloqueo global" (Global Lock) para lograr el aislamiento de escritura** Se requiere que antes de que se confirme la transacción local, se debe obtener el bloqueo global para el registro modificado antes de que se permita el envío. .No se obtiene el bloqueo global, hubo que esperar todo el tiempo antes.Este diseño, a costa de sacrificar cierto rendimiento, evita que la transacción local contenida en dos transacciones distribuidas modifique los mismos datos, evitando así la escritura sucia.

En términos de aislamiento de lectura , el nivel de aislamiento predeterminado de las transacciones AT es Lectura no confirmada (Lectura no confirmada) , lo que significa que pueden ocurrir lecturas sucias (Lectura sucia) . También puede usar la solución de bloqueo global para resolver el problema de aislamiento de lectura, pero si bloquea directamente la lectura, el costo será muy alto y, por lo general, no lo hará. Se puede ver que no existe una solución única para transacciones distribuidas, y la única forma efectiva es elegir una solución de procesamiento de transacciones adecuada de acuerdo con las condiciones locales.

Supongo que te gusta

Origin blog.csdn.net/zkkzpp258/article/details/131423327
Recomendado
Clasificación