缓存的简单实现

缓存的实现

  • Redis(分布式缓存)

  • memcached(分布式)

  • Etcd(云原生架构的一个分布式存储,存储配置,扩容能力)


  • ehcache(单机)

  • 本地缓存(Java 内存 Map)

  • Caffeine(Java 内存缓存,高性能)

  • Google Guava

Redis

NoSQL 数据库

key - value 存储系统(区别于 MySQL,他存储的是键值对)

Redis 数据结构

String 字符串类型: name: "yupi"

List 列表:names: ["yupi", "dogyupi", "yupi"]

Set 集合:names: ["yupi", "dogyupi"](值不能重复)

Hash 哈希:nameAge: { "yupi": 1, "dogyupi": 2 }

Zset 集合:names: { yupi - 9, dogyupi - 12 }(适合做排行榜)

Java中Redis的实现

  • Spring Data Redis(推荐)

1)引入

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
    <version>2.6.4</version>
</dependency>

2)配置 Redis 地址

spring:
  # redis 配置
  redis:
    port: 6379
    host: localhost
    database: 0

3)实现redis的配置类

这里是为redis配置一个非原生的序列化器,防止存入redis的键存在乱码前缀。

/**
 * redis的配置类,源码中表示redis会默认配置一个java原生的序列化器,这使得k-v结构在存入redis库时,
 * k会序列化上一些乱码的前缀,所以我们要自定义一个RedisTemplate
 */
@Configuration
public class RedisTemplateConfig {

    @Bean
    public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory){
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        redisTemplate.setKeySerializer(RedisSerializer.string());//return StringRedisSerializer.UTF_8配置一个string的序列化器
        return redisTemplate;
    }
}

 4)操作redis

@SpringBootTest
public class RedisTest {

    @Resource
    private RedisTemplate redisTemplate;

    @Test
    void test() {
        ValueOperations valueOperations = redisTemplate.opsForValue();
        // 增
        valueOperations.set("yupiString", "dog");
        valueOperations.set("yupiInt", 1);
        valueOperations.set("yupiDouble", 2.0);
        User user = new User();
        user.setId(1L);
        user.setUsername("yupi");
        valueOperations.set("yupiUser", user);
        // 查
        Object yupi = valueOperations.get("yupiString");
        Assertions.assertTrue("dog".equals((String) yupi));
        yupi = valueOperations.get("yupiInt");
        Assertions.assertTrue(1 == (Integer) yupi);
        yupi = valueOperations.get("yupiDouble");
        Assertions.assertTrue(2.0 == (Double) yupi);
        System.out.println(valueOperations.get("yupiUser"));
        valueOperations.set("yupiString", "dog");
        redisTemplate.delete("yupiString");
    }
}

5)实践

@GetMapping("/recommend")
    public BaseResponse<Page<User>> usersRecommend(long page, long pageSize, HttpServletRequest request){
        User loginUser = userService.getLoginUser(request);
        String redisKey = String.format("zj:user:recommend:%s", loginUser.getId());
        ValueOperations<String, Object> valueOperations = redisTemplate.opsForValue();//opsForValue存string
        //如果有缓存,直接读缓存
        Page<User> userListPage = (Page<User>) valueOperations.get(redisKey);
        if(userListPage != null) {
            return ResultUtils.success(userListPage);
        }
        //无缓存,查数据库,存入缓存
        Page<User> userPage = new Page<>(page, pageSize);
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        userService.page(userPage, queryWrapper);
        List<User> userList = userPage.getRecords();
        userPage.setRecords(userList.stream().map((user) -> {return userService.getSafetyUser(user);}).collect(Collectors.toList()));
        try {
            //指定键、值、缓存过期时间和时间单位
            valueOperations.set(redisKey, userPage, 10000, TimeUnit.MILLISECONDS);
        } catch (Exception e) {
            log.error("redis set key error", e);
        }
        return ResultUtils.success(userPage);
    }

 

  • Jedis

独立于 Spring 操作 Redis 的 Java 客户端

要配合 Jedis Pool 使用

  • Lettuce

高阶 的操作 Redis 的 Java 客户端

异步、连接池

  • Redisson

分布式操作 Redis 的 Java 客户端,让你像在使用本地的集合一样操作 Redis(分布式 Redis 数据网格)

  • JetCache

对比

  1. 如果你用的是 Spring,并且没有过多的定制化要求,可以用 Spring Data Redis,最方便

  2. 如果你用的不是 SPring,并且追求简单,并且没有过高的性能要求,可以用 Jedis + Jedis Pool

  3. 如果你的项目不是 Spring,并且追求高性能、高定制化,可以用 Lettuce,支持异步、连接池


  • 如果你的项目是分布式的,需要用到一些分布式的特性(比如分布式锁、分布式集合),推荐用 redisson

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值