Tutorial: Erstellen eines Write-Behind-Cache mithilfe von Azure Functions und Azure Redis
Das Ziel dieses Tutorials besteht darin, eine Azure Managed Redis-Instanz (Vorschau) oder Azure Cache for Redis-Instanz als Write-Behind-Cache zu verwenden. Das Write-Behind-Muster in diesem Tutorial zeigt, wie Schreibvorgänge in den Cache entsprechende Schreibvorgänge in eine SQL-Datenbank (eine Instanz des Azure SQL-Datenbank-Diensts) auslösen.
Sie verwenden den Redis-Trigger für Azure Functions, um diese Funktionalität zu implementieren. In diesem Szenario sehen Sie, wie Redis verwendet wird, um Bestands- und Preisinformationen zu speichern. Gleichzeitig werden diese Informationen in einer SQL-Datenbank gesichert.
Jedes neue Element oder jeder neue Preis, das bzw. der in den Cache geschrieben wird, wird dann in einer SQL-Tabelle in der Datenbank wiedergegeben.
In diesem Tutorial lernen Sie Folgendes:
- Konfigurieren einer Datenbank, eines Triggers und von Verbindungszeichenfolgen
- Überprüfen, ob Trigger funktionieren
- Bereitstellen von Code in einer Funktions-App
Voraussetzungen
- Ein Azure-Abonnement. Wenn Sie kein Azure-Abonnement besitzen, können Sie ein kostenloses Konto erstellen.
- Abschluss des vorherigen Tutorials Erste Schritte mit Azure Functions-Triggern in Azure Redis mit den folgenden bereitgestellten Ressourcen:
- Eine Azure Managed Redis-Instanz (Vorschau) oder Azure Cache for Redis-Instanz
- Azure Functions-Instanz
- Fundierte Kenntnisse in Bezug auf die Verwendung von Azure SQL
- VS Code-Umgebung (Visual Studio Code), eingerichtet mit installierten NuGet-Paketen
Erstellen und Konfigurieren einer neuen SQL-Datenbank
Die SQL-Datenbank ist die Sicherungsdatenbank für dieses Beispiel. Sie können eine SQL-Datenbank-Instanz über das Azure-Portal oder über Ihre bevorzugte Automatisierungsmethode erstellen.
Weitere Informationen zum Erstellen einer SQL-Datenbank finden Sie unter Schnellstart: Erstellen einer Einzeldatenbank – Azure SQL-Datenbank.
In diesem Beispiel wird das Portal verwendet:
Geben Sie einen Datenbanknamen ein, und wählen Sie Neu erstellen aus, um einen neuen Server für die Datenbank zu erstellen.
Wählen Sie SQL-Authentifizierung verwenden aus, und geben Sie einen Administratoranmeldenamen und das Kennwort ein. Sie müssen sich diese Anmeldeinformationen merken oder notieren. Wenn Sie einen Server in der Produktion bereitstellen, verwenden Sie stattdessen die Microsoft Entra-Authentifizierung.
Wechseln Sie zur Registerkarte Netzwerk, und wählen Sie Öffentlicher Endpunkt als Verbindungsmethode aus. Wählen Sie Ja für beide angezeigten Firewallregeln aus. Dieser Endpunkt ermöglicht den Zugriff über Ihre Azure-Funktions-App.
Wählen Sie nach Abschluss der Überprüfung Überprüfen + erstellen und dann Erstellen aus. Die SQL-Datenbank wird bereitgestellt.
Wechseln Sie nach Abschluss der Bereitstellung zur Ressource im Azure-Portal, und wählen Sie die Registerkarte Abfrage-Editor aus. Erstellen Sie eine neue Tabelle namens Bestand, die die von Ihnen geschriebenen Daten aufnimmt. Verwenden Sie den folgenden SQL-Befehl, um eine neue Tabelle mit zwei Feldern zu erstellen:
ItemName
listet die Namen der einzelnen Elemente auf.Price
speichert den Preis der Elemente.
CREATE TABLE inventory ( ItemName varchar(255), Price decimal(18,2) );
Erweitern Sie nach Abschluss dieses Befehls den Ordner Tabellen, und überprüfen Sie, ob die neue Tabelle erstellt wurde.
Konfigurieren des Redis-Triggers
Erstens: Erstellen Sie eine Kopie des VS Code-Projekts, das Sie im vorherigen Tutorial verwendet haben. Kopieren Sie den Ordner aus dem vorherigen Tutorial unter einen neuen Namen, z. B. RedisWriteBehindTrigger, und öffnen Sie ihn in VS Code.
Zweitens: Löschen Sie die Dateien RedisBindings.cs und RedisTriggers.cs.
In diesem Beispiel verwenden Sie den Pub/Sub-Trigger, um keyevent
-Benachrichtigungen auszulösen. Die Ziele des Beispiels sind:
- Auslösung bei jedem
SET
-Ereignis. EinSET
-Ereignis tritt auf, wenn neue Schlüssel in die Cache-Instanz geschrieben werden oder der Wert eines Schlüssels geändert wird. - Nachdem ein
SET
-Ereignis ausgelöst wurde, greifen Sie auf die Cache-Instanz zu, um den Wert des neuen Schlüssels zu ermitteln. - Ermitteln Sie, ob der Schlüssel bereits in der Tabelle Bestand in der SQL-Datenbank vorhanden ist.
- Wenn ja, aktualisieren Sie den Wert dieses Schlüssels.
- Wenn nicht, schreiben Sie eine neue Zeile mit dem Schlüssel und dem zugehörigen Wert.
So konfigurieren Sie den Trigger
Importieren Sie das NuGet-Paket
System.Data.SqlClient
, um die Kommunikation mit der SQL-Datenbank zu ermöglichen. Wechseln Sie zum VS Code-Terminal, und verwenden Sie den folgenden Befehl:dotnet add package System.Data.SqlClient
Erstellen Sie eine neue Datei mit dem Namen RedisFunction.cs. Stellen Sie sicher, dass Sie die Dateien RedisBindings.cs und RedisTriggers.cs gelöscht haben.
Kopieren Sie dann den folgenden Code, und fügen Sie ihn in RedisFunction.cs ein, um den vorhandenen Code zu ersetzen:
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}");
}
}
Wichtig
Dieses Beispiel wurde für das Tutorial vereinfacht. Für die Verwendung in der Produktion wird empfohlen, parametrisierte SQL-Abfragen zu verwenden, um Angriffe durch Einschleusung von SQL-Befehlen zu verhindern.
Konfigurieren von Verbindungszeichenfolgen
Sie müssen die Datei local.settings.json aktualisieren, um die Verbindungszeichenfolge für Ihre SQL-Datenbank einzuschließen. Fügen Sie einen Eintrag im Abschnitt Values
für SQLConnectionString
. Die Datei sollte wie dieses Beispiel aussehen:
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "",
"FUNCTIONS_WORKER_RUNTIME": "dotnet-isolated",
"redisConnectionString": "<redis-connection-string>",
"SQLConnectionString": "<sql-connection-string>"
}
}
Um die Redis-Verbindungszeichenfolge zu ermitteln, wechseln Sie zum Ressourcenmenü in der Azure Managed Redis- oder Azure Cache for Redis-Ressource. Suchen Sie die Zeichenfolge im Bereich Zugriffsschlüssel im Menü „Ressource“.
Um die Verbindungszeichenfolge der SQL-Datenbank zu ermitteln, wechseln Sie zum Ressourcenmenü in der SQL-Datenbankressource. Wählen Sie unter Einstellungen die Option Verbindungszeichenfolgen und dann die Registerkarte ADO.NET aus. Die Zeichenfolge befindet sich im Bereich ADO.NET (SQL-Authentifizierung).
Sie müssen das Kennwort für die Verbindungszeichenfolge Ihrer SQL-Datenbank manuell eingeben, da das Kennwort nicht automatisch eingefügt wird.
Wichtig
Dieses Beispiel wurde für das Tutorial vereinfacht. Für die Verwendung in der Produktion wird empfohlen, Azure Key Vault zum Speichern von Verbindungszeichenfolgeninformationen oder Azure Microsoft Entra ID für die SQL-Authentifizierung zu verwenden.
Erstellen und Ausführen des Projekts
Wechseln Sie zur Registerkarte Ausführen und debuggen in VS Code, und führen Sie das Projekt aus.
Navigieren Sie zurück zur Redis-Instanz im Azure-Portal, und wählen Sie die Schaltfläche Konsole aus, um die Redis-Konsole aufzurufen. Probieren Sie einige der
SET
-Befehle aus:SET apple 5.25
SET bread 2.25
SET apple 4.50
Wichtig
Das Konsolentool ist für Azure Managed Redis noch nicht verfügbar. Verwenden Sie stattdessen redis-cli oder ein Tool wie Redis Insights, um Befehle direkt in der Redis-Instanz auszuführen.
Wieder zurück in VS Code werden die Trigger registriert. So überprüfen Sie, ob die Trigger funktionieren
Wechseln Sie zur SQL-Datenbank im Azure-Portal.
Wählen Sie dann im Menü „Ressource“ die Option Abfrage-Editor aus.
Erstellen Sie unter Neue Abfrage eine Abfrage mit dem folgenden SQL-Befehl, um die 100 wichtigsten Elemente in der Bestandstabelle anzuzeigen:
SELECT TOP (100) * FROM [dbo].[inventory]
Vergewissern Sie sich, dass die in Ihre Redis-Instanz geschriebenen Elemente hier angezeigt werden.
Bereitstellen des Codes in Ihrer Funktions-App
Dieses Tutorial baut auf dem vorherigen Tutorial auf. Weitere Informationen finden Sie unter Bereitstellen von Code in einer Azure-Funktion.
Wechseln Sie in VS Code zur Registerkarte Azure.
Suchen Sie Ihr Abonnement, und erweitern Sie es. Navigieren Sie dann zum Abschnitt Funktions-App, und erweitern Sie diesen.
Wählen Sie Ihre Funktions-App bei gedrückter Maustaste aus (oder klicken Sie mit der rechten Maustaste darauf), und wählen Sie dann In Funktions-App bereitstellen aus.
Informationen zur Verbindungszeichenfolge hinzufügen
Dieses Tutorial baut auf dem vorherigen Tutorial auf. Weitere Informationen zu redisConnectionString
finden Sie unter Informationen zur Verbindungszeichenfolge hinzufügen.
Navigieren Sie im Azure-Portal zu Ihrer Funktions-App. Wählen Sie im Ressourcenmenü die Option Umgebungsvariablen aus.
Geben Sie im Bereich App-Einstellungen SQLConnectionString als neues Feld ein. Geben Sie unter Wert Ihre Verbindungszeichenfolge an.
Wählen Sie Übernehmen.
Wechseln Sie zum Blatt Übersicht, und wählen Sie Neustarten aus, um die App mit den neuen Verbindungszeichenfolgeninformationen neu zu starten.
Überprüfen der Bereitstellung
Wenn die Bereitstellung abgeschlossen ist, kehren Sie zu Ihrer Redis-Instanz zurück, und verwenden Sie SET
-Befehle, um weitere Werte zu schreiben. Vergewissern Sie sich, dass sie auch in Ihrer SQL-Datenbank angezeigt werden.
Wenn Sie überprüfen möchten, ob Ihre Funktions-App ordnungsgemäß funktioniert, wechseln Sie im Portal zur App, und wählen Sie im Menü „Ressource“ die Option Protokollstream aus. Sie sollten sehen, dass die Trigger ausgeführt werden und dass die entsprechenden Aktualisierungen an Ihrer SQL-Datenbank vorgenommen werden.
Wenn Sie die SQL-Datenbanktabelle bereinigen möchten, ohne sie zu löschen, können Sie die folgende SQL-Abfrage verwenden:
TRUNCATE TABLE [dbo].[inventory]
Bereinigen von Ressourcen
Wenn Sie die in diesem Artikel erstellten Ressourcen weiterhin verwenden möchten, behalten Sie die Ressourcengruppe bei.
Wenn Sie die Ressourcen nicht mehr benötigen, können Sie die erstellte Azure-Ressourcengruppe ansonsten löschen, um Kosten zu vermeiden.
Wichtig
Das Löschen einer Ressourcengruppe kann nicht rückgängig gemacht werden. Beim Löschen einer Ressourcengruppe werden alle darin enthaltenen Ressourcen unwiderruflich gelöscht. Achten Sie daher darauf, dass Sie nicht versehentlich die falsche Ressourcengruppe oder die falschen Ressourcen löschen. Falls Sie die Ressourcen in einer vorhandenen Ressourcengruppe erstellt haben, die Ressourcen enthält, die Sie behalten wollen, können Sie jede Ressource einzeln löschen, statt die Ressourcengruppe zu löschen.
So löschen Sie eine Ressourcengruppe
Melden Sie sich beim Azure-Portal an, und wählen Sie anschließend Ressourcengruppen aus.
Wählen Sie die Ressourcengruppe aus, die Sie löschen möchten.
Wenn viele Ressourcengruppen vorhanden sind, verwenden Sie das Feld Nach einem beliebigen Feld filtern..., und geben Sie den Namen Ihrer Ressourcengruppe ein, die Sie für diesen Artikel erstellt haben. Wählen Sie die Ressourcengruppe in der Ergebnisliste aus.
Wählen Sie die Option Ressourcengruppe löschen.
Sie werden aufgefordert, das Löschen der Ressourcengruppe zu bestätigen. Geben Sie den Namen Ihrer Ressourcengruppe ein, und wählen Sie Löschen aus.
Daraufhin werden die Ressourcengruppe und alle darin enthaltenen Ressourcen gelöscht.
Zusammenfassung
In diesem Tutorial und unter Erste Schritte mit Azure Functions-Triggern in Azure Redis erfahren Sie, wie Sie Redis-Trigger und -bindungen in Azure-Funktions-Apps verwenden. Außerdem wird gezeigt, wie Sie Redis als Write-Behind-Cache mit Azure SQL-Datenbank verwenden. Die Verwendung von Azure Managed Redis oder Azure Cache for Redis mit Azure Functions ist eine leistungsstarke Kombination, mit der Sie viele Integrations- und Leistungsprobleme lösen können.