使用redis对热门数据进行缓存

简介: 使用redis对热门数据进行缓存

一、业务场景介绍


当一些经常访问而又不轻易改变以及不重要的数据,我们可以使用redis对其进行缓存,来提高系统的流畅度。


二、redis简介


Redis是当前比较热门的NOSQL系统之一,它是一个开源的使用ANSI c语言编写的key-value存储系统


(区别于MySQL的二维表格的形式存储。)。和Memcache类似,但很大程度补偿了Memcache的不足。和Memcache一样,Redis数据都是缓存在计算机内存中,不同的是,Memcache只能将数据缓存到


内存中,无法自动定期写入硬盘,这就表示,一断电或重启,内存清空,数据丢失。所以Memcache的应用场景适用于缓存无需持久化的数据。而Redis不同的是它会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,实现数据的持久化。


Redis的特点:


1,Redis读取的速度是110000次/s,写的速度是81000次/s; 2,原子 。Redis的所有操作都是原子性的,同时Redis还支持对几个操作全并后的原子性执行。

3,支持多种数据结构:string(字符串);list(列表);hash(哈希),set(集合);zset(有序集合) 4,持久化,集群部署

5,支持过期时间,支持事务,消息订阅


三、项目集成redis


1、引入依赖


<!-- redis -->
<dependency> 
<groupId>org.springframework.boot</groupId> 
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- spring2.X集成redis所需common-pool2-->
<dependency>
 <groupId>org.apache.commons</groupId> 
<artifactId>commons-pool2</artifactId>
 <version>2.6.0</version>
</dependency>


2、在配置包中添加redis配置类


package com.caiweiwei.servicebase;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.time.Duration;
@EnableCaching
@Configuration
public class RedisConfig extends CachingConfigurerSupport {
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory
                                                               factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        RedisSerializer<String> redisSerializer = new StringRedisSerializer();
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new
                Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        template.setConnectionFactory(factory);
        //key序列化方式
        template.setKeySerializer(redisSerializer);
        //value序列化
        template.setValueSerializer(jackson2JsonRedisSerializer);
        //value hashmap序列化
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        return template;
    }
    @Bean
    public CacheManager cacheManager(RedisConnectionFactory factory) {
        RedisSerializer<String> redisSerializer = new StringRedisSerializer();
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new
                Jackson2JsonRedisSerializer(Object.class);
        //解决查询缓存转换异常的问题
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        // 配置序列化(解决乱码的问题),过期时间600秒
        RedisCacheConfiguration config =
                RedisCacheConfiguration.defaultCacheConfig()
                        .entryTtl(Duration.ofSeconds(600))
                        .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
                        .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
                        .disableCachingNullValues();
        RedisCacheManager cacheManager = RedisCacheManager.builder(factory)
                .cacheDefaults(config)
                .build();
        return cacheManager;
    }
}


3、在接口上添加redis缓存


3.1 Spring Boot缓存注解


(1)缓存@Cacheable


根据方法对其返回结果进行缓存,下次请求时,如果缓存存在,则直接读取缓存数据返回;如果缓存不存在,则执行方法,并把返回的结果存入缓存中。一般用在查询方法上。


查看源码,属性值如下:


属性/方法名 解释


value 缓存名,必填,它指定了你的缓存存放在哪块命名空间


cacheNames 与 value 差不多,二选一即可


key 可选属性,可以使用 SpEL 标签自定义缓存的key


(2)缓存@CachePut


使用该注解标志的方法,每次都会执行,并将结果存入指定的缓存中。其他方法可以直接从响应的缓存中读取缓存数据,而不需要再去查询数据库。一般用在新增方法上。

查看源码,属性值如下:


属性/方法名 解释


value 缓存名,必填,它指定了你的缓存存放在哪块命名空间


cacheNames 与 value 差不多,二选一即可


key 可选属性,可以使用 SpEL 标签自定义缓存的key


(3)缓存@CacheEvict


使用该注解标志的方法,会清空指定的缓存。一般用在更新或者删除方法上

查看源码,属性值如下:


属性/方法

名 解释

value                       缓存名,必填,它指定了你的缓存存放在哪块命名空间

cacheNames         与 value 差不多,二选一即可

key                           可选属性,可以使用 SpEL 标签自定义缓存的key

allEntries               是否清空所有缓存,默认为 false。如果指定为 true,则方法调用后将立即清空所有的缓存


beforeInvocation 是否在方法执行前就清空,默认为 false。如果指定为 true,则在

方法执行前就会清空缓存


3.2启动redis服务


image.png


image.png


3.3连接redis服务可能遇到的问题


(1)关闭liunx防火墙

(2)找到redis配置文件, 注释一行配置


image.png

image.png


(3)如果出现下面错误提示


3.png

image.png


修改 protected-mode yes      改为         protected-mode no


3.4接口改造


(1)在service-cms模块配置文件添加redis配置


spring.redis.host=192.168.44.132
spring.redis.port=6379
spring.redis.database= 0
spring.redis.timeout=1800000
spring.redis.lettuce.pool.max-active=20
spring.redis.lettuce.pool.max-wait=-1
#最大阻塞等待时间(负数表示没限制)
spring.redis.lettuce.pool.max-idle=5
spring.redis.lettuce.pool.min-idle=0


(2)修改接口,添加redis缓存注解


@Service
public class CrmBannerServiceImpl extends ServiceImpl<CrmBannerMapper, CrmBanner>
implements CrmBannerService {
@Cacheable(value = "banner", key = "'selectIndexList'")
@Override
public List<CrmBanner> selectIndexList() {
List<CrmBanner> list = baseMapper.selectList(new
QueryWrapper<CrmBanner>().orderByDesc("sort"));
return list;
 }
@Override
public void pageBanner(Page<CrmBanner> pageParam, Object o) {
baseMapper.selectPage(pageParam,null);
 }
@Override
public CrmBanner getBannerById(String id) {
return baseMapper.selectById(id);
 }
@CacheEvict(value = "banner", allEntries=true)
@Override
public void saveBanner(CrmBanner banner) {
baseMapper.insert(banner);
 }
@CacheEvict(value = "banner", allEntries=true)
@Override
public void updateBannerById(CrmBanner banner) {
baseMapper.updateById(banner);
 }
@CacheEvict(value = "banner", allEntries=true)
@Override
public void removeBannerById(String id) {
baseMapper.deleteById(id);
 }
}


相关文章
|
5月前
|
Web App开发 存储 缓存
如何精准清除特定类型或标签的缓存数据?
如何精准清除特定类型或标签的缓存数据?
482 57
|
7月前
|
缓存 NoSQL 关系型数据库
美团面试:MySQL有1000w数据,redis只存20w的数据,如何做 缓存 设计?
美团面试:MySQL有1000w数据,redis只存20w的数据,如何做 缓存 设计?
美团面试:MySQL有1000w数据,redis只存20w的数据,如何做 缓存 设计?
|
2月前
|
缓存 负载均衡 监控
135_负载均衡:Redis缓存 - 提高缓存命中率的配置与最佳实践
在现代大型语言模型(LLM)部署架构中,缓存系统扮演着至关重要的角色。随着LLM应用规模的不断扩大和用户需求的持续增长,如何构建高效、可靠的缓存架构成为系统性能优化的核心挑战。Redis作为业界领先的内存数据库,因其高性能、丰富的数据结构和灵活的配置选项,已成为LLM部署中首选的缓存解决方案。
|
3月前
|
存储 缓存 NoSQL
Redis专题-实战篇二-商户查询缓存
本文介绍了缓存的基本概念、应用场景及实现方式,涵盖Redis缓存设计、缓存更新策略、缓存穿透问题及其解决方案。重点讲解了缓存空对象与布隆过滤器的使用,并通过代码示例演示了商铺查询的缓存优化实践。
217 1
Redis专题-实战篇二-商户查询缓存
|
2月前
|
缓存 运维 监控
Redis 7.0 高性能缓存架构设计与优化
🌟蒋星熠Jaxonic,技术宇宙中的星际旅人。深耕Redis 7.0高性能缓存架构,探索函数化编程、多层缓存、集群优化与分片消息系统,用代码在二进制星河中谱写极客诗篇。
|
3月前
|
缓存 NoSQL 关系型数据库
Redis缓存和分布式锁
Redis 是一种高性能的键值存储系统,广泛用于缓存、消息队列和内存数据库。其典型应用包括缓解关系型数据库压力,通过缓存热点数据提高查询效率,支持高并发访问。此外,Redis 还可用于实现分布式锁,解决分布式系统中的资源竞争问题。文章还探讨了缓存的更新策略、缓存穿透与雪崩的解决方案,以及 Redlock 算法等关键技术。
|
4月前
|
存储 缓存 监控
一次缓存引发的文件系统数据不一致问题排查与深度解析
本文详述了一次由自研分布式文件系统客户端 EFC 的缓存架构更新所引发的严重数据不一致问题的完整排查过程。
一次缓存引发的文件系统数据不一致问题排查与深度解析
|
6月前
|
存储 缓存 NoSQL
告别数据僵尸!Redis实现自动清理过期键值对
在数据激增的时代,Redis如同内存管理的智能管家,支持键值对的自动过期功能,实现“数据保鲜”。通过`EXPIRE`设定生命倒计时、`TTL`查询剩余时间,结合惰性删除与定期清理策略,Redis高效维护内存秩序。本文以Python实战演示其过期机制,并提供最佳实践指南,助你掌握数据生命周期管理的艺术,让数据优雅退场。
416 0
|
7月前
|
缓存 NoSQL Java
Redis+Caffeine构建高性能二级缓存
大家好,我是摘星。今天为大家带来的是Redis+Caffeine构建高性能二级缓存,废话不多说直接开始~
1011 0
|
7月前
|
消息中间件 缓存 NoSQL
基于Spring Data Redis与RabbitMQ实现字符串缓存和计数功能(数据同步)
总的来说,借助Spring Data Redis和RabbitMQ,我们可以轻松实现字符串缓存和计数的功能。而关键的部分不过是一些"厨房的套路",一旦你掌握了这些套路,那么你就像厨师一样可以准备出一道道饕餮美食了。通过这种方式促进数据处理效率无疑将大大提高我们的生产力。
250 32