zoukankan      html  css  js  c++  java
  • redis实现分布式缓存

    redis的使用场景

    • 利用redis 中字符串类型完成 项目中手机验证码存储的实现
    • 利用redis中字符串类型完成 具有时效性业务功能 12306等电商的订单倒计时过期功能
    • 利用redis分布式集群系统中进行session共享
    • 利用redis zset类型可排序的特点,可实现排行榜之类的功能
    • 利用redis 实现分布式缓存
    • 利用redis 实现微信小程序或者公众号的token信息
    • 利用redis解决分布式集群系统中分布式锁问题

    分布式缓存

    缓存就是计算机内存中的数据,特点是读写快,断点立即丢失,主要用来减轻数据库访问压力,使用缓存一定是数据库中数据极少发生修改,更多用于查询这种情况

    • 本地缓存:存在应用服务器内存中的数据

    • 分布式缓存:存储在当前应用服务器内存之外的数据

    • 集群:同一个服务的多个节点放在一起共同对外提供服务

    • 分布式:有多个不同服务共同对外提供服务

    自定义分布式缓存

    利用mybatis自身本地缓存结合redis实现分布式缓存
    a.mybatis的二级缓存是应用级别的缓存,所有会话共享,开启在mapper中使用,只要是增删改操作都会清空当前命名空间的缓存
    b.默认使用PerpetualCache类,如果需要用redis,需要实现cache接口,并在的type属性指定,比如:
    c.自定义RedisCache实现

    package com.yyb.cache;
    
    import org.apache.ibatis.cache.Cache;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.data.redis.serializer.StringRedisSerializer;
    
    public class RedisCache implements Cache {
        private final String id;
        private RedisTemplate redisTemplate;
    
        public RedisCache(String id) {
            this.id = id;
            redisTemplate = (RedisTemplate)ApplicationContextUtil.getBean("redisTemplate");
    //        redisTemplate.setKeySerializer(new StringRedisSerializer());
    //        redisTemplate.setHashValueSerializer(new StringRedisSerializer());
        }
    
        public String getId() {
            return this.id;
        }
    
        public void putObject(Object o, Object o1) {
            redisTemplate.opsForHash().put(id, o, o1);
        }
    
        public Object getObject(Object o) {
            return redisTemplate.opsForHash().get(id, o);
        }
    
        //该方法为mybatis的保留方法,未使用
        public Object removeObject(Object o) {
            redisTemplate.opsForHash().delete(id, o);
            return null;
        }
    
        public void clear() {
            redisTemplate.opsForHash().delete(id);
        }
    
        public int getSize() {
            return redisTemplate.opsForHash().size(id).intValue();
        }
    }
    
    
    package com.yyb.cache;
    
    import org.springframework.beans.BeansException;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.ApplicationContextAware;
    import org.springframework.stereotype.Component;
    
    @Component
    public class ApplicationContextUtil implements ApplicationContextAware {
        private static ApplicationContext applicationContext;
    
        public static <T> T getBean(Class<T> tClass) {
            return applicationContext.getBean(tClass);
        }
    
        public static Object getBean(String beanName) {
            return applicationContext.getBean(beanName);
        }
    
        public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
            this.applicationContext = applicationContext;
        }
    }
    

    如果单表查询没什么问题,但是如果表之间有关联关系,比如连接查询就会存在问题,这个时候就需要使用共享缓存

    用来将多个具有关联关系的查询缓存放在一起处理,执行增删改时,就会一起删除

    缓存优化策略-对放入redis中key进行优化:key的长度不能太长,比如使用MD5处理

    缓存问题

    缓存穿透

    客户端查询了数据库中没有的数据,导致这种情况下缓存无法利用,直接穿过redis到数据库了

    解决方案:将数据库没有查询到结果也进行缓存

    缓存击穿

    大量请求访问热点数据,然后这个key突然失效,这些请求就会涌向数据库导致极端情况,数据库阻塞或挂起

    解决方案:
    1、让缓存永不过期
    2、使用分布式锁,在访问数据时加锁,然后存入redis,推荐的方式

    缓存雪崩

    在系统运行的某一时刻,缓存全部失效,恰好这一时刻涌来了大量请求,导致缓存无法使用,请求涌向数据库导致极端情况,数据库阻塞或挂起

    解决方案:
    1、缓存永久存储【不推荐】
    2、针对不同业务数据设置不同的超时时间

  • 相关阅读:
    Transact_SQL小手册
    使用泛型的 TArray 从动态数组中查找指定元素
    使用泛型的 TArray 为动态数组排序
    使用 InputBox、InputQuery 的启发
    近况汇报
    泛型排序器 TComparer
    详测 Generics Collections TList (2): First、Last、IndexOf、LastIndexOf
    详测 Generics Collections TList (1): Add、Clear、Count、Capacity
    WindowsAPI: MulDiv
    SendTextMessage 等方便的消息发送函数
  • 原文地址:https://www.cnblogs.com/ginb/p/14479752.html
Copyright © 2011-2022 走看看