Capítulo 4. Trabajar con una base de datos relacional

Este trabajo se ha traducido utilizando IA. Agradecemos tus opiniones y comentarios: translation-feedback@oreilly.com

A estas alturas, deberías tener una buena idea de lo que es Cloud Run y de cómo puedes utilizarlo para ejecutar y escalar tus aplicaciones basadas en contenedores. Sin embargo, Cloud Run necesita datos para ser interesante; tanto si esos datos proceden del almacenamiento blob, de una base de datos o de otra API, incluso un contenedor sin servidor necesita datos. En este capítulo, te mostraré cómo utilizar una base de datos relacional con Cloud Run.

Una base de datos relacional es la forma más común de almacenar datos para tu aplicación. Quiero mostrarte cómo trabajar con Cloud SQL, una base de datos relacional gestionada en Google Cloud. Como servicio gestionado, Cloud SQL te quita muchas tareas operativas de encima. Es compatible con MySQL, PostgreSQL y SQL Server, motores de bases de datos comunes que puedes ejecutar en cualquier lugar. Si alguna vez decides migrar a otro proveedor, tendrás una salida.

En este capítulo, te ayudaré a empezar a utilizar Cloud SQL, te mostraré cómo implementar mi aplicación de demostración de la lista de tareas pendientes y exploraré las distintas formas de conectar un servicio Cloud Run a Cloud SQL.

Cloud Run puede escalar potencialmente hasta mil (o más) contenedores muy rápidamente. Esto puede crear cuellos de botella de rendimiento en los sistemas posteriores, como tu base de datos Cloud SQL. En la parte final de este capítulo, te explicaré por qué y te mostraré los distintos controles de que dispones para mantener tu base de datos en funcionamiento cuando se produzca una ráfaga de tráfico.

Presentación de la aplicación de demostración

La aplicación de demostración de este capítulo y del siguiente es una lista de tareas pendientes. Tiene una interfaz basada en navegador y guarda los elementos de las tareas en una base de datos MySQL . Existen muchas aplicaciones con un diseño similar; si has trabajado en un proyecto con una arquitectura parecida, te sentirás como en casa(Figura 4-1).

A Cloud Run service backed by a Cloud SQL database
Figura 4-1. Un servicio Cloud Run respaldado por una base de datos Cloud SQL

No he construido yo mismo el frontend. Estoy utilizando Todo-Backend, un proyecto que te permite mostrar una pila de tecnología backend. Sólo implementé su API de backend en Cloud Run con una aplicación Go, lo que me permite utilizar la interfaz de usuario preconstruida con ella.

El código fuente para construir la aplicación de demostración está en GitHub. Todo lo que tienes que hacer es clonar el repositorio y configurar la infraestructura. Te guiaré paso a paso en la configuración de tu propia versión de la aplicación(Figura 4-2).

Figura 4-2. La aplicación de demostración de este capítulo

Esto es lo que harás:

  1. Establece los requisitos previos.

  2. Crea una instancia de MySQL Cloud SQL.

  3. Conéctate a Cloud SQL para inicializar el esquema.

  4. Implementa la aplicación de demostración en Cloud Run.

Mientras te guío por los distintos pasos, ilustraré lo que ocurre y explicaré cómo funcionan las cosas bajo el capó.

Puedes ejecutar toda la aplicación localmente utilizando Docker Compose sin una dependencia de Google Cloud. El Capítulo 6 explora Docker Compose en mayor profundidad. Si sólo quieres probarlo, puedes iniciar la aplicación ejecutando docker-compose up en el directorio.

Creación de la Instancia SQL en la Nube

Los datos de la lista de tareas persistirán en MySQL, que es un servidor de base de datos relacional tradicional de código abierto, , que se ha utilizado para alimentar aplicaciones web durante más de dos décadas. Cloud SQL también es compatible con PostgreSQL y SQL Server: no estás limitado a MySQL. Como primer paso, habilita Cloud SQL en tu proyecto de Google Cloud:

gcloud services enable sqladmin.googleapis.com
gcloud services enable sql-component.googleapis.com

El siguiente paso es crear la instancia de Cloud SQL. Una instancia de Cloud SQL es una máquina virtual que ejecuta un servidor de base de datos. El servidor de base de datos puede ser MySQL, PostgreSQL o SQL Server, y gestiona una o varias bases de datos (las tablas y filas de datos reales).

