Compartir a través de


Tutorial: Creación de una caché de escritura subyacente mediante Azure Functions y Azure Cache for Redis

El objetivo de este tutorial es usar una instancia de Azure Cache for Redis como caché de escritura subyacente. El patrón de escritura subyacente de este tutorial muestra cómo se escriben en el desencadenador de caché las escrituras correspondientes en una base de datos SQL (una instancia del servicio de base de datos Azure SQL).

Se usa el Desencadenador de Redis para Azure Functions para implementar esta funcionalidad. En este escenario, verá cómo usar Azure Cache for Redis para almacenar información de inventario y precios, mientras realiza una copia de seguridad de esa información en una base de datos SQL.

Cada nuevo elemento o nuevo precio escrito en la memoria caché se refleja en una tabla SQL de la base de datos.

En este tutorial aprenderá a:

  • Configure una base de datos, un desencadenador y cadenas de conexión.
  • Compruebe que los desencadenadores funcionan.
  • Implemente código en una aplicación de función.

Requisitos previos

Creación y configuración de una nueva base de datos SQL

La base de datos SQL es la base de datos auxiliar de este ejemplo. Puede crear una instancia de base de datos de SQL a través del Azure Portal o a través del método de automatización que prefiera.

Para obtener más información sobre cómo crear una base de datos SQL, consulte Inicio rápido: Creación de una base de datos única: Azure SQL Database.

En este ejemplo se usa el portal:

  1. Escriba un nombre de base de datos y seleccione Crear nuevo para crear un nuevo servidor que contenga la base de datos.

    Captura de pantalla de la creación de un recurso de Azure SQL.

  2. Seleccione Usar autenticación de SQL y escriba un inicio de sesión de administrador y una contraseña. Asegúrese de recordar estas credenciales o anótelas. Al implementar un servidor en producción, use la autenticación de Microsoft Entra.

    Captura de pantalla de la información de autenticación de un recurso de Azure SQL.

  3. Vaya a la pestaña Redes y elija Punto de conexión público como método de conexión. Seleccione para ambas reglas de firewall que aparecen. Este punto de conexión permite el acceso desde la aplicación de funciones de Azure.

    Captura de pantalla del valor de conexión en red de un recurso de Azure SQL.

  4. Una vez finalizada la validación, seleccione Revisar y crear y, a continuación, Crear. La base de datos SQL comienza a implementarse.

  5. Una vez completada la implementación, vaya al recurso en el Azure Portal y seleccione la pestaña Editor de consultas. Cree una nueva tabla denominada inventario que contenga los datos que va a escribir en él. Utilice el siguiente comando SQL para crear una nueva tabla con dos campos:

    • ItemName muestra el nombre de cada elemento.
    • Price almacena el precio del elemento.
    CREATE TABLE inventory (
        ItemName varchar(255),
        Price decimal(18,2)
        );
    

    Captura de pantalla que muestra la creación de una tabla en el Editor de consultas de un recurso de Azure SQL.

  6. Una vez completado ese comando, expanda la carpeta Tabla y compruebe que se creó la nueva tabla.

Configuración del desencadenador de Redis

Primero, haga una copia del mismo proyecto de VS Code que usó en el tutorial anterior. Copie la carpeta del tutorial anterior con un nuevo nombre, como RedisWriteBehindTrigger y ábrala en VS Code.

En segundo lugar, elimine los archivos RedisBindings.cs y RedisTriggers.cs.

En este ejemplo, va a usar el desencadenador pub/sub para desencadenar las notificaciones en keyevent. Los objetivos del ejemplo son:

  • Desencadene cada vez que se produzca un evento SET. Un evento SET se produce cuando se escriben nuevas claves en la instancia de caché o se cambia el valor de una clave.
  • Una vez desencadenado un evento SET acceda a la instancia de caché para encontrar el valor de la nueva clave.
  • Determine si la clave ya existe en la tabla inventario en la base de datos SQL.
    • Si es así, actualice el valor de esa clave.
    • Si no es así, escriba una nueva fila con la clave y su valor.

Para configurar el desencadenador:

  1. Importe el paquete NuGet System.Data.SqlClient para habilitar la comunicación con la instancia de base de datos SQL. Vaya al terminal de VS Code y use el siguiente comando:

      dotnet add package System.Data.SqlClient
    
  2. Cree un nuevo archivo denominado RedisFunction.cs. Asegúrese de que ha eliminado los archivos RedisBindings.cs y RedisTriggers.cs.

  3. Copie y pegue el código siguiente en RedisFunction.cs para reemplazar el código existente:

using Microsoft.Extensions.Logging;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Extensions.Redis;
using System.Data.SqlClient;

