教學課程:使用 Azure Functions 和 Azure Redis 建立寫入後置快取
本教學課程的目標是使用 Azure 受控 Redis(預覽版)或 Azure Cache for Redis 實例作為 寫入後置快取。 本教學課程中的寫入後置模式示範快取的寫入如何觸發 SQL 資料庫的對應寫入 (Azure SQL Database 服務的執行個體)。
您會使用 Azure Functions 的 Redis 觸發程序來實作此功能。 在此案例中,您會瞭解如何使用 Redis 來儲存庫存和定價資訊,同時備份 SQL 資料庫中的資訊。
每個寫入快取的新項目或新價格都會反映在資料庫的 SQL 資料表中。
在本教學課程中,您會了解如何:
- 設定資料庫、觸發程序和連接字串。
- 驗證觸發程序是否正常運作。
- 將程式碼部署至函數應用程式。
必要條件
- Azure 訂用帳戶。 如果您沒有 Azure 訂用帳戶,請建立免費帳戶。
- 完成上一個教學課程: 開始使用 Azure Redis 中的 Azure Functions 觸發程式,並布建下列資源:
- Azure 受控 Redis (預覽版) 或 Azure Cache for Redis 實例
- Azure Functions 執行個體
- 使用 Azure SQL 的使用知識
- 已安裝 NuGet 套件的 Visual Studio Code (VS Code) 環境設定
建立並設定新的 SQL 資料庫
SQL 資料庫是此範例的備份資料庫。 您可透過 Azure 入口網站或偏好的自動化方法建立 SQL 資料庫。
如需建立 SQL 資料庫的詳細資訊,請參閱快速入門:建立單一資料庫 - Azure SQL Database。
此範例使用入口網站:
輸入資料庫名稱並選擇 [新建] 來建立新伺服器以保存資料庫。
選取 [使用 SQL 驗證],並輸入系統管理員登入和密碼。 請務必記住這些認證或將其寫下。 在實際執行環境中部署伺服器後,請改為使用 Microsoft Entra 驗證。
移至 [網路] 索引標籤,然後選擇 [公用端點] 作為連線方法。 針對顯示的兩個防火牆規則,選擇 [是]。 此端點允許從 Azure 函數應用程式進行存取。
驗證完成後,選擇 [檢閱 + 建立],然後選擇 [建立]。 SQL 資料庫開始部署。
部署完成後,請移至 Azure 入口網站中的資源,然後選擇 [查詢編輯器] 索引標籤。建立名為 [庫存] 的新資料表以保存所要寫入的資料。 使用下列 SQL 命令以建立新資料表,並包含下列兩個欄位:
ItemName
列出每個項目的名稱。Price
儲存項目的價格。
CREATE TABLE inventory ( ItemName varchar(255), Price decimal(18,2) );
命令完成執行後,請展開 [資料表] 資料夾並驗證已建立新的資料表。
設定 Redis 觸發程序
首先建立上一個教學課程 (部分機器翻譯) 所使用相同 VS Code 專案的複本。 在新的名稱下複製上一個教學課程的資料夾,例如 RedisWriteBehindTrigger,並在 VS Code 中開啟。
其次,刪除 RedisBindings.cs 和 RedisTriggers.cs 檔案。
在此範例中,您會使用 pub/sub 觸發程序以在 keyevent
通知上觸發。 範例的目標如下:
- 每次發生
SET
事件時觸發。 當新索引鍵寫入至快取執行個體或變更索引鍵值時,便會發生SET
事件。 - 觸發
SET
事件後,存取快取執行個體以尋找新索引鍵值。 - 判斷 SQL 資料庫的 [庫存] 資料表是否已有該索引鍵。
- 若有,則值為該索引鍵。
- 若無,則使用索引鍵和其值寫入新的資料列。
若要設定觸發程序:
匯入
System.Data.SqlClient
NuGet 套件以啟用與 SQL 資料庫的通訊。 移至 VS Code 終端並使用下列命令:dotnet add package System.Data.SqlClient
建立名為 RedisFunction.cs 的新檔案。 請確定您已刪除 RedisBindings.cs 和 RedisTriggers.cs 檔案。
將下列程式碼複製並貼至 RedisFunction.cs 以取代現有程式碼:
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}");
}
}
重要
針對教學課程,已簡化此範例。 針對實際執行環境使用,建議您使用參數化 SQL 查詢以防止 SQL 插入式攻擊。
設定連接字串
您必須更新 local.settings.json 檔案以包含 SQL 資料庫的連接字串。 在 Values
區段新增 SQLConnectionString
的項目。 您的檔案看起來應該像下列範例:
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "",
"FUNCTIONS_WORKER_RUNTIME": "dotnet-isolated",
"redisConnectionString": "<redis-connection-string>",
"SQLConnectionString": "<sql-connection-string>"
}
}
若要尋找 Redis 連接字串,請移至 Azure 受控 Redis 或 Azure Cache for Redis 資源中的資源功能表。 在 [資源] 功能表的 [存取金鑰] 區域中找到字串。
若要尋找 SQL 資料庫連接字串,請移至 SQL 資料庫資源中的資源功能表。 在 [設定] 下,選擇 [連接字串],然後選擇 [ADO.NET] 索引標籤。字串位於 [ADO.NET (SQL 驗證)] 區域。
您必須手動輸入 SQL 資料庫連接字串的密碼,因為不會自動貼上密碼。
重要
針對教學課程,已簡化此範例。 若要使用生產環境,建議您使用 Azure 金鑰保存庫 來儲存 連接字串 資訊,或使用 Azure Microsoft Entra ID 進行 SQL 驗證。
建置和執行專案
在 VS Code 中,移至 [執行和偵錯] 索引標籤並執行專案。
返回 Azure 入口網站 中的 Redis 實例,然後選取 [主控台] 按鈕以輸入 Redis 主控台。 嘗試使用一些指令
SET
:SET apple 5.25
SET bread 2.25
SET apple 4.50
返回 VS Code,觸發程序正在註冊。 若要驗證觸發程序是否正常運作:
移至 Azure 入口網站中的 SQL 資料庫。
在資源功能表上,選擇 [查詢編輯器]。
針對 [新增查詢],使用下列 SQL 命令建立查詢以檢視庫存資料表中的前 100 個項目:
SELECT TOP (100) * FROM [dbo].[inventory]
確認寫入 Redis 實例的專案會出現在這裡。
將程式碼部署至函數應用程式
本教學課程會以上一個教學課程為基礎來建置。 如詳細資訊,請參閱將程式碼部署至 Azure 函數。
在 VS Code 中,移至 [Azure] 索引標籤。
尋找訂用帳戶並將其展開。 然後,尋找 [函數應用程式] 並展開該區段。
選擇並保存 (或以滑鼠右鍵按一下) 函數應用程式,然後選擇 [部署至函數應用程式]。
新增連接字串資訊
本教學課程會以上一個教學課程為基礎來建置。 如需 redisConnectionString
的詳細資訊,請參閱新增連接字串資訊。
移至 Azure 入口網站中的函數應用程式。 在資源功能表上,選取 [環境變數]。
在 [應用程式設定] 窗格中,輸入 SQLConnectionString 作為新欄位。 針對 [值],輸入連接字串。
選取套用。
移至 [概觀] 窗格,然後選取 [重新啟動] 以使用新的連接字串資訊重新啟動應用程式。
驗證部署
部署完成之後,請返回您的 Redis 實例,並使用 SET
命令來撰寫更多值。 確認這些值顯示在 SQL 資料庫中。
如果您要確認函數應用程式正常運作,請移至入口網站中的應用程式並從資源功能表選擇 [記錄資料流]。 您應在這裡看到觸發程序正在執行並正在對 SQL 資料庫進行對應更新。
如果您要清除 SQL 資料庫資料表而不加以刪除,您可使用下列 SQL 查詢:
TRUNCATE TABLE [dbo].[inventory]
清除資源
如果您想要繼續使用在本文中建立的資源,請保留該資源群組。
否則,若已完成資源使用,則可刪除您建立的 Azure 資源群組,以避免衍生費用。
重要
刪除資源群組是無法回復的動作。 當您刪除資源群組時,其中包含的所有資源都將永久刪除。 請確定您不會不小心刪除錯誤的資源群組或資源。 如果您是在包含需保留資源的現有資源群組內部建立資源,則可以個別刪除每個資源,而不必刪除整個資源群組。
刪除資源群組
登入 Azure 入口網站,然後選取 [資源群組]。
選取您想要刪除的資源群組。
如果有許多資源群組,請使用 [篩選任何欄位] 方塊,並輸入您針對本文所建立資源群組的名稱。 選取結果清單中的資源群組。
選取 [刪除資源群組]。
系統將會要求您確認是否刪除資源群組。 輸入您的資源群組名稱以進行確認,然後選取 [刪除]。
不久後,系統便會刪除該資源群組及其所有的資源。
摘要
本教學課程和 開始使用 Azure Redis 中的 Azure Functions 觸發程式會示範如何在 Azure 函式應用程式中使用 Redis 觸發程式和系結。 它們也會示範如何使用 Redis 作為 Azure SQL 資料庫 的回寫快取。 搭配 Azure Functions 使用 Azure 受控 Redis 或 Azure Cache for Redis 是一個功能強大的組合,可解決許多整合和效能問題。