一、概述
上篇文章介紹了基於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的問題
- 什麼是熱點key的問題
就是某個瞬間有大量的請求去訪問Redis上某個固定的key,導致快取擊穿,請求都打到了DB上,壓垮了快取服務和DB服務,從而影響到服務的可用性;
- 怎麼樣會成為熱點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,敬請期待。