public class WriteBehindDemo
{
    private readonly ILogger<WriteBehindDemo> logger;

    public WriteBehindDemo(ILogger<WriteBehindDemo> logger)
    {
        this.logger = logger;
    }
    
    public string SQLAddress = System.Environment.GetEnvironmentVariable("SQLConnectionString");

    //This example uses the PubSub trigger to listen to key events on the 'set' operation. A Redis Input binding is used to get the value of the key being set.
    [Function("WriteBehind")]
    public void WriteBehind(
        [RedisPubSubTrigger(Common.connectionString, "__keyevent@0__:set")] Common.ChannelMessage channelMessage,
        [RedisInput(Common.connectionString, "GET {Message}")] string setValue)
    {
        var key = channelMessage.Message; //The name of the key that was set
        var value = 0.0;

        //Check if the value is a number. If not, log an error and return.
        if (double.TryParse(setValue, out double result))
        {
            value = result; //The value that was set. (i.e. the price.)
            logger.LogInformation($"Key '{channelMessage.Message}' was set to value '{value}'");
        }
        else
        {
            logger.LogInformation($"Invalid input for key '{key}'. A number is expected.");
            return;
        }        

        // Define the name of the table you created and the column names.
        String tableName = "dbo.inventory";
        String column1Value = "ItemName";
        String column2Value = "Price";        
        
        logger.LogInformation($" '{SQLAddress}'");
        using (SqlConnection connection = new SqlConnection(SQLAddress))
            {
                connection.Open();
                using (SqlCommand command = new SqlCommand())
                {
                    command.Connection = connection;

                    //Form the SQL query to update the database. In practice, you would want to use a parameterized query to prevent SQL injection attacks.
                    //An example query would be something like "UPDATE dbo.inventory SET Price = 1.75 WHERE ItemName = 'Apple'".
                    command.CommandText = "UPDATE " + tableName + " SET " + column2Value + " = " + value + " WHERE " + column1Value + " = '" + key + "'";
                    int rowsAffected = command.ExecuteNonQuery(); //The query execution returns the number of rows affected by the query. If the key doesn't exist, it will return 0.

                    if (rowsAffected == 0) //If key doesn't exist, add it to the database
                 {
                         //Form the SQL query to update the database. In practice, you would want to use a parameterized query to prevent SQL injection attacks.
                         //An example query would be something like "INSERT INTO dbo.inventory (ItemName, Price) VALUES ('Bread', '2.55')".
                        command.CommandText = "INSERT INTO " + tableName + " (" + column1Value + ", " + column2Value + ") VALUES ('" + key + "', '" + value + "')";
                        command.ExecuteNonQuery();

                        logger.LogInformation($"Item " + key + " has been added to the database with price " + value + "");
                    }

                    else {
                        logger.LogInformation($"Item " + key + " has been updated to price " + value + "");
                    }
                }
                connection.Close();
            }

            //Log the time that the function was executed.
            logger.LogInformation($"C# Redis trigger function executed at: {DateTime.Now}");
    }
}

Importante

Este ejemplo se ha simplificado para el tutorial. Para su uso en producción, se recomienda usar consultas SQL parametrizadas para evitar ataques por inyección de código SQL.

Configurar cadenas de conexión

Debe actualizar el archivo local.settings.json para incluir la cadena de conexión de la instancia de base de datos SQL. Agregar una entrada en la Values sección de SQLConnectionString. El archivo debería tener un aspecto similar al de este ejemplo:

{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "",
    "FUNCTIONS_WORKER_RUNTIME": "dotnet-isolated",
    "redisConnectionString": "<redis-connection-string>",
    "SQLConnectionString": "<sql-connection-string>"
  }
}

Para buscar la cadena de conexión de Redis, vaya al menú de recursos del recurso Azure Cache for Redis. Busque la cadena en el área Claves de acceso en el menú Recurso.

Para buscar la cadena de conexión de la base de datos SQL, vaya al menú de recursos del recurso de base de datos SQL. En Configuración, seleccione Cadenas de conexión y, a continuación, seleccione la pestaña ADO.NET. La cadena está en el área ADO.NET (autenticación de SQL).

Debe escribir manualmente la contraseña de la cadena de conexión de base de datos SQL, ya que la contraseña no se pega automáticamente.

Importante

Este ejemplo se ha simplificado para el tutorial. Para su uso en producción, se recomienda usar Azure Key Vault para almacenar información de cadena de conexión o usar Azure Entra ID para la autenticación de SQL.

