redis热点发现以及保护措施

    xiaoxiao2025-03-17  29

    前言

    看过很多文章讲述redis热点key的发现以及处理措施

     

    redis热点发现

    1.客户端

    在客户端get的时候进行统计

    2.美团TMC框架

    重写redis源代码进行统计

    3.预先知道的热点key

    比如我在一个大促的活动中,哪些key是热点的应该知道的吧

     

    处理措施

    为了避免所有的请求都砸到redis上,一般处理方式:启动二级缓存,比如ehcache

     

    讲下个人思路,当key请求次数达到一定数量时,我们把它放到ehcache缓存中,以后该key的请求从缓存里面读取

    @Component public class RedisUtil { ConcurrentHashMap<String, Integer> concurrentHashMap = new ConcurrentHashMap(); private static final String CACHE_NAME = "cache"; @Resource private RedisTemplate redisTemplate; public String getRedis(String key) { if (concurrentHashMap.get(key) != null) { concurrentHashMap.put(key, concurrentHashMap.get(key) + 1); if(concurrentHashMap.get(key)>=1000){ return getCache(key); } } else { concurrentHashMap.put(key, 1); } return (String) redisTemplate.opsForValue().get(key); } @Cacheable(value = CACHE_NAME, key = "redis+'_'+#key") public String getCache(String key){ System.out.println("使用Cache"); return (String) redisTemplate.opsForValue().get(key); } }

    代码如上图,当请求超过1000个的时候缓存起来

     

    控制器

    @RestController public class RedisController { @Resource private RedisTemplate redisTemplate; @Autowired private RedisUtil redisUtil; @RequestMapping("/redis") public void getRedis() throws InterruptedException { long time=System.nanoTime(); String key = "dajitui"; redisTemplate.opsForValue().set(key, "0"); CountDownLatch countDownLatch = new CountDownLatch(5000); for (int i = 0; i < 30000; i++) { new Thread(new Runnable() { @Override public void run() { countDownLatch.countDown(); System.out.println(redisUtil.getRedis(key)); } }).start(); } countDownLatch.await(); long time1=System.nanoTime(); System.out.println("耗时"+(time1-time)); } @RequestMapping("/redis1") public void getRedis1() throws InterruptedException { long time=System.nanoTime(); String key = "dajitui"; redisTemplate.opsForValue().set(key, "0"); CountDownLatch countDownLatch = new CountDownLatch(5000); for (int i = 0; i < 30000; i++) { new Thread(new Runnable() { @Override public void run() { countDownLatch.countDown(); System.out.println(redisTemplate.opsForValue().get(key)); } }).start(); } countDownLatch.await(); long time1=System.nanoTime(); System.out.println("耗时"+(time1-time)); } }

    http://localhost:8080/redis1是没有使用二级缓存的,http://localhost:8080/redis使用了二级缓存

     

    运行结果发现,没有用缓存的耗时6秒多,使用缓存的耗时2秒多

     

    源码下载

    最新回复(0)