Este comando create puede tardar algún tiempo (de tres a cinco minutos) en completarse. Asegúrate de utilizar la misma región en la que despliegas tus servicios Cloud Run(us-central1 en este ejemplo). Aunque puedes ejecutar tu instancia de Cloud SQL y tu servicio Cloud Run en regiones diferentes, aumentará la latencia de las consultas y los costes:

gcloud sql instances create sql-db \
--tier db-f1-micro \
--database-version MYSQL_8_0 \
--region us-central1

El comando crea una instancia MySQL (versión 8) llamada sql-db con el tipo de máquina (tier) más pequeño disponible-db-f1-micro-utilizando MySQL como servidor de base de datos. Aunque no lo utilizaríamos como instancia de producción, es perfecto para nuestra aplicación de ejemplo .

El tipo de máquina (nivel) es importante: la cantidad de CPU, RAM, y espacio en disco que aprovisiones desempeña un papel significativo en el rendimiento de tu aplicación. Generalmente, los discos más grandes tienen más operaciones de entrada/salida por segundo (IOPS) disponibles; suele tener sentido aprovisionar discos grandes para aprovecharlo. Pero no te preocupes demasiado por elegir el nivel y el tamaño de disco adecuados. Puedes redimensionar la instancia más adelante y activar el aumento automático de almacenamiento.

Nota

Cloud SQL no es sin servidor: se te cobra por cada minuto que esta instancia esté activa. A partir de septiembre de 2020, una instancia db-f1-micro cuesta alrededor de 9 $ (USD) si se deja funcionando durante un mes completo en us-central1. Consulta los precios para obtener información actualizada. En cuanto elimines la instancia, ya no se te cobrará (para saber cómo, consulta "Apagar ").

Comprender el proxy SQL en la nube

Puedes conectarte a Cloud SQL mediante una conexión directa o a través del proxy Cloud SQL, que creo que es la mejor forma de conectarse. Más adelante explicaré por qué es mejor. En primer lugar, quiero explicarte cómo funciona el Proxy SQL en la Nube(Figura 4-3).

Understanding Cloud SQL Proxy
Figura 4-3. Comprender el proxy SQL en la nube

Cloud SQL Proxy es un programa que puedes ejecutar en tu máquina local. Configurará automáticamente una conexión segura SSL/TLS con el Servidor Proxy de Cloud SQL, que se ejecuta en la instancia de Cloud SQL próxima al servidor de la base de datos.

El Servidor Proxy SQL en la Nube autentica las conexiones entrantes utilizando Cloud IAM. Profundizaré en Cloud IAM en el Capítulo 6, pero esto es lo que necesitas saber para entender este capítulo: utilizas Cloud IAM para vincular roles a una identidad. Un rol contiene una lista de permisos (cosas que puedes hacer). Una identidad es tu cuenta de usuario, y cada servicio de Cloud Run también tiene una identidad asignada, una cuenta de servicio. Las cuentas de servicio son identidades no personales (robot) en Google Cloud. Una máquina virtual Compute Engine también está asociada a una cuenta de servicio.

Uno de esos roles es "Cliente de Cloud SQL". Si una identidad tiene este rol , puede conectarse a todas las instancias de base de datos Cloud SQL del proyecto. Como tú creaste el proyecto de Google Cloud, tienes el rol de "Propietario" en el proyecto, que incluye los permisos para conectarte a las instancias de Cloud SQL.

Conectar y cargar el esquema

Ahora vas a crear las tablas que necesita la aplicación para ejecutarse. Empieza instalando el Proxy SQL de la Nube en tu máquina local utilizando gcloud:

gcloud components install cloud_sql_proxy

Utilizando el Proxy SQL de la Nube, puedes establecer una conexión con el servidor de bases de datos MySQL de . Seguirás necesitando el cliente MySQL para enviar comandos SQL. Los usuarios de Mac pueden instalar el cliente a través de Homebrew:

brew install mysql-client

Si utilizas otro sistema operativo, sigue los pasos de la documentación de MySQL para instalar el cliente de línea de comandos de MySQL.

