PostgreSQL y la configuración de coherencia de escritura para cada conexión específica.

La traducción del artículo ha sido preparada especialmente para los estudiantes del curso «Bases de Datos». ¿Te interesa desarrollarte en esta área? Te invitamos a Día de Puertas Abiertas, donde hablaremos en detalle sobre el programa, las características del formato online, las competencias y las perspectivas de carrera que esperan a los graduados tras completar su formación.

PostgreSQL y la configuración de coherencia de escritura para cada conexión específica.

PostgreSQL y la configuración de coherencia de escritura para cada conexión específica.
En Compose, tratamos con muchas bases de datos, lo que nos brinda la oportunidad de conocer más de cerca su funcionalidad y desventajas. A medida que aprendemos a apreciar las características funcionales de las nuevas bases de datos, a veces comenzamos a pensar en cómo sería ideal que tales funciones estuvieran presentes también en las herramientas más maduras con las que hemos trabajado durante mucho tiempo. Una de las nuevas características que me gustaría ver en PostgreSQL es la consistencia de escritura configurada por conexión en todo el clúster. Y, como resultó, ya la tenemos, y hoy queremos compartir con ustedes información sobre cómo pueden utilizarla.

¿Por qué necesito esto?

El comportamiento de un clúster depende de tu aplicación. Tomemos, por ejemplo, una aplicación para pagos de facturas. Necesitarás una consistencia del cien por ciento en el clúster, por lo que tendrás que habilitar los commits sincrónicos para que tu base de datos espere a que se realicen todos los cambios. Sin embargo, si tu aplicación es una red social en rápido desarrollo, seguramente preferirás una respuesta rápida a la consistencia total. Para lograr esto, puedes utilizar commits asíncronos en tu clúster.

Conozcan el compromiso

Deberás llegar a un compromiso entre la consistencia de los datos y el rendimiento. PostgreSQL tiende hacia la consistencia, ya que la configuración predeterminada en este caso resulta predecible y sin sorpresas inesperadas. Ahora, vamos a conocer los compromisos.

Compromiso 1: Rendimiento

Si un clúster de PostgreSQL no requiere consistencia, puede funcionar de manera asíncrona. La escritura se realiza en el líder del clúster, y sus réplicas recibirán las actualizaciones después de algunos milisegundos. Cuando el clúster de PostgreSQL requiere consistencia, debe funcionar de manera sincrónica. La escritura se realizará en el líder del clúster, que enviará la actualización a las réplicas y esperará la confirmación de que cada una ha realizado la escritura, antes de enviar la confirmación al cliente que inició la escritura, informando que fue exitosa. La diferencia práctica entre estos enfoques es que el método asíncrono requiere dos saltos en la red, mientras que el sincrono requiere cuatro.

Compromiso 2: Consistencia

El resultado en caso de falla en el líder en estos dos enfoques también será diferente. Si la operación se realiza de manera asíncrona, al ocurrir tal error, no todas las escrituras estarán registradas por las réplicas. ¿Cuánto se perderá? Depende de la propia aplicación y la eficiencia de la replicación. La replicación de Compose impedirá que una réplica se convierta en líder si la cantidad de información en ella es 1 MB menor que en el líder, lo que significa que potencialmente se pueden perder hasta 1 MB de registros durante el funcionamiento asíncrono.

En modo sincrónico, esto no ocurre. Si el líder falla, todas las réplicas se actualizan, ya que cualquier escritura confirmada en el líder debe ser confirmada en las réplicas. Ahí está la consistencia.

El comportamiento sincrónico tiene sentido en una aplicación para pagos de facturas, donde la consistencia tiene una ventaja clara al buscar un compromiso entre consistencia y rendimiento. Lo más importante para tal aplicación son los datos válidos. Y ahora, recuerda una red social, donde el objetivo principal es retener la atención del usuario, respondiendo a las consultas lo más rápido posible. En tal caso, el rendimiento, con menos saltos en la red y menos espera por confirmaciones, será la prioridad. Sin embargo, el compromiso entre rendimiento y consistencia no es el único que se debe considerar.

Compromiso 3: Fallos

Es muy importante entender cómo se comporta el clúster durante una falla. Consideremos la situación en la que una o más réplicas fallan. Cuando los commits se procesan de forma asincrónica, el líder seguirá funcionando, es decir, aceptando y procesando entradas sin esperar las réplicas faltantes. Cuando las réplicas regresan al clúster, se ponen al día con el líder. Con la replicación sincrónica, si las réplicas no responden, el líder no tendrá otra opción y continuará esperando la confirmación del commit hasta que la réplica vuelva al clúster y pueda aceptar y confirmar la entrada.

¿Una conexión por transacción?

Cada aplicación necesita un tipo especial de combinación de consistencia y rendimiento. A menos que sea nuestra aplicación de pago de facturas, que imaginamos totalmente consistente, o nuestra aplicación casi efímera de redes sociales. En todos los demás casos, habrá momentos en que algunas operaciones deben ser sincrónicas y otras asincrónicas. Puede que no quiera que el sistema espere hasta que el mensaje enviado en el chat sea confirmado, pero si en la misma aplicación se está realizando un pago, habrá que esperar.

