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、针对不同业务数据设置不同的超时时间

分类:

技术点:

相关文章: