本地緩存更新方案探索

文章目錄

  • 本地緩存更新方案探索
    • 1 背景
    • 2 方案探索
      • 2.1 初始化
      • 2.2 實時更新
        • 2.2.1 長輪詢
          • 2.2.1.1 client
          • 2.2.2.2 server

本地緩存更新方案探索

1 背景

  • 大家在工作中是否遇到過某些業務數據需要頻繁使用,但是數據量不大的情況,一般就是幾十條甚至幾百條這種。
  • 一般的解決方案就是業務維護數據,然后同步redis緩存,C端使用緩存的數據。但是這里不免會出現大key/熱key的問題,另外還有緩存穿透、緩存擊穿等問題。
  • 那么接下來我們一起探索一下如何解決上述問題吧。

2 方案探索

  • 首先我們評估數據量,發現這類數據一般只有百條左右。那么在技術選型上使用本地緩存無疑是最好的方案。現在應對C端場景基本選型的都是Caffeine。詳見:https://blog.csdn.net/for62/article/details/147494533
  • 我們選擇了本地緩存一方面可以抗大流量,做到無狀態橫向擴容。另一方面可以提高服務穩定性降低tp99。
  • 那么接下來我們就要設計緩存一致性的實現方案了,如何將redis中的數據近實時同步到本地緩存,C端只讀本地緩存,可以降級讀redis。
  • 這里我們參考長輪詢實現配置中心的方案:https://mp.weixin.qq.com/s/YjvL0sUTGHxR3GJFqrP8qg。客戶端長輪詢監聽服務端數據變更,感知到數據變更后更新本地緩存數據。設計圖如下:
    在這里插入圖片描述

2.1 初始化

  • 這里我們先假設刷新本地緩存的方法為:LocalCacheRefresher.refresh();
    public void refresh() {Caffeine<String, Object> cacheInfo = getLocalCacheInstance();String redisCacheKey = getRedisCacheKey();Set<String> keys = redisCache.hKeys(redisCacheKey);for (String key : keys) {String data = redisCache.hGet(redisCacheKey, key);cacheInfo.put(key, data);}}
  • 服務啟動時數據加載
@Component
public class LocalCacheInitRunner implements ApplicationRunner {@Overridepublic void run(ApplicationArguments args) throws Exception {LocalCacheRefresher.refresh();}}

2.2 實時更新

2.2.1 長輪詢
  • 這里我們用長輪詢的方案監聽源數據的變更來刷新本地緩存。
