基於木舟平臺淺談surging 的熱點KEY的解決方法

fanly11發表於2024-11-20

一、概述

上篇文章介紹了基於surging的木舟平臺如何構建起微服務 ,那麼此篇文章將介紹基於木舟平臺淺談surging 的熱點KEY的解決方法

木舟 (Kayak) 是什麼?

木舟(Kayak)是基於.NET6.0軟體環境下的surging微服務引擎進行開發的, 平臺包含了微服務和物聯網平臺。支援非同步和響應式程式設計開發,功能包含了物模型,裝置,產品,網路元件的統一管理和微服務平臺下的註冊中心,服務路由,模組,中間服務等管理。還有多協議適配(TCP,MQTT,UDP,CoAP,HTTP,Grpc,websocket,rtmp,httpflv,webservice,等),透過靈活多樣的配置適配能夠接入不同廠家不同協議等裝置。並且透過裝置告警,訊息通知,資料視覺化等功能。能夠讓你能快速建立起微服務物聯網平臺系統。

木舟kayal 平臺開源地址:https://github.com/microsurging/

surging 微服務引擎開源地址:https://github.com/fanliang11/surging(後面surging 會移動到microsurging進行維護)

二、快取熱點Key的問題

  1. 什麼是熱點key的問題
    就是某個瞬間有大量的請求去訪問Redis上某個固定的key,導致快取擊穿,請求都打到了DB上,壓垮了快取服務和DB服務,從而影響到服務的可用性;
  2. 怎麼樣會成為熱點Key

(1)、 QPS 集中訪問頻次佔比比較高的會被稱為熱點Key,木舟平臺會新增基於routepath訪問頻次統計,讓技術人員查詢出排名靠前的熱點KEY,

(2)、Value資料集合非常大導致頻寬佔用比較高會被稱為熱點KEY.

3.熱點KEY的危害

(1)、佔用頻寬影響其它服務呼叫

(2)、請求過大,降低了其它快取呼叫效能

(3)、快取擊穿,DB被壓垮,引起業務雪崩。

三、基於surging 如何解決熱點Key的問題

1.基於MemoryCache快取攔截

訪問頻次比較高,資料不經常修改,而無需其它微服務共享呼叫的時候就可以使用MemoryCache進行快取在本地,就比如木舟平臺首頁的產品,裝置,裝置訊息統計,如下圖

你可以新增以下特性就能開啟快取攔截,Mode選擇CacheTargetType.MemoryCache

        [ServiceCacheIntercept(CachingMethod.Get, Key = "GetProductStatistics", CacheSectionType = "ddlCache", EnableL2Cache = false, Mode = CacheTargetType.MemoryCache, Time = 1, EnableStageCache = true)]
        Task<ApiResult<ProductStatisticsModel>> GetProductStatistics();

刪除的時候就可以使用CachingMethod.Remove,傳入"GetProducts", "GetProductStatistics", 如果需要傳入其它引數值就可以新增_{0}_{1} ,比如 GetProductsByName_{0}

        [ServiceCacheIntercept(CachingMethod.Remove, "GetProducts", "GetProductStatistics", CacheSectionType = "ddlCache", Mode = CacheTargetType.MemoryCache, EnableStageCache = true)]
        [ServiceLogIntercept]
        Task<ApiResult<bool>> DeleteById(List<int> ids);

2. 基於redis 快取

訪問頻次比較高,資料不經常修改,但需其它微服務共享呼叫的時候就可以使用Redis進行快取,就比如獲取Token,就需要開啟redis快取攔截,可以在新增上新增,修改程式碼:Mode = CacheTargetType.Redis,如下圖:

        [ServiceCacheIntercept(CachingMethod.Get, Key = "GetProductStatistics", CacheSectionType = "ddlCache", EnableL2Cache = false, Mode = CacheTargetType.Redis, Time = 1, EnableStageCache = true)]
        Task<ApiResult<ProductStatisticsModel>> GetProductStatistics();

3.二級快取

