利用Java来访问Redis并对Redis进行相关操作以及spring+redis集成配置与注解式注解

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: redis缓存的一些注意事项 只应将热数据放到缓存中 所有缓存信息都应设置过期时间 缓存过期时间应当分散以避免集中过期 缓存key应具备可读性 应避免不同业务出现同名缓存key 可对key进行适当的缩写以节省内存空间 选择合适的数据结构 确保写入缓存中的数据是完整且正确的 避免使用耗时较长的操作命令,如:keys * Redis默认配置中操作耗时超过10ms即视为慢查询 一个key对应的数据不应过大 对于string类型,一个key对应的value大小应控制在10K以内,1K左右更优hash类型,不应超过5000行
  1. 可视化管理工具redis-desktop-manager安装与配置
    1.1 双击redis-desktop-manager-0.8.8.384.exe即可

    1.2 配置远程登录
    vi redis.conf #编辑redis.conf文件
    命令模式下输入“/字符串”,例如:“/requirepass”,再按N键向下查找

    1)修改访问IP地址,服务器IP(69)
    #bind 127.0.0.1 #注释这一行

    2)找到下面这一行并去除注释,并添加密码(396行)
    #requirepass foobared #修改前
    requirepass 123456 #修改后

    3)配置redis的6379端口到防火墙
    firewall-cmd --zone=public --add-port=6379/tcp --permanent &&
    firewall-cmd --reload &&
    firewall-cmd --list-ports

  2. Java访问redis
    2.1 添加依赖

    <dependency>
      <groupId>redis.clients</groupId>
      <artifactId>jedis</artifactId>
      <version>2.9.0</version>
    </dependency>
    

    2.2 Java连接redis

    Jedis jedis = new Jedis(ip, port);
    jedis.auth("123456");//权限认证
    jedis.ping();
    jedis.select(0);//切换数据库
    

2.3 Java操作redis

  string(字符串)
  hash(哈希)
  list(列表)
  set(集合)
  zset(sorted set:有序集合)
    zadd/zrevrange


  注1:不需要记得API的方法,只需要查redis命令





spring+redis集成配置

jedis.zadd("zset", 50d, "zs");
jedis.zadd("zset", 30d, "lw");
jedis.zadd("zset", 100d, "ww");

ScanResult zscan = jedis.zscan("zset", 0);
List result1 = zscan.getResult();
for (Tuple tuple : result1) {

System.out.println(tuple.getScore()+","+tuple.getElement());

}

  1. 前提
    spring+redis集成已完成
  2. spring注解式缓存使用步骤
    1.0 前提:spring+redis集成已完成

    1.1 配置缓存管理器

     <bean id="redisCacheManager" class="org.springframework.data.redis.cache.RedisCacheManager">
       <constructor-arg name="redisOperations" ref="redisTemplate" />
       <!--redis缓存数据过期时间单位秒-->
       <property name="defaultExpiration" value="${redis.expiration}" />
    
       <property name="usePrefix" value="true"/>
    
       <property name="cachePrefix">
           <bean class="org.springframework.data.redis.cache.DefaultRedisCachePrefix">
               <constructor-arg index="0" value="-cache-"/>
           </bean>
       </property>
    

    1.2 配置自定义Key生成器CacheKeyGenerator

     缓存的Java对象一定要重写hashCode和eqauls
     <bean id="cacheKeyGenerator" class="com.zking.ssm.redis.CacheKeyGenerator"></bean>
     
     

    1.3 启用缓存注解功能

     <cache:annotation-driven cache-manager="redisCacheManager" key-generator="cacheKeyGenerator"/>
    

    1.4 在需要的地方进行注解缓存

  3. 缓存注解
    2.1 @CacheConfig

     它是一个类级别的注解,允许共享缓存的名称、KeyGenerator、CacheManager和CacheResolver
    
     value:缓存位置的一段名称,不能为空
     key:缓存的key,默认为空,表示使用方法的参数类型及参数值作为key,支持SpEL
    
    

    2.2 @Cacheable

     配置在方法或类上,作用:本方法执行后,先去缓存看有没有数据,如果没有,从数据库中查找出来,给缓存中存一份,返回结果,
     下次本方法执行,在缓存未过期情况下,先在缓存中查找,有的话直接返回,没有的话从数据库查找
     value:缓存位置的一段名称,不能为空
     key:缓存的key,默认为空,表示使用方法的参数类型及参数值作为key,支持SpEL
     keyGenerator:指定key的生成策略
     condition:触发条件,满足条件就加入缓存,默认为空,表示全部都加入缓存,支持SpEL
    
     注1:condition是在方法执行前评估, unless是在方法执行后评估. 
     

    2.3 @CachePut

     类似于更新操作,即每次不管缓存中有没有结果,都从数据库查找结果,并将结果更新到缓存,并返回结果
    
     value    缓存的名称,在 spring 配置文件中定义,必须指定至少一个
     key    缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合
     condition    缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存
    

    2.4 @CacheEvict

     用来清除用在本方法或者类上的缓存数据(用在哪里清除哪里)
     value:缓存位置的一段名称,不能为空
     key:缓存的key,默认为空,表示使用方法的参数类型及参数值作为key,支持SpEL
     condition:触发条件,满足条件就加入缓存,默认为空,表示全部都加入缓存,支持SpEL
     allEntries:true表示清除value中的全部缓存,默认为false
    
    
  4. Spring-Cache key设置
    3.1 基本形式

     @Cacheable(value="cacheName", key="#id")
     public ResultDTO method(int id);
    
     注1:Spring Cacheable注解不缓存null值
          用Cacheable注解时,发现空值,也会被缓存下来。下次另一个系统如果更新了值,这边从缓存取,还是空值,会有问题。
          解决方案:
          @Cacheable(value = "service", key = "#service.serviceId.toString()", unless = "#result == null")
          @Cacheable(value = "service", keyGenerator = RedisKeys.KEY_GENERATOR, unless = "#result.size() == 0")
    

    3.2 组合形式

     @Cacheable(value="cacheName", key="T(String).valueOf(#name).concat('-').concat(#password))
     public ResultDTO method(int name, String password);
    

    3.3 对象形式

     @Cacheable(value="cacheName", key="#user.id)
     public ResultDTO method(User user);
    
     注1:以上三种配置方式中,使用了spEL表达式
    

    3.4 自定义Key生成器

     @Cacheable(value="gomeo2oCache", keyGenerator = "keyGenerator")
     public ResultDTO method(User user);
    
     spring注解式缓存中的巨坑~~~~~~~
     没有指定key,默认情况下spirng会使用SimpleKeyGenerator生成key,
     而Spring默认的SimpleKeyGenerator是不会将函数名组合进key中的,举个例子:
     @Component
     public class CacheTestImpl implements CacheTest {
       @Cacheable("databaseCache")
       public Long test1()
       { return 1L; }
    
       @Cacheable("databaseCache")
       public Long test2()
       { return 2L; }
    
       @Cacheable("databaseCache")
       public Long test3()
       { return 3L; }
    
       @Cacheable("databaseCache")
       public String test4()
       { return "4"; }//注意返回的是字符串“4”
     }
     我们期望的输出是:
     1
     2
     3
     4
     而实际上的输出是:
     1
     1
     1
     ClassCastException: java.lang.Long cannot be cast to java.lang.String
    
  此外,原子类型的数组,直接作为key使用也是不会生效的,为了解决上述2个问题,只能通过自定义KeyGenerator解决


  自定义Key生成器CacheKeyGenerator:源码见资料“CacheKeyGenerator.java”,另外此类使用非加密哈希算法MurmurHash
  (源码46行: Hashing.murmur3_128().hashString),需要引入google guava项目,其pom如下:
  <dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>27.0.1-jre</version>
  </dependency>
  

  1. redis缓存的一些注意事项
    只应将热数据放到缓存中
    所有缓存信息都应设置过期时间
    缓存过期时间应当分散以避免集中过期
    缓存key应具备可读性
    应避免不同业务出现同名缓存key
    可对key进行适当的缩写以节省内存空间
    选择合适的数据结构
    确保写入缓存中的数据是完整且正确的
    避免使用耗时较长的操作命令,如:keys *
    Redis默认配置中操作耗时超过10ms即视为慢查询
    一个key对应的数据不应过大

    对于string类型,一个key对应的value大小应控制在10K以内,1K左右更优hash类型,不应超过5000行

    避免缓存穿透
    数据库中未查询到的数据,可在Redis中设置特殊标识,以避免因缓存中无数据而导致每次请求均达到数据库

    缓存层不应抛出异常

    缓存应有降级处理方案,缓存出了问题要能回源到数据库进行处理

    可以进行适当的缓存预热
    对于上线后可能会有大量读请求的应用,在上线之前可预先将数据写入缓存中

读的顺序是先缓存,后数据库;写的顺序是先数据库,后缓存

数据一致性问题
数据源发生变更时可能导致缓存中数据与数据源中数据不一致,应根据实际业务需求来选择适当的缓存更新策略:

主动更新:在数据源发生变更时同步更新缓存数据或将缓存数据过期。一致性高,维护成本较高。
被动删除:根据缓存设置的过期时间有Redis负责数据的过期删除。一致性较低,维护成本较低。

  1. 根据用户ID或公司ID进行查询(此想法未测试)

    @Transactional(readOnly = true)
    @Cacheable(value = "service+'By'+service.userId", unless = "#result.size() == 0")
    List listByUserId(Service service, PageBean pageBean);

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
2月前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
86 2
|
3天前
|
人工智能 自然语言处理 Java
FastExcel:开源的 JAVA 解析 Excel 工具,集成 AI 通过自然语言处理 Excel 文件,完全兼容 EasyExcel
FastExcel 是一款基于 Java 的高性能 Excel 处理工具,专注于优化大规模数据处理,提供简洁易用的 API 和流式操作能力,支持从 EasyExcel 无缝迁移。
46 9
FastExcel:开源的 JAVA 解析 Excel 工具,集成 AI 通过自然语言处理 Excel 文件,完全兼容 EasyExcel
|
1月前
|
Java 开发者 微服务
Spring Boot 入门:简化 Java Web 开发的强大工具
Spring Boot 是一个开源的 Java 基础框架,用于创建独立、生产级别的基于Spring框架的应用程序。它旨在简化Spring应用的初始搭建以及开发过程。
58 6
Spring Boot 入门:简化 Java Web 开发的强大工具
|
2月前
|
人工智能 前端开发 Java
基于开源框架Spring AI Alibaba快速构建Java应用
本文旨在帮助开发者快速掌握并应用 Spring AI Alibaba,提升基于 Java 的大模型应用开发效率和安全性。
239 12
基于开源框架Spring AI Alibaba快速构建Java应用
|
2月前
|
SQL Java 数据库连接
在Java应用中,数据库访问常成为性能瓶颈。连接池技术通过预建立并复用数据库连接,有效减少连接开销,提升访问效率
在Java应用中,数据库访问常成为性能瓶颈。连接池技术通过预建立并复用数据库连接,有效减少连接开销,提升访问效率。本文介绍了连接池的工作原理、优势及实现方法,并提供了HikariCP的示例代码。
60 3
|
2月前
|
SQL Java 数据库连接
打破瓶颈:利用Java连接池技术提升数据库访问效率
在Java应用中,数据库访问常成为性能瓶颈。连接池技术通过预建立并复用数据库连接,避免了频繁的连接建立和断开,显著提升了数据库访问效率。常见的连接池库包括HikariCP、C3P0和DBCP,它们提供了丰富的配置选项和强大的功能,帮助优化应用性能。
85 2
|
3月前
|
JSON Java Maven
实现Java Spring Boot FCM推送教程
本指南介绍了如何在Spring Boot项目中集成Firebase云消息服务(FCM),包括创建项目、添加依赖、配置服务账户密钥、编写推送服务类以及发送消息等步骤,帮助开发者快速实现推送通知功能。
134 2
|
2月前
|
Java 数据库连接 API
Spring 框架的介绍(Java EE 学习笔记02)
Spring是一个由Rod Johnson开发的轻量级Java SE/EE一站式开源框架,旨在解决Java EE应用中的多种问题。它采用非侵入式设计,通过IoC和AOP技术简化了Java应用的开发流程,降低了组件间的耦合度,支持事务管理和多种框架的无缝集成,极大提升了开发效率和代码质量。Spring 5引入了响应式编程等新特性,进一步增强了框架的功能性和灵活性。
52 0
|
2月前
|
安全 Java 测试技术
Java开发必读,谈谈对Spring IOC与AOP的理解
Spring的IOC和AOP机制通过依赖注入和横切关注点的分离,大大提高了代码的模块化和可维护性。IOC使得对象的创建和管理变得灵活可控,降低了对象之间的耦合度;AOP则通过动态代理机制实现了横切关注点的集中管理,减少了重复代码。理解和掌握这两个核心概念,是高效使用Spring框架的关键。希望本文对你深入理解Spring的IOC和AOP有所帮助。
45 0
|
8月前
|
NoSQL Java Redis
用java写个redis工具类
用java写个redis工具类
149 0