Ahora deberías poder iniciar el programa cloud_sql_proxy y conectarte a utilizando el cliente MySQL. Sin embargo, por comodidad, puedes hacer que gcloud se encargue de esto por ti. (¿Por qué instalar las herramientas y no utilizarlas? Porque gcloud las utiliza bajo el capó). Si se te pide que introduzcas una contraseña, puedes dejar el mensaje en blanco y pulsar Intro inmediatamente:

gcloud beta sql connect sql-db --user root

Por defecto, una instancia SQL de MySQL Cloud tendrá un usuario root sin contraseña. Pronto te enseñaré a solucionar esto; no te preocupes. Deberías poder iniciar sesión y obtener un prompt de MySQL. Introduce el comando show databases para listar todas las bases de datos y asegurarte de que todo funciona:

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
4 rows in set (0.13 sec)

Escribe exit para cerrar la ventana y cerrar la sesión.

Ahora que has probado la conexión, puedes cargar el esquema de la base de datos para inicializar las tablas. En primer lugar, crea la base de datos, llamada todo:

gcloud sql databases create todo --instance sql-db

El esquema está en el repositorio con el código fuente de la aplicación. Clona el repositorio y abre el directorio. Ahora carga el archivo schema.sql utilizando gcloud (pulsa Intro de nuevo en el indicador de contraseña):

gcloud beta sql connect sql-db --user root < schema.sql

Ya has creado las tablas que la aplicación necesita para funcionar. Es hora de hacer algunas mejoras en la seguridad de la instancia de Cloud SQL.

Proteger al usuario por defecto

Por defecto, la instancia de MySQL tiene un superusuario, root, sin contraseña, y cualquier host (%) puede conectarse:

$: gcloud sql users list --instance sql-db
NAME  HOST
root  %

Estás protegido por un cortafuegos en la instancia de Cloud SQL, que detiene todo el tráfico entrante por defecto. Sin embargo, sigue habiendo un superusuario MySQL sin contraseña al que puede acceder cualquier host que esté detrás de ese cortafuegos. No sé a ti, pero a mí esto me incomoda. Elimina el usuario con este comando:

$: gcloud sql users delete root --host % --instance sql-db
root@% will be deleted. New connections can no longer be made using
this user. Existing connections are not affected.

Do you want to continue (Y/n)?

Deleting Cloud SQL user...done.

Ahora puedes volver a crear el usuario en la base de datos MySQL, y sólo podrá iniciar sesión a través del Proxy SQL en la Nube:

$: gcloud sql users create root \
--host "cloudsqlproxy~%" \
--instance sql-db Creating Cloud SQL user...done. Created user [root].

Utilizando la bandera --host, restrinjo al usuario para que sólo se conecte a través de la red llamada cloudsqlproxy. Esto aprovecha el hecho de que el servidor de base de datos MySQL y el Servidor Proxy de Cloud SQL comparten la misma red privada interna en la instancia de Cloud SQL, llamada cloudsqlproxy (como has visto en la Figura 4-3).

Lo que esto significa es que el Proxy SQL de la Nube gestiona la autenticación por nosotros. Si el usuario root inicia sesión en la instancia de MySQL, ahora tienes la certeza de que el inicio de sesión se originó a partir de una identidad con el rol de Cloud IAM "Cliente de Cloud SQL".

Nota

El nuevo usuario root que has creado tiene privilegios de superusuario. En el ejemplo de este capítulo, dejaré que la aplicación de demostración se conecte utilizando este usuario; en un sistema de producción de , debes aplicar el principio del menor privilegio y crear un usuario independiente sin permisos administrativos para tu aplicación y establecer una contraseña en el usuario root.

Ahora profundizaré un poco más en las distintas opciones de conexión a Cloud SQL desde Cloud Run. Cuando sepas cómo funciona, te mostraré cómo implementar la aplicación de demostración.

Conectar Cloud Run a Cloud SQL

El proxy de Cloud SQL que acabas de utilizar para conectarte y cargar el esquema también está disponible en Cloud Run como servicio integrado y gestionado(Figura 4-4). Hay otra forma de conectarse a Cloud SQL: utilizando una conexión directa. No creo que debas utilizarla, ya que requiere más orquestación para usarla de forma segura.

Si implementas o actualizas un servicio Cloud Run, puedes conectarlo a Cloud SQL utilizando la bandera --add-cloudsql-instances. Esto añadirá un archivo especial a tu contenedor en el directorio /cloudsql/.

Sé que puede parecer confuso, pero en un sistema basado en UNIX, puedes utilizar un archivo en lugar de un puerto para escuchar las conexiones entrantes. Es similar a abrir un puerto (como localhost:3306) y escuchar nuevas conexiones. El archivo se llama Socket de Dominio UNIX. Te mostraré cómo utilizarlo cuando despliegues la aplicación de demostración.

Connecting to Cloud SQL using the managed Cloud SQL Proxy
Figura 4-4. Conectarse a Cloud SQL utilizando el Cloud SQL Proxy gestionado

Desactivar la Conexión Directa

La otra forma de conectarse desde Cloud Run es a través de una conexión directa (directamente a la IP de la instancia de Cloud SQL). Aunque ciertamente hay casos de uso para una conexión directa, no recomiendo utilizarla desde Cloud Run.1 La conexión directa no está encriptada por defecto; puedes requerir SSL/TLS, pero eso significa que tendrás que generar certificados de cliente y hacerlos llegar a tu contenedor de Cloud Run de forma segura. La conexión directa siempre eludirá Cloud IAM, y tendrás que empezar a gestionar las reglas del cortafuegos de tu instancia de Cloud SQL.

Creo que estarás de acuerdo conmigo en que utilizar el Proxy SQL en la Nube es más cómodo y seguro que utilizar la conexión directa. Para añadir otra barrera que impida las conexiones directas, puedes exigir SSL/TLS para ellas:

gcloud sql instances patch --require-ssl sql-db

Con require-ssl configurado, mientras no generes certificados de cliente, nadie podrá utilizar una conexión directa para iniciar sesión.

Implementación de la aplicación de demostración

Con la base de datos en su sitio y el esquema cargado, ya estás listo para construir el contenedor e implementar la aplicación de demostración. Construye el contenedor y envíalo al Registro de Artefactos utilizando Cloud Build (yo estoy utilizando el repositorio cloud-run-book que creamos en el Capítulo 3). Construir el contenedor puede llevar un rato:

PROJECT=$(gcloud config get-value project)
IMAGE=us-docker.pkg.dev/$PROJECT/cloud-run-book/todo

gcloud builds submit --tag $IMAGE

Ya puedes implementar el contenedor en Cloud Run. Presta atención a REGION. Asegúrate de que coincide con la región donde desplegaste la instancia de base de datos Cloud SQL:

REGION=us-central1
DB_INSTANCE=$PROJECT\:$REGION\:sql-db

gcloud run deploy todo \
--add-cloudsql-instances $DB_INSTANCE \
--image $IMAGE \
--region $REGION \
--allow-unauthenticated \
--set-env-vars DB="mysql://root@unix(/cloudsql/$DB_INSTANCE)/todo"

La bandera --add-cloudsql-instances indica a Cloud Run que se conecte a una instancia de Cloud SQL, identificada por su nombre completo, que tiene el siguiente formato: (<project>:<region>:<instance>).

La propia aplicación sabrá cómo conectarse a CloudSQL a través del socket UNIX Domain Socket porque está pasando una cadena de conexión en la variable de entorno DB (--set-env-vars DB=...). Hablaré más sobre esto en la siguiente sección, pero antes, deberías comprobar si la aplicación de demostración funciona.

En cuanto la implementación se realice correctamente, puedes abrir la URL de tu nuevo servicio y rellenar tus tareas pendientes. Puedes comprobar si realmente aparecen en la base de datos con este comando:

$: gcloud beta sql connect sql-db --user root
Starting Cloud SQL Proxy 
[..SNIP..]
mysql> SELECT * FROM todo.todos;

Si muestra tus elementos pendientes, habrás creado correctamente la base de datos Cloud SQL, cargado el esquema y conectado el servicio Cloud Run.

Cadena de conexión

El formato que utilizo para esta cadena de conexión es el delpaquete Go-MySQL-Driver. Verás que incluye la ruta del socket del dominio: unix(/cloudsql/<project>:<region>:<instance>). Me gusta utilizar variables de entorno para pasar cadenas de conexión porque hace que la aplicación sea más portable. Un ejemplo está en el archivo docker-compose.yml (explicaré Docker Compose con más detalle en el Capítulo 6.)

IP pública y privada

