redis与缓存

1.什么是缓存

缓存是计算机内存里的一段数据

2.缓存的特点

由于缓存数据在内存中 所以读写缓存中的数据非常快

3.为什么项目中使用缓存

  1. 项目中使用缓存可以在一定程度上减轻数据库压力
  2. 可以提高现有网站中查询效率 加快网站响应速度

4.项目中是不是所有数据都需要缓存

不是 加入缓存主要数据:查询居多 增删改极少

5.mybatis自身缓存缺陷

  1. 自身实现缓存的数据会占用一定应用服务器内存 导致应用服务器处理请求的速度可能变慢 这种缓存也叫本地缓存。
  2. 本地缓存在集群架构下不能实现缓存共享。
  3. 为了解决本地缓存存在的问题可以实现分布式缓存服务器 memcached redis

6.现有项目中使用redis做分布式缓存的实现

1.基于现有mybatis提供cache接口实现自定义缓存

  1. 自定义缓存实现类 implements Cache
    1. 要求必须存在一个带有String类型id参数构造方法
    2. 要求实现getId方法 这个方法必须返回值当前namespace
public class RedisCache implements Cache {
    private final String id;

    private Jedis cache = new Jedis("192.168.160.129",6379);

    public RedisCache(String id) {
        this.id = id;
    }

    @Override
    public String getId() {
        return id;
    }
    // 返回缓存所有键值对的数量
    @Override
    public int getSize() {
        Long dbSize = cache.dbSize();
        return dbSize.intValue();
    }
    // 向缓存中存入数据
    @Override
    public void putObject(Object key, Object value) {
        System.out.println("put object key:"+key);
        // 将对象序列化成字节数组
        byte[] keyBs = SerializationUtils.serialize((Serializable) key);
        byte[] valueBs = SerializationUtils.serialize((Serializable) value);
        cache.set(keyBs, valueBs);
    }
    // 从缓存中获取数据
    @Override
    public Object getObject(Object key) {
        byte[] keyBs = SerializationUtils.serialize((Serializable) key);
        byte[] valueBs = cache.get(keyBs);
        if (valueBs != null) { // 第一次到缓存找数据的时候 , 返回的是null
            return SerializationUtils.deserialize(valueBs);
        }
        return null;
    }
    // 清除缓存
    @Override
    public Object removeObject(Object key) {
        // 先获取一下删除的对象
        byte[] keyBs = SerializationUtils.serialize((Serializable) key);
        byte[] valueBs = cache.get(keyBs);
        Object obj = SerializationUtils.deserialize(valueBs);
        cache.del(keyBs);// 执行删除操作
        return obj;
    }
    // 清空缓存
    @Override
    public void clear() {
        cache.flushDB();
    }

    @Override
    public ReadWriteLock getReadWriteLock() {
        return null;
    }

    @Override
    public boolean equals(Object o) {
        if (getId() == null) {
            throw new CacheException("Cache instances require an ID.");
        }
        if (this == o) {
            return true;
        }
        if (!(o instanceof Cache)) {
            return false;
        }

        Cache otherCache = (Cache) o;
        return getId().equals(otherCache.getId());
    }

    @Override
    public int hashCode() {
        if (getId() == null) {
            throw new CacheException("Cache instances require an ID.");
        }
        return getId().hashCode();
    }
  1. 在mapper文件中指定使用自定义缓存
 <!--使用自定义二级缓存-->
    <cache type="com.baizhi.cache.RedisCache"></cache>

7.redis结合mybatis实现缓存存在的问题

1. 缓存穿透

1.概念

缓存穿透是指用户查询数据,在数据库中没有,自然缓存中也不会存在。这样就导致在缓存中查找后,又进行数据库的查找,进行了两次无用的操作。

2.解决方案

  1. 使用布隆过滤器,将所有可能存在的数据哈希到一个足够大的bitmap中,一个一定不存在的数据会被bitmap拦截掉,从而避免了对底层存储系统查询的压力。
  2. 空数据也缓存,但他的缓存过期时间很短,最长不超过5分钟,进而避免空数据进行数据库的查询。

2.缓存雪崩

1.概念

由于大量的缓存,在同一时刻到达失效时间,而新缓存未到,形成大面积的缓存过期。所有原本应该访问缓存的请求全部,同时去查询数据库,造成数据库CPU和内存过大的并发压力,严重造成宕机,造成系统崩溃。

2.解决方案

  1. 队列、加锁: 保证不会在同一时刻对数据库的大量访问。
  2. 分散失效时间:在原有失效时间的基础上加上一个随机值,比如1-5分钟随机,这样可以避免大面积缓存在同一时间过期。
  3. 添加缓存标记:给每一个缓存数据增加相应的缓存标记,记录缓存是否失效,如果失效,则更新数据缓存。

3.缓存预热

1.概念

缓存预热这个应该是一个比较常见的概念,相信很多小伙伴都应该可以很容易的理解,缓存预热就是系统上线后,将相关的缓存数据直接加载到缓存系统。这样就可以避免在用户请求的时候,先查询数据库,然后再将数据缓存的问题!用户直接查询事先被预热的缓存数据!

2.思路

  1. 直接写个缓存刷新页面,上线时手工操作
  2. 数据量不大,可以在项目启动的时候自动进行加载
  3. 定时刷新缓存

4.缓存降级

1.概念

当访问量剧增、服务出现问题(如响应时间慢或不响应)或非核心服务影响到核心流程的性能时,仍然需要保证服务还是可用的,即使是有损服务。系统可以根据一些关键数据进行自动降级,也可以配置开关实现人工降级。

2.降级原则

参考日志级别设置预案

  1. 一般:比如有些服务偶尔因为网络抖动或者服务正在上线而超时,可以自动降级
  2. 警告:有些服务在一段时间内成功率有波动(如在95~100%之间),可以自动降级或人工降级,并发送告警
  3. 错误:比如可用率低于90%,或者数据库连接池被打爆了,或者访问量突然猛增到系统能承受的最大阀值,此时可以根据情况自动降级或者人工降级
  4. 严重错误:比如因为特殊原因数据错误了,此时需要紧急人工降级
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值