Redis缓存服务器(redis安装,redis启动配置,springboot整合redis,AOP缓存的实现)

Redis缓存服务器

1.业务说明

在这里插入图片描述

2.关于缓存机制说明

说明: 缓存中的数据都是数据库中的记录. 引入缓存机制之后,主要的目的为了降低用户访问物理设备的频次.提高服务器响应效率.
维度说明:
1).开发语言: C语言开发
2).数据结构问题: K-V结构 map/properties key不能重复
3).内存数据 断电及擦除: 定期将内存数据持久化操作
4).内存资源有效: 如何有效的维护内存大小? 定期清理内存. LRU算法/LFU算法/TLL算法

3.Redis介绍

Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。 它支持多种类型的数据结构,如 字符串(strings), 散列(hashes), 列表(lists), 集合(sets), 有序集合(sorted sets) 与范围查询, bitmaps, hyperloglogs 和 地理空间(geospatial) 索引半径查询。 Redis 内置了 复制(replication),LUA脚本(Lua scripting), LRU驱动事件(LRU eviction),事务(transactions) 和不同级别的 磁盘持久化(persistence), 并通过 Redis哨兵(Sentinel)和自动 分区(Cluster)提供高可用性(high availability)。

速度: 读: 11.2万次/秒 写: 8.6万次/秒 平均10万次/秒

4.Redis安装

4.1 上传Redis安装包

在这里插入图片描述

4.2 解压文件
tar -xvf redis-5.0.4.tar.gz

在这里插入图片描述

4.2 安装redis

步骤: 进入redis根目录中
命令1: make
在这里插入图片描述
命令2: make install
在这里插入图片描述

4.3修改redis配置文件
vim后显示行号:set nu

命令: vim redis.conf
展现行号:
在这里插入图片描述
1).关闭IP绑定
在这里插入图片描述
2).关闭保护模式
在这里插入图片描述
3).开启后台运行
在这里插入图片描述

4.4 Redis启动命令

1).启动redis命令

  redis-server redis.conf

在这里插入图片描述
2).进入redis客户端
redis-cli -p 6379

3).关闭redis
redis-cli -p 6379 shutdown

5.Redis入门案例

5.1 导入jar包
        <!--spring整合redis -->
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-redis</artifactId>
        </dependency>
5.2 入门案例
package com.jt.redis;

import org.junit.jupiter.api.Test;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;
import redis.clients.jedis.params.Params;
import redis.clients.jedis.params.SetParams;

public class TestRedis {

    /**
     * 1.redis配置文件3处修改
     * 2.Linux系统防火墙
     * 3.检查redis启动方式 redis-server redis.conf
     * */
    @Test
    public void testSet() throws InterruptedException {
        String host = "192.168.126.129";
        int port = 6379;
        Jedis jedis = new Jedis(host,port);
        //命令怎么敲,代码怎么写
        jedis.set("2011", "redis入门案例");
        System.out.println(jedis.get("2011"));
        jedis.flushAll();
        //测试是否存在
        if(jedis.exists("2011")){
            jedis.del("2011");
        }else{
            jedis.set("num", "100");
            //自增1
            jedis.incr("num");
            jedis.expire("num", 20);
            Thread.sleep(2000);
            //检查超时时间
            System.out.println(jedis.ttl("num"));
            //取消超时时间
            jedis.persist("num");
        }
    }

    //有时我们可能会为数据添加超时时间
    //原子性问题: 有时业务要求要么同时完成,要么同时失败
    @Test
    public void testSetEx(){
        Jedis jedis = new Jedis("192.168.126.129", 6379);
        //jedis.set("a","aa");
        //服务器异常
        //jedis.expire("a",60);
        jedis.setex("a", 20, "100");
        System.out.println(jedis.get("a"));
    }

    /**
     * 需求1:如果该数据不存在时,才会赋值.
     * 需求2: 如果数据存在时,进行修改, 并且为他设定超时时间 满足原子性要求.
     *
     */
    @Test
    public void testSetNX(){
        Jedis jedis = new Jedis("192.168.126.129", 6379);
        jedis.set("a", "111");
        jedis.setnx("a", "123");
        System.out.println(jedis.get("a"));

        SetParams params = new SetParams();
        params.xx().ex(20);
        jedis.set("b", "bb", params);
    }