Puedes crear una instancia de Cloud SQL con una IP pública y una IP privada. La opción predeterminada es utilizar una IP pública: tus instancias serán accesibles desde la Internet pública y estarán protegidas por el servidor proxy de Cloud SQL, el cortafuegos incorporado y SSL/TLS con un certificado de cliente (si necesitas SSL). Si quieres mejorar la postura de seguridad de tu instancia Cloud SQL y mejorar potencialmente la latencia, puedes elegir asignar sólo una IP privada a tu instancia Cloud SQL.

Una IP privada sólo es accesible desde dentro de tu red de Nube Privada Virtual (VPC) . Proporciona una red privada para los recursos de tu proyecto de Google Cloud, como una instancia de Cloud SQL, una instancia de Memorystore (lo veremos en el Capítulo 5), máquinas virtuales de Compute Engine y contenedores en Google Kubernetes Engine.

Como un servicio Cloud Run no forma parte de la VPC, necesitarás un Conector VPC para comunicarte con las IP privadas(Figura 4-5). Un Conector VPC crea una ruta de red entre los contenedores de tu servicio Cloud Run y las IP privadas de la VPC (incluida la IP privada de Cloud SQL). Sé que esto puede ser mucho para asimilar ahora mismo. En el próximo capítulo encontrarás una guía práctica para trabajar con un Conector VPC.

Puedes conectar Cloud Run a Cloud SQL utilizando --add-cloudsql-instances y el Socket de Dominio UNIX, protegido por IAM, independientemente de si utilizas una IP privada o pública.

Figura 4-5. Utilizar un conector VPC para comunicarse con IPs privadas

Limitar la concurrencia

Cloud Run, con su capacidad para escalar rápidamente, puede causar problemas con sistemas posteriores que no tengan capacidad para gestionar muchas peticiones al mismo tiempo. Un servidor de base de datos relacional tradicional, como MySQL, PostgreSQL o SQL Server, es un gran ejemplo: aunque incluso un servidor de base de datos pequeño puede manejar fácilmente 10.000 transacciones por segundo, no lo hace bien si la concurrencia de transacciones supera las 200.

Laconcurrencia de transacciones es el número de transacciones (consultas) que el servidor de la base de datos gestiona al mismo tiempo. Cuando aparecen más clientes para utilizar tu base de datos al mismo tiempo, aumenta la concurrencia de transacciones. Para obtener un buen rendimiento de tu servidor de base de datos, te conviene tener una concurrencia baja, en lugar de alta. La concurrencia óptima de transacciones es diferente para cada carga de trabajo, pero una heurística común es que sea un múltiplo pequeño del número de vCPUs de la máquina.

Cloud Run puede escalar rápidamente hasta mil instancias (o más mediante el aumento de cuota) y sobrecargar tu base de datos relacional. En esta sección, explicaré la mecánica y mostraré cómo puedes gestionar la concurrencia.

Concurrencia de transacciones

La Figura 4-6 muestra cómo se relacionan la concurrencia de transacciones y la tasa de transacciones. La tasa de transacciones se expresa como transacciones completadas por segundo (TPS). Se trata de un gráfico simplificado, pero los principios generales son válidos para todos los servidores de bases de datos relacionales que puedas utilizar en Cloud SQL.

Saturating a relational database with concurrent transactions
Figura 4-6. Saturar una base de datos relacional con transacciones concurrentes

El gráfico muestra lo que ocurre cuando empiezas a aumentar la concurrencia de transacciones añadiendo más clientes. Al principio, a medida que aumenta la concurrencia, la tasa de transacciones aumenta de forma constante. Sin embargo, en algún momento, la curva de la tasa de transacciones empieza a nivelarse hacia un máximo cuando la duración de las transacciones empieza a aumentar. En algún momento, la tasa de transacciones puede incluso empezar a disminuir cuando empiezan a agotarse las transacciones y se rechazan nuevas conexiones.

Es difícil encontrar un número exacto para la concurrencia óptima de transacciones. Depende de la base de datos (versión), de la forma y el tamaño de tus datos, y de las consultas que envíe tu aplicación. Las transacciones grandes con muchas consultas afectan a tu servidor de base de datos de forma diferente que un montón de sentencias SELECT pequeñas y centradas. Por si fuera poco, todos estos factores cambian con el tiempo, al igual que tu aplicación.

Contención de recursos

Como has visto en la Figura 4-6, cuando aumenta la concurrencia, la duración de la transacción empieza a subir a partir de cierto punto. La razón es la contención de recursos. La contención de recursos se produce cuando varias transacciones quieren utilizar un recurso compartido al mismo tiempo. Un recurso compartido pueden ser datos (como una fila, tabla o índice) o recursos del sistema (como la CPU o el disco). El sistema necesita emplear tiempo de procesamiento adicional para resolver la contención de recursos, lo que aumenta la duración de las transacciones.

Los bloqueos son una causa común de contención de recursos. Si una transacción necesita acceso exclusivo a un dato, el motor de la base de datos lo bloquea. Si otra transacción necesita acceso exclusivo al mismo tiempo, tiene que esperar.

Límites de escala y agrupación de conexiones

Te mostraré los distintos controles que puedes utilizar para limitar la concurrencia. Tendrás que encontrar una buena configuración para tu sistema experimentando en tu sistema de producción y monitorizando las métricas continuamente.

Hay dos formas de limitar la concurrencia de transacciones utilizando la configuración estándar. Echa un vistazo a la Figura 4-7.

Managing transaction concurrency with scaling boundaries and connection pools
Figura 4-7. Gestión de la concurrencia de transacciones con límites de escala y agrupaciones de conexiones

El límite de escalado de tu servicio Cloud Run es el primer control. Limita el número máximo de contenedores que Cloud Run añadirá, lo que a su vez limita la cantidad de solicitudes HTTP que puede gestionar simultáneamente un servicio Cloud Run.

Este comando gcloud establece el número máximo de contenedores en 100 para el servicio denominado todo:

gcloud run services update todo \
--max-instances 100

Si todos los contenedores están en uso, las peticiones se retienen en la cola de peticiones hasta que se libera una ranura de petición en un contenedor. Si la carga sigue aumentando, es posible que veas solicitudes rechazadas con un estado de respuesta HTTP 429.

Desde tu aplicación, puedes limitar aún más la concurrencia utilizando un pool de conexiones internas . Un pool de conexiones mantiene conexiones de larga duración con el servidor de la base de datos. Si el código de tu aplicación quiere enviar una consulta, toma prestada una conexión de la agrupación de conexiones exclusivamente y la devuelve cuando termina. De esta forma, puedes compartir una conexión entre varios hilos de solicitud. En la aplicación de demostración, establecí así el número máximo de conexiones abiertas:

db.SetMaxOpenConns(2)

Esta configuración limitará el número total de conexiones activas a Cloud SQL a un máximo de instancias × 2. Un grupo de conexiones pequeño se asegurará de que siempre haya hilos de solicitud listos para utilizar una conexión cuando se libere, por lo que, en este caso, "conexiones activas" equivale a concurrencia de transacciones.

Grupo de conexiones externas

Es posible que te encuentres con una situación en la que no puedas utilizar eficazmente pools de conexión internos para limitar la concurrencia. En este caso, puedes beneficiarte del uso de un pool de conexiones externas , como PgBouncer, en una máquina virtual Compute Engine delante de tu instancia SQL PostgreSQL Cloud. Se trata de una configuración avanzada, pero no quería ocultarte la solución: puede que la necesites.

Un pool de conexiones externo se ejecuta en un servidor y acepta conexiones de tu aplicación. Intercalará de forma transparente tus transacciones en un conjunto limitado de conexiones existentes a la base de datos descendente, igual que hace un pool de conexiones interno.

Chris Tippett ha puesto a disposición de un repositorio GitHub muy bien documentado que te muestra cómo se hace (para PostgreSQL). Tendrás que entender primero Terraform para darle sentido al repositorio (véase el Capítulo 8).

Un ejemplo real

Para poner todo esto en perspectiva con algunas cifras del mundo real, Quiero compartir un ejemplo del mundo real. Uno de nuestros clientes es www.yoursurprise.eu, que fabrica y vende regalos personalizados, como tazas, camisetas, álbumes de fotos y copas de champán con grabados personalizados. Envían productos a toda Europa (su sitio está localizado en 18 idiomas).