Todas estas decisiones, por supuesto, las toma el desarrollador de la aplicación. Las decisiones correctas sobre cuándo aplicar cada enfoque ayudarán a maximizar el clúster. Es importante que el desarrollador pueda alternar entre ellos a nivel de SQL para conexiones y transacciones.

Implementación del control en la práctica

Por defecto, PostgreSQL asegura consistencia. Esto se controla mediante el parámetro del servidor synchronous_commit. Por defecto, está en la posición on, pero tiene tres otras opciones: local, remote_write o off.

Al establecer el parámetro en off se detienen todos los commits sincrónicos, incluso en el sistema local. El parámetro en local define el modo sincrónico para el sistema local, pero las entradas en las réplicas se realizan de forma asincrónica. Remote_write va un paso más allá: las entradas en las réplicas se realizan de forma asincrónica, pero retornan cuando la réplica ha aceptado la entrada, aunque no la haya escrito en disco.

Al considerar el rango de opciones disponible, elegimos el comportamiento y, recordando que on son registros sincrónicos, seleccionaremos local para commits asincrónicos por la red, manteniendo los commits locales como sincrónicos.

Ahora, les explicaremos cómo configurarlo en un abrir y cerrar de ojos, pero imagine que hemos instalado synchronous_commit en local para el servidor. Nos preguntamos si se puede modificar el parámetro synchronous_commit sobre la marcha, y resultó que no solo se puede, hay hasta dos maneras de hacerlo. La primera es configurar la sesión de su conexión de la siguiente manera:

SET SESSION synchronous_commit TO ON;  
// Sus escrituras van aquí

Todas las escrituras posteriores en la sesión confirmarán las operaciones de escritura para las réplicas antes de devolver un resultado positivo al cliente conectado. A menos que, por supuesto, cambie la configuración synchronous_commit de nuevo. Se puede omitir la parte SESSION en el comando, ya que tendrá el valor predeterminado.

La segunda forma es buena cuando solo desea asegurarse de obtener replicación síncrona para una transacción. En muchas bases de datos de la generación "NoSQL", el concepto de transacciones no existe, pero sí en PostgreSQL. En este caso, inicia una transacción y luego establece synchronous_commit en on antes de realizar la escritura para la transacción. COMMIT confirmará la transacción usando cualquier valor del parámetro synchronous_commit, que se haya establecido en ese momento, aunque es mejor establecer la variable de antemano para asegurarse de que otros desarrolladores entiendan que las escrituras no son asíncronas.

BEGIN;  
SET LOCAL synchronous_commit TO ON;  
// Sus escrituras van aquí
COMMIT;  

Todos los commits de transacciones ahora serán confirmados, como escritos en las réplicas, incluso antes de que la base de datos devuelva una respuesta positiva al cliente conectado.

Configuración de PostgreSQL

Antes de esto, imaginábamos un sistema de PostgreSQL con synchronous_commit, instalado en local. Para que esto sea real en el lado del servidor, necesitará establecer dos parámetros de configuración del servidor. Otro parámetro synchronous_standby_names entrará en juego cuando synchronous_commit esté en on. Define qué réplicas tienen derecho a commits síncronos, y lo estableceremos en *, lo que significará habilitar todas las réplicas. Estos valores generalmente se configuran en el archivo de configuración agregando:

synchronous_commit = local  
synchronous_standby_names='*'

Al establecer el parámetro synchronous_commit en local, creamos un sistema en el que los discos locales permanecen sincronizados, pero los commits de las réplicas de red son asíncronos por defecto. A menos que, por supuesto, decidamos hacer esos commits síncronos, como se muestra arriba.

Si han seguido el desarrollo del proyecto Governor, es posible que haya notado algunos cambios recientes (1, 2), que permitieron a los usuarios de Governor probar estos parámetros y controlar su coherencia.

Un par de palabras más…

Literalmente, hace una semana, le diría que no era posible ajustar PostgreSQL tan finamente. Fue entonces cuando Kurt, un miembro del equipo de plataforma de Compose, insistió en que tal posibilidad existía. Acalló mis objeciones y encontró en la documentación de PostgreSQL lo siguiente:

PostgreSQL y la configuración de coherencia de escritura para cada conexión específica.

Este parámetro puede ser modificado en cualquier momento. El comportamiento para cualquier transacción se determina por la configuración vigente al momento del commit. Por lo tanto, es posible y útil tener commits síncronos para algunas transacciones, mientras que para otras son asíncronos. Por ejemplo, para hacer que una multistatement transacción realice commits de forma asíncrona, cuando el valor del parámetro por defecto sea opuesto, establezca SET LOCAL synchronous_commit TO OFF dentro de la transacción.

Con esta pequeña modificación en el archivo de configuración, brindamos a los usuarios la capacidad de controlar su coherencia y rendimiento.

Fuente: habr.com

Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS 🔥 Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS | ProHoster