    //默认hash是无序的
    @Test
    public void testHash(){
        Jedis jedis = new Jedis("192.168.126.129", 6379);
        jedis.hset("user", "id", "100");
        jedis.hset("user", "name", "101");
        jedis.hset("user", "age", "18");
        System.out.println(jedis.hkeys("user"));

    }

    //队列:先进先出   方向相反
    //栈: 先进后出    方向相同     注意可变参数类型
    @Test
    public void testList(){
        Jedis jedis = new Jedis("192.168.126.129", 6379);
        jedis.lpush("list", "1","2","3","4");
        System.out.println(jedis.rpop("list"));
    }

    @Test
    public void testTx(){
        Jedis jedis = new Jedis("192.168.126.129", 6379);
        //开启事务
        Transaction transaction = jedis.multi();
        try {
            transaction.set("a", "a");
            transaction.set("b", "b");
            transaction.set("b", "b");
            //提交事务
            transaction.exec();
        }catch (Exception e){
            transaction.discard();
        }

    }
}

6.SpringBoot整合Redis

6.1 编辑pro配置文件

在这里插入图片描述

6.2 编辑配置类
package com.jt.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import redis.clients.jedis.Jedis;

@Configuration  //标识为一个配置类, 一般整合第三方
@PropertySource("classpath:/properties/redis.properties")
public class RedisConfig {

    @Value("${redis.host}")
    private String host;
    @Value("${redis.port}")
    private Integer port;

    @Bean   //将该方法的返回值,交给Spring容器管理
    public Jedis jedis(){

        return new Jedis(host,port);
    }
}

7.AOP缓存的实现

7.1 自定义注解
@Target({ElementType.METHOD})       //标识注解使用在方法中
@Retention(RetentionPolicy.RUNTIME) //什么时期有效
public @interface CacheFind {
    //key-value方法的返回值
    String key();   //要求用户必须指定key
    int seconds() default -1;  //设定超时时间  -1 无需超时
}
7.2 使用缓存注解

在这里插入图片描述

7.3 编辑RedisAOP
@Component  //将对象交给Spring容器管理
@Aspect     //标识AOP切面
public class RedisAOP {

    @Autowired
    private Jedis jedis;

    //通知选择: 是否控制目标方法是否执行.  环绕通知
    //切入点表达式: 控制注解 @annotation(语法....)

    /**
     * 需求: 如何动态获取注解中的属性值.
     * 原理: 反射机制
     *       获取目标对象~~~~~获取方法对象~~~获取注解  原始API
     *
     * @param joinPoint
     * @return
     * @throws Throwable
     *
     * 向上造型:  父类  = 子类
     * 向下造型:  子类  = (强制类型转化)父类
     *
     * AOP中的语法规范1.:
     *   如果通知方法有参数需要添加,则joinPoint 必须位于第一位.
     *   报错信息: error at ::0 formal unbound in pointcut
     * AOP中的语法规范3:
     *   如果需要动态接受注解对象,则在切入点表达式中直接写注解参数名称即可
     *   虽然看到的是名称,但是解析时变成了包名.类型
     */
    @Around("@annotation(cacheFind)")
    public Object around(ProceedingJoinPoint joinPoint,CacheFind cacheFind) throws Throwable {
        Object result = null;
        //1.获取key="ITEM_CAT_PARENTID"
        String key = cacheFind.key();
        //2.动态拼接key 获取参数信息
        String args = Arrays.toString(joinPoint.getArgs());
        key += "::" + args;
        //3.redis缓存实现
        if(jedis.exists(key)){
            String json = jedis.get(key);
            //target标识返回值类型????
            MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
            Class returnType = methodSignature.getReturnType();
            result = ObjectMapperUtil.toObject(json, returnType);
            System.out.println("AOP缓存查询!!!");
        }else{
            //查询数据库 执行目标方法
            result = joinPoint.proceed();
            String json = ObjectMapperUtil.toJSON(result);
            if(cacheFind.seconds()>0)
                jedis.setex(key,cacheFind.seconds(),json);
            else
                jedis.set(key, json);
            System.out.println("AOP查询数据库");
        }
        return result;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值