2.2.1.1 client
@Slf4j
public class LongPollClient {private CloseableHttpClient httpClient;private RequestConfig requestConfig;public ConfigClient() {this.httpClient = HttpClientBuilder.create().build();// httpClient 客戶端超時時間要大于長輪詢約定的超時時間this.requestConfig = RequestConfig.custom().setSocketTimeout(6000).build();}public void longPolling(String url, String dataId) {String endpoint = url + "?dataId=" + dataId;HttpGet request = new HttpGet(endpoint);CloseableHttpResponse response = httpClient.execute(request);switch (response.getStatusLine().getStatusCode()) {case 200: {BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));StringBuilder result = new StringBuilder();String line;while ((line = rd.readLine()) != null) {result.append(line);}response.close();String configInfo = result.toString();log.info("dataId: [{}] changed, receive configInfo: {}", dataId, configInfo);longPolling(url, dataId);break;}// ② 304 響應碼標記配置未變更case 304: {log.info("longPolling dataId: [{}] once finished, configInfo is unchanged, longPolling again", dataId);longPolling(url, dataId);break;}default: {throw new RuntimeException("unExcepted HTTP status code");}}}
}
2.2.2.2 server
@RestController
@Slf4j
@SpringBootApplication
public class LongPollServer {@Dataprivate static class AsyncTask {// 長輪詢請求的上下文,包含請求和響應體private AsyncContext asyncContext;// 超時標記private boolean timeout;public AsyncTask(AsyncContext asyncContext, boolean timeout) {this.asyncContext = asyncContext;this.timeout = timeout;}}// guava 提供的多值 Map,一個 key 可以對應多個 valueprivate Multimap<String, AsyncTask> dataIdContext = Multimaps.synchronizedSetMultimap(HashMultimap.create());private ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat("longPolling-timeout-checker-%d").build();private ScheduledExecutorService timeoutChecker = new ScheduledThreadPoolExecutor(1, threadFactory);// 配置監聽接入點@RequestMapping("/listener")public void addListener(HttpServletRequest request, HttpServletResponse response) {String dataId = request.getParameter("dataId");// 開啟異步AsyncContext asyncContext = request.startAsync(request, response);AsyncTask asyncTask = new AsyncTask(asyncContext, true);// 維護 dataId 和異步請求上下文的關聯dataIdContext.put(dataId, asyncTask);// 啟動定時器,30s 后寫入 304 響應timeoutChecker.schedule(() -> {if (asyncTask.isTimeout()) {dataIdContext.remove(dataId, asyncTask);response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);asyncContext.complete();}}, 3000, TimeUnit.MILLISECONDS);}// 配置發布接入點@RequestMapping("/publishConfig")@SneakyThrowspublic String publishConfig(String dataId, String configInfo) {log.info("publish configInfo dataId: [{}], configInfo: {}", dataId, configInfo);Collection<AsyncTask> asyncTasks = dataIdContext.removeAll(dataId);for (AsyncTask asyncTask : asyncTasks) {asyncTask.setTimeout(false);HttpServletResponse response = (HttpServletResponse)asyncTask.getAsyncContext().getResponse();response.setStatus(HttpServletResponse.SC_OK);response.getWriter().println(configInfo);asyncTask.getAsyncContext().complete();}return "success";}public static void main(String[] args) {SpringApplication.run(ConfigServer.class, args);}}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/81446.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/81446.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/81446.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

深入理解 requestIdleCallback:瀏覽器空閑時段的性能優化利器

requestIdleCallback 核心作用 requestIdleCallback 是瀏覽器提供的 API&#xff0c;用于將非關鍵任務延遲到瀏覽器空閑時段執行&#xff0c;避免阻塞用戶交互、動畫等關鍵任務&#xff0c;從而提升頁面性能體驗。 基本語法 const handle window.requestIdleCallback(callb…

51單片機——交通指示燈控制器設計

設計目標 1、設計一交通燈控制&#xff0c;控制東西方向的紅、黃、綠燈和南北方向的紅、黃、綠燈。 2、可手動控制和自動控制&#xff0c;設置兩個輸入控制開關。 手動/自動開關&#xff0c;通過P11的按鍵輸入控制 3、手動&#xff1a;設置開關P11&#xff0c;兩種情況&#x…

神經網絡語言模型(前饋神經網絡語言模型)

神經網絡語言模型 什么是神經網絡&#xff1f;神經網絡的基本結構是什么&#xff1f;輸入層隱藏層輸出層 神經網絡為什么能解決問題&#xff1f;通用近似定理為什么需要權重和偏置&#xff1f;為什么需要激活函數&#xff1f;權重是如何確定的&#xff1f;1. 窮舉2. 反向傳播主…

信息系統項目管理師高級-軟考高項案例分析備考指南(2023年案例分析)

個人筆記整理---僅供參考 計算題 案例分析里的計算題就是進度、掙值分析、預測技術。主要考査的知識點有:找關鍵路徑、求總工期、自由時差、總時差、進度壓縮資源平滑、掙值計算、預測計算。計算題是一定要拿下的&#xff0c;做計算題要保持頭腦清晰&#xff0c;認真讀題把PV、…

unordered_map和unordered的介紹和使用

目錄 unordered系列關聯式容器 unordered_map unordered_map的接口說明 unordered_map的定義方式 unordered_map接口的使用 unordered_map的容量 unordered_map的迭代器 unordered_map的元素訪問 unordered_map的查詢 unordered_map的修改操作 unordered_multimap u…

設計模式7大原則與UML類圖詳解

設計模式7大原則與UML類圖詳解 引言 &#x1f31f; 在軟件工程領域&#xff0c;設計模式和UML&#xff08;統一建模語言&#xff09;是提高代碼質量、增強系統可維護性的重要工具。設計模式提供了解決軟件設計中常見問題的通用方案&#xff0c;而UML則為我們提供了一種可視化的…

計算機視覺與深度學習 | Python實現ARIMA-LSTM時間序列預測(完整源碼和數據)

ARIMA-LSTM混合模型 1. 環境準備2. 數據生成(示例數據)3. 數據預處理4. ARIMA建模5. LSTM殘差建模6. 混合預測7. 結果可視化完整代碼說明1. **數據生成**2. **ARIMA建模**3. **LSTM殘差建模**4. **混合預測**5. **性能評估**參數調優建議擴展方向典型輸出以下是使用Python實現…

Docker部署單節點Elasticsearch

1.Docker部署單節點ES 1.前置條件 配置內核參數 echo "vm.max_map_count262144" >> /etc/sysctl.conf sysctl -w vm.max_map_count262144準備密碼 本文所有涉及密碼的配置&#xff0c;均使用通用密碼 Zzwl2024。 生產環境&#xff0c;請用密碼生成器生成20…

pe文件二進制解析(用c/c++解析一個二進制pe文件)

pe文件二進制解析 c解析pe文件控制臺版本 #include<iostream> #include<windows.h> #include<vector>/*RVA&#xff08;相對虛擬地址&#xff09;與FOA&#xff08;文件偏移地址&#xff09;的轉換1.得到 的值&#xff1a;內存地址 - ImageBase2.判斷是否位…

融智學視域下的系統性認知增強框架——基于文理工三類AI助理賦能HI四階躍遷路徑

融智學視域下的系統性認知增強框架 ——基于文理工三類AI助理賦能HI四階躍遷路徑 一、如何排除50個認知偏差&#xff1a;消除50類偏差的精準矯正系統 1. 技術架構 文科AI&#xff1a; 構建文化語義場&#xff08;Cultural Semantic Field, CSF&#xff09;&#xff0c;通過…

MMDetection環境安裝配置

MMDetection 支持在 Linux&#xff0c;Windows 和 macOS 上運行。它需要 Python 3.7 以上&#xff0c;CUDA 9.2 以上和 PyTorch 1.8 及其以上。 MMDetection 至今也一直更新很多個版本了&#xff0c;但是對于最新的pytorch版本仍然不支持&#xff0c;我安裝的時候仍然多次遇到m…

如何實現k8s高可用

一、控制平面高可用設計 多主節點部署 ? API Server 冗余&#xff1a;部署至少 3 個 Master 節點&#xff0c;每個節點運行獨立的 API Server&#xff0c;通過負載均衡器&#xff08;如 Nginx、HAProxy、云廠商 LB&#xff09;對外提供統一入口。 ? 選舉機制&#xff1a;Sche…

記錄心態和工作變化

忙中帶閑的工作 其實工作挺忙的, 總是在趕各種功能點. 好巧的是iOS那邊因為上架的問題耽擱了一些時間, 從而讓Android的進度有了很大的調整空間. 更巧的是后端那邊因為對客戶端的需求不是很熟悉, 加上Android海外這塊的業務他也是第一次接觸. 所以需要給他留一些時間把各個環節…

JVM 雙親委派機制

一、從 JDK 到 JVM&#xff1a;Java 運行環境的基石 在 Java 開發領域&#xff0c;JDK&#xff08;Java Development Kit&#xff09;是開發者的核心工具包。它不僅包含了編譯 Java 代碼的工具&#xff08;如 javac&#xff09;&#xff0c;還內置了 JRE&#xff08;Java Run…

java開發之異常

一 結構 Throwable分為Exception和error Exception分為RuntimeException&#xff08;運行時異常&#xff09;和其他異常 主動拋出運行時異常和非運行時異常的區別 1、throw RuntimeException&#xff08;或運行時異常的子類&#xff09; 編譯時不會報錯。 2、throw Excepti…

MySQL 中 JOIN 和子查詢的區別與使用場景

目錄 一、JOIN:表連接1.1 INNER JOIN:內連接1.2 LEFT JOIN:左連接1.3 RIGHT JOIN:右連接1.4 FULL JOIN:全連接二、子查詢:嵌套查詢2.1 WHERE 子句中的子查詢2.2 FROM 子句中的子查詢2.3 SELECT 子句中的子查詢三、JOIN 和子查詢的區別3.1 功能差異3.2 性能差異3.3 使用場…

2025年第三屆盤古石杯初賽(智能冰箱,監控部分)

前言 所以去哪里可以取到自己家里的智能家居數據呢&#xff1f;&#xff1f;&#xff1f;&#xff1f; IOT物聯網取證 1、分析冰箱&#xff0c;請問智能冰箱的品牌&#xff1f; [答案格式&#xff1a;xiaomi] Panasonic2、請問智能冰箱的型號&#xff1f; [答案格式&#x…

【強化學習】強化學習算法 - 馬爾可夫決策過程

文章目錄 馬爾可夫決策過程 (Markov Decision Process, MDP)1. MDP 原理介紹2. MDP 建模/實現步驟3. MDP 示例&#xff1a;簡單網格世界 (Grid World) 馬爾可夫決策過程 (Markov Decision Process, MDP) 1. MDP 原理介紹 馬爾可夫決策過程 (MDP) 是強化學習 (Reinforcement L…

用戶現場不支持路由映射,如何快速將安防監控EasyCVR視頻匯聚平臺映射到公網?

一、方案背景? 隨著數字化安防與智能交通管理發展&#xff0c;視頻監控遠程管理需求激增。EasyCVR作為專業視頻融合平臺&#xff0c;具備多協議接入等核心功能&#xff0c;是智能監控的重要工具。但實際部署中&#xff0c;當EasyCVR處于內網且路由器無法進行端口映射時&#…

MODBUS RTU調試助手使用方法詳解

一、軟件簡介 485調試助手是一款常用的串口通信調試工具&#xff0c;專門用于RS-485總線設備的測試、調試和通信監控。它支持多種串口參數設置&#xff0c;提供數據收發功能&#xff0c;是工業現場調試的必備工具之一。 二、軟件安裝與啟動 1. 系統要求 Windows 7/10/11操作…