Compilación y ejecución del proyecto

  1. En VS Code, vaya a la pestaña Ejecutar y depurar y ejecute el proyecto.

  2. Vuelva a la instancia de Azure Cache for Redis en el Azure Portal y seleccione el botón Consola para escribir la consola de Redis. Pruebe a usar algunos comandos SET:

    • SET apple 5.25
    • SET bread 2.25
    • SET apple 4.50
  3. De nuevo en VS Code, los desencadenadores se están registrando. Para validar que los desencadenadores funcionan:

    1. Vaya a la base de datos SQL en el Azure Portal.

    2. En el menú de recursos, seleccione Editor de consultas.

    3. Para Nueva consulta, cree una consulta con el siguiente comando SQL para ver los 100 elementos principales en la tabla de inventario:

      SELECT TOP (100) * FROM [dbo].[inventory]
      

      Confirme que los elementos escritos en la instancia de Azure Cache for Redis aparecen aquí.

    Captura de pantalla que muestra que la información se ha copiado a SQL desde la instancia de caché.

Implementación del código en la aplicación de funciones

Este tutorial se basa en el tutorial anterior. Para obtener más información, consulte Implementación de código en una función de Azure.

  1. En VS Code, vaya a la pestaña Azure.

  2. Busque la suscripción y expándala. A continuación, busque la sección Aplicación de funciones y expándala.

  3. Seleccione y mantenga presionada (o haga clic con el botón derecho) su aplicación de funciones y, a continuación, seleccione Implementar en la aplicación de funciones.

Añadir información de cadena de conexión

Este tutorial se basa en el tutorial anterior. Para obtener más información sobre redisConnectionString, consulte Agregar información de cadena de conexión.

  1. Vaya a la aplicación de función en Azure Portal. En el menú de recursos, seleccione Variables de entorno.

  2. En el panel Configuración de la aplicación, escriba SQLConnectionString como un nuevo campo. En Valor escriba la cadena de conexión.

  3. Seleccione Aplicar.

  4. Vaya a la hoja Información general y seleccione Reiniciar para reiniciar la aplicación con la nueva información de cadena de conexión.

Comprobación de la implementación

Una vez finalizada la implementación, vuelva a la instancia de Azure Cache for Redis y use comandos SET para escribir más valores. Confirme que también aparecen en la base de datos SQL.

Si desea confirmar que la Aplicación de funciones funciona correctamente, vaya a la aplicación en el portal y seleccione la Secuencia de registro en el menú de recursos. Debe ver los desencadenadores que se ejecutan allí y las actualizaciones correspondientes que se realizan en la base de datos SQL.

Si alguna vez desea borrar la tabla de base de datos SQL sin eliminarla, puede usar la siguiente consulta SQL:

TRUNCATE TABLE [dbo].[inventory]

Limpieza de recursos

Si desea seguir usando los recursos que creó en este artículo, mantenga el grupo de recursos.

De lo contrario, si ya ha terminado con los recursos, puede eliminar el grupo de recursos de Azure que ha creado para evitar cargos.

Importante

La eliminación de un grupo de recursos es irreversible. Cuando elimine un grupo de recursos, todos los recursos contenidos en él se eliminan permanentemente. Asegúrese de no eliminar por accidente el grupo de recursos o los recursos equivocados. Si ha creado los recursos en un grupo de recursos existente que contiene recursos que desea conservar, puede eliminar cada recurso individualmente en lugar de eliminar el grupo de recursos.

Para eliminar un grupo de recursos

  1. Inicie sesión en Azure Portal y después seleccione Grupos de recursos.

  2. Seleccione el grupo de recursos que desea eliminar.

    Si hay muchos grupos de recursos, use el cuadro Filtro para cualquier campo... y escriba el nombre del grupo de recursos que creó para este artículo. Seleccione el grupo de recursos en la lista de resultados.

    Captura de pantalla que muestra una lista de grupos de recursos para eliminar en el panel de trabajo.

  3. Seleccione Eliminar grupo de recursos.

  4. Se le pedirá que confirme la eliminación del grupo de recursos. Escriba el nombre del grupo de recursos para confirmar y, después, seleccione Eliminar.

    Captura de pantalla que muestra un formulario que requiera el nombre del recurso para confirmar la eliminación.

Transcurridos unos instantes, el grupo de recursos y todos sus recursos se eliminan.

Resumen

Este tutorial y la Introducción a los desencadenadores de Azure Functions en Azure Cache for Redis muestran cómo usar Azure Cache for Redis para desencadenar aplicaciones de funciones de Azure. También muestran cómo usar Azure Cache for Redis como caché de escritura subyacente con Azure SQL Database. El uso de Azure Cache for Redis con Azure Functions es una combinación eficaz que puede resolver muchos problemas de integración y rendimiento.