Les ayudé a trasladarse a Google Cloud cuando estaban abandonando su centro de datos local. El negocio de los regalos experimenta una fuerte estacionalidad. En torno al Día de la Madre, salen de las instalaciones de producción de YourSurprise muchos regalos en forma de corazón con impresiones fotográficas personalizadas. La temporada de vacaciones es otro periodo de máxima demanda. En diciembre de 2019, eso significó que, durante la hora punta, realizaron unas 10.000 transacciones MySQL por segundo. Ejecutan MySQL en el nivel db-n1-standard-16, una máquina Cloud SQL con 16 vCPUs. Su concurrencia óptima de transacciones resulta ser de unas 110, que es un pequeño múltiplo del número de vCPU de la instancia de Cloud SQL.

SQL en la nube en producción

Cloud SQL es un producto gestionado, y con él obtienes funciones listas para la producción. Las siguientes secciones exploran algunos de los aspectos más destacados.

Monitoreo

Utilizar un producto gestionado como Cloud SQL no te libera de todas las tareas operativas. Tendrás que monitorizar las instancias. Puedes utilizar el Monitoreo en la Nube para establecer alertas sobre el uso de la CPU. Si observas un aumento sostenido por encima de un determinado nivel, puede que necesites pasar a un nivel de instancia mayor.

Aumento automático del almacenamiento

Si activas esta función, Cloud SQL aumentará automáticamente la capacidad de almacenamiento de cuando tu disco se esté llenando. Es una alerta de monitoreo que puedes desactivar.

Alta disponibilidad

Cuando actives la alta disponibilidad, Cloud SQL creará dos instancias en zonas diferentes dentro de la misma región. Cuando la instancia primaria deja de responder, la secundaria toma el relevo. Este proceso de conmutación por error puede llevar algún tiempo, pero es más rápido que un reinicio de todo el servidor.

Para esta aplicación de demostración, una implementación de zona única estaba bien (es la predeterminada), pero en un entorno de producción, deberías activar la alta disponibilidad.

Cómo hacer que tu aplicación sea resistente a un breve tiempo de inactividad

Hay una advertencia importante: incluso en una configuración de alta disponibilidad, tu aplicación debe estar diseñada para resistir breves periodos de inactividad de alrededor de un minuto. Esto puede ocurrir durante una conmutación por error o durante el mantenimiento. Menciono esto porque es fácil suponer que el tiempo de inactividad no se producirá en una configuración de alta disponibilidad.

Utilizar un producto gestionado como Cloud SQL no te libera de las tareas operativas. Si sólo haces una cosa, asegúrate de activar las copias de seguridad automatizadas.

Cierre

La base de datos Cloud SQL que has creado en este capítulo está siempre encendida. Si te olvidas de pararla, se te cobrará.

Con gcloud sql instances listpuedes listar tus instancias Cloud SQL que están activas en este momento. Sólo debería aparecer la que has creado en este capítulo: sql-db. Elimina la instancia de Cloud SQL:

gcloud sql instances delete sql-db

También has creado otro servicio Cloud Run. Puedes mantenerlo: mientras no le envíes solicitudes, no se te cobrará.

Resumen

En este capítulo, has implementado una instancia de Cloud SQL y la has conectado a un servicio Cloud Run. Has aprendido sobre el Proxy de Cloud SQL: cómo puedes utilizarlo desde tu máquina local y que está integrado en Cloud Run.

El Proxy SQL en la Nube cifra automáticamente tu conexión y realiza la autenticación del cliente utilizando Cloud IAM. Es conveniente que no tengas que gestionar tú mismo los certificados.

También aprendiste que limitar la concurrencia es clave para gestionar el rendimiento de tus sistemas descendentes. Descubriste qué mecanismos de control puedes utilizar en el servicio Cloud Run y en tu aplicación para evitar que tu instancia Cloud SQL se sobrecargue cuando tu servicio gestione repentinamente una ráfaga de tráfico.

En el próximo capítulo, te mostraré cómo tratar las sesiones HTTP, otro aspecto importante de las aplicaciones web. Como Cloud Run utiliza contenedores desechables, necesitas almacenar los datos de sesión en una base de datos (o, alternativamente, en el cliente). Una forma de persistir las sesiones en Google Cloud es con Memorystore, una base de datos Redis gestionada. Te mostraré cómo conectar Memorystore a tu servicio Cloud Run utilizando un Conector VPC.

1 Aunque utilices una IP privada, no se recomienda utilizar conexiones no encriptadas.

Get Construir aplicaciones sin servidor con Google Cloud Run now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.