問題描述
Azure Redis作為微軟雲提供的一種PaaS服務,由於PaaS的特性,服務端的安裝和維護、修補、升級等操作均由平臺放負責。雖然終端使用者只需要關注當前服務的使用,但是後臺的升級和補丁行為,總會對使用Redis服務產生影響。如:Azure Redis的“故障轉移 Failover”就是專為此類行為設計的功能。
故障轉移的說明
當Redis的副本節點將其自身提升為主節點,且舊主節點關閉現有連線時,將發生故障轉移。 主節點重新啟動後,它將自身降級為副本節點。 故障轉移可以是計劃性的,也可以是非計劃的。
計劃性故障轉移發生在系統更新(例如 Redis 修補或 OS 升級)和管理操作(例如縮放和重啟)過程中。 由於節點會提前收到更新通知,因此它們可以協作交換角色,並在更改後快速更新負載均衡器。 計劃性故障轉移通常可在 1 秒內完成。
發生非計劃性故障轉移的可能原因是硬體故障、網路故障或主節點的其他意外中斷。 副本節點可將自身提升為主節點,但該過程需要更長時間。 副本節點必須先檢測到其主節點不可用,然後才能啟動故障轉移過程。 副本節點還必須驗證此非計劃性故障不是暫時性的或區域性性的,以避免不必要的故障轉移。 檢測時出現的這種延遲意味著非計劃性故障轉移通常要在 10 到 15 秒內完成。
所以在Redis發生故障,升級時,在前端使用Redis時,雖然受影響的時間非常的短,但是還是會有所影響。所以當前端Redis收到異常訊息時候,如何快速的定位是否Redis由升級行為呢?
解決辦法
使用Redis的“事件(Events)”功能頁面,配置Event Grid,傳送補丁完成事件到接收端,如Webhook, Azure Storage Queue, Function等,方式非常的多。
當前,Redis Events支援四種事件:
- ExportRDBCompleted :匯出快取資料時觸發
- ImportRDBCompleted :匯入快取資料時觸發
- PatchingCompleted :修補完成時觸發
- ScalingCompleted :縮放完成後觸發
使用PatchingCompleted事件,則可以在更新,升級完成後,收到來自Redis服務端的訊息。此外,也需要針對快取設定“計劃更新”。 告知Redis管理服務在指定的每週時段應用 Redis 執行時修補程式。 通常,這些時段是客戶端應用程式流量較低的時段,目的是避免潛在的事件。
操作步驟
因本文在測時並無法得知何時有升級事件發生,所以以下操作步驟中,以ScallingCompleted事件做為結果演示。並且在演示中使用的儲存佇列方式來接收事件訊息,這裡也可以使用其他方式,此處只作為一個演示。
一:建立Redis的Event Grid訂閱,並配置儲存佇列作為接收端
- 需要提前準備好在配置中需要的 儲存賬號 和 佇列 資訊,如示例中使用的為:backuptest01 和redisupdatequeue01
- 自定義訂閱事件的名稱
- 選擇訂閱Redis的事件,如這裡全部選擇了Redis的四個事件
- 選擇終結點型別。
二:觸發Scalling 操作。在儲存佇列中檢視結果
補充說明
一:在Redis發生故障轉移,對客戶端的影響和如何減少影響?
Redis客戶端遇到的錯誤數目取決於故障轉移時該連線上掛起的運算元目。 在連線中斷時,許多客戶端庫可能會引發不同型別的錯誤,包括超時異常、連線異常或套接字異常。 例如,在發生故障轉移時傳送了請求但未收到響應的操作可能會收到超時異常。 對關閉的連線物件發出的新請求將收到連線異常,直到重新連線成功為止。
由於故障轉移不可完全避免,因此,客戶端應用程式需要使用重試機制,大多數的Redis客戶端都支援重試機制。在 Microsoft.NET 和其他物件導向的語言中,可以使用 Lazy<T> 模式來重新建立連線,而無需重啟應用程式。
private static Lazy<ConnectionMultiplexer> CreateMultiplexer() { return new Lazy<ConnectionMultiplexer>(() => ConnectionMultiplexer.Connect(connectionString)); } private static void CloseMultiplexer(Lazy<ConnectionMultiplexer> oldMultiplexer) { if (oldMultiplexer != null) { try { oldMultiplexer.Value.Close(); } catch (Exception) { // Example error condition: if accessing old.Value causes a connection attempt and that fails. } } }
更多訊息,請檢視Redis故障轉移和修補文件:https://docs.azure.cn/zh-cn/azure-cache-for-redis/cache-failover
二:如何設定Redis的計劃更新功能?
使用“計劃更新”邊欄選項卡可以為快取例項指定維護時段。 藉助維護時段,可以控制在一週中的哪一天和哪個時間點更新託管快取的 VM。 Azure Cache for Redis 將盡最大努力在定義的指定時間範圍內啟動和完成 Redis 伺服器軟體的更新。詳見:https://docs.azure.cn/zh-cn/azure-cache-for-redis/cache-administration#schedule-updates
三:Redis Event Grid事件中訊息體內容格式
PatchingCompleted 事件
[{ "id":"9b87886d-21a5-4af5-8e3e-10c4b8dac73b", "eventType":"Microsoft.Cache.PatchingCompleted", "topic":"/subscriptions/{subscription_id}/resourceGroups/{resource_group_name}/providers/Microsoft.Cache/Redis/{cache_name}", "data":{ "name":"PatchingCompleted", "timestamp":"2020-12-09T21:50:19.9995668+00:00", "status":"Succeeded"}, "subject":"PatchingCompleted", "dataversion":"1.0", "metadataVersion":"1", "eventTime":"2020-12-09T21:50:19.9995668+00:00"}]
ScalingCompleted 事件
[{ "id":"9b87886d-21a5-4af5-8e3e-10c4b8dac73b", "eventType":"Microsoft.Cache.ScalingCompleted", "topic":"/subscriptions/{subscription_id}/resourceGroups/{resource_group_name}/providers/Microsoft.Cache/Redis/{cache_name}", "data":{ "name":"ScalingCompleted", "timestamp":"2020-12-09T21:50:19.9995668+00:00", "status":"Succeeded"}, "subject":"ScalingCompleted", "dataversion":"1.0", "metadataVersion":"1", "eventTime":"2020-12-09T21:50:19.9995668+00:00"}]
跟多全面的事件訊息體,請參考 Azure Redis事件網格源: https://docs.microsoft.com/zh-cn/azure/event-grid/event-schema-azure-cache#the-contents-of-an-event-response
參考資料
Redis 的故障轉移和修補:https://docs.azure.cn/zh-cn/azure-cache-for-redis/cache-failover
Redis計劃更新:https://docs.azure.cn/zh-cn/azure-cache-for-redis/cache-administration#schedule-updates
什麼是事件網格(Event Grid):https://docs.microsoft.com/zh-cn/azure/event-grid/overview?WT.mc_id=Portal-HubsExtension
Redis 事件網格源:https://docs.microsoft.com/zh-cn/azure/event-grid/event-schema-azure-cache#the-contents-of-an-event-response