Guava本地缓存通过滑动时间窗口算法缓存热数据

# Guava 通过滑动时间窗口算法缓存热数据 本文介绍了如何使用Guava库实现滑动时间窗口算法,以检测并缓存热点数据。 ## 1. 引入guava依赖 ```xml <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>18.0</version> </dependency> ``` ## 2. 新建HotSpotDetector.java 接下来,创建一个名为HotSpotDetector.java的类。该类使用Guava的缓存功能,并通过滑动时间窗口算法来检测和缓存热点数据。 ```java package com.bs.hotkey; import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; import java.util.*; import java.util.concurrent.TimeUnit; public class HotSpotDetector { //sku_1 1000 5 10 private final int WINDOW_SIZE = 10; // 滑动窗口大小,单位为秒 private final int THRESHOLD = 5; // 阈值,达到该条件即视为热点数据 private final Cache<String, Object> hotCache = CacheBuilder .newBuilder() .expireAfterWrite(5, TimeUnit.SECONDS) .maximumSize(1000).build(); // 缓存热点数据 private Map<String, Queue<Long>> window = new HashMap<>(); private Map<String, Integer> counts = new HashMap<>(); // 判断是否为热点数据 public boolean isHot(String data) { //如果缓存中有数据,直接返回ture if (hotCache.getIfPresent(data)!=null){ return true; } // 获取当前数据在计数器中的统计次数 int count = counts.getOrDefault(data, 0); // 如果统计次数大于等于阈值,将该数据加入热点缓存,清空队列并返回true if (count >= THRESHOLD) { hotCache.put(data, 1); // 将热点数据放入缓存 clear(data); // 处理完毕后将队列清空 return true; } else { // 如果统计次数小于阈值,则更新计数器,维护时间窗口,并返回false counts.put(data, count + 1); // 获取对应数据的时间队列 Queue<Long> queue = window.get(data); // 如果该队列为null,创建一个新的LinkedList队列 if (queue == null) { queue = new LinkedList<Long>(); window.put(data, queue); } // 获取当前时间(秒级) long currTime = System.currentTimeMillis() / 1000; queue.add(currTime);// 将当前时间加入时间队列中,用于后面数据滑动窗口的统计 // 如果队列中数据的时间超过了滑动窗口的时间区间,则将该时间从队列中移除 while (!queue.isEmpty() && currTime - queue.peek() > WINDOW_SIZE) { queue.poll(); counts.put(data, counts.get(data) - 1); // 统计次数-1 } return false; } } // 清除指定数据的队列和计数 private void clear(String data) { window.remove(data); counts.remove(data); } //添加数据到本地缓存 public void set(String key , Object value){ hotCache.put(key , value); } public Object get(String key){ return hotCache.getIfPresent(key); } public static void main(String[] args) throws InterruptedException { HotSpotDetector detector = new HotSpotDetector(); Random random = new Random(); String[] testData = {"A", "B", "C", "D", "E", "F"}; // 模拟数据访问 detector.isHot("A"); detector.isHot("A"); detector.isHot("A"); detector.isHot("A"); detector.isHot("A"); boolean isHotspot = detector.isHot("A"); if (isHotspot) { System.out.println("A是热数据"); detector.get("C"); }else{ System.out.println("A不是热数据"); } } } ```