訪問頻次比較高,資料會經常修改,Value資料集合非常大會導致佔用頻寬,這時候使用二級快取是最適合的,因為大的資料集合會透過二級本地快取讀取,一級快取儲存標誌位來管理二級快取的失效,程式碼如下

        [Metadatas.ServiceCacheIntercept(Metadatas.CachingMethod.Get, Key = "GetUserId_{0}", CacheSectionType = "ddlCache", L2Key= "GetUserId_{0}",  EnableL2Cache = true, Mode = Metadatas.CacheTargetType.Redis, Time = 480,EnableStageCache =true)]

4. 快取中介軟體的分片處理

快取中介軟體使用了雜湊一致性負載分流演算法,這樣就可以把不同的KEY分散到不同的服務節點上,也保證熱點KEY的集中訪問的問題,可以在cacheSettings配置檔案中新增redis服務節點,配置檔案程式碼如下:

{
  "CachingSettings": [
    {
      "Id": "ddlCache",
      "Class": "Surging.Core.Caching.RedisCache.RedisContext,Surging.Core.Caching",
      "InitMethod": "",
      "Maps": null,
      "Properties": [
        {
          "Name": "appRuleFile",
          "Ref": "rule",
          "Value": "",
          "Maps": null
        },
        {
          "Name": "dataContextPool",
          "Ref": "ddls_sample",
          "Value": "",
          "Maps": [
            {
              "Name": "Redis",
              "Properties": [
                {
                  "Name": null,
                  "Ref": null,
                  "Value": "127.0.0.1:6379::1",
                  "Maps": null
                },
                {
                  "Name": null,
                  "Ref": null,
                  "Value": "127.0.0.1:6379::1",
                  "Maps": null
                },
                {
                  "Name": null,
                  "Ref": null,
                  "Value": "127.0.0.1:6379::1",
                  "Maps": null
                }
              ]
            },
            {
              "Name": "MemoryCache",
              "Properties": null
            }
          ]
        },
        {
          "Name": "defaultExpireTime",
          "Ref": "",
          "Value": "120",
          "Maps": null
        },
        {
          "Name": "connectTimeout",
          "Ref": "",
          "Value": "120",
          "Maps": null
        },
        {
          "Name": "minSize",
          "Ref": "",
          "Value": "1",
          "Maps": null
        },
        {
          "Name": "maxSize",
          "Ref": "",
          "Value": "10",
          "Maps": null
        }
      ]
    },
    {
      "Id": "userCache",
      "Class": "Surging.Core.Caching.RedisCache.RedisContext,Surging.Core.Caching",
      "InitMethod": "",
      "Maps": null,
      "Properties": [
        {
          "Name": "appRuleFile",
          "Ref": "rule",
          "Value": "",
          "Maps": null
        },
        {
          "Name": "dataContextPool",
          "Ref": "ddls_sample",
          "Value": "",
          "Maps": [
            {
              "Name": "Redis",
              "Properties": [
                {
                  "Name": null,
                  "Ref": null,
                  "Value": "127.0.0.1:7000::1",
                  "Maps": null
                },
                {
                  "Name": null,
                  "Ref": null,
                  "Value": "127.0.0.1:7005::1",
                  "Maps": null
                },
                {
                  "Name": null,
                  "Ref": null,
                  "Value": "127.0.0.1:6379::1",
                  "Maps": null
                }
              ]
            },
            {
              "Name": "MemoryCache",
              "Properties": null
            }
          ]
        },
        {
          "Name": "defaultExpireTime",
          "Ref": "",
          "Value": "120",
          "Maps": null
        },
        {
          "Name": "connectTimeout",
          "Ref": "",
          "Value": "120",
          "Maps": null
        },
        {
          "Name": "minSize",
          "Ref": "",
          "Value": "1",
          "Maps": null
        },
        {
          "Name": "maxSize",
          "Ref": "",
          "Value": "10",
          "Maps": null
        }
      ]
    }
  ]
}

四、總結

木舟平臺api,ui已經開源釋出,後面陸續更新,等完成mqtt和國標28181裝置接入,會搭建官方網站和DEMO,敬請期待。

相關文章