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

本文涉及的产品
云数据库 Redis 版,标准版 2GB
推荐场景:
搭建游戏排行榜
云原生内存数据库 Tair,内存型 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
相关文章
|
12天前
|
Java Maven Windows
使用Java创建集成JACOB的HTTP服务
本文介绍了如何在Java中创建一个集成JACOB的HTTP服务,使Java应用能够调用Windows的COM组件。文章详细讲解了环境配置、动态加载JACOB DLL、创建HTTP服务器、实现IP白名单及处理HTTP请求的具体步骤,帮助读者实现Java应用与Windows系统的交互。作者拥有23年编程经验,文章来源于稀土掘金。著作权归作者所有,商业转载需授权。
使用Java创建集成JACOB的HTTP服务
|
22天前
|
编解码 NoSQL Java
使用Spring Boot + Redis 队列实现视频文件上传及FFmpeg转码的技术分享
【8月更文挑战第30天】在当前的互联网应用中,视频内容的处理与分发已成为不可或缺的一部分。对于视频平台而言,高效、稳定地处理用户上传的视频文件,并对其进行转码以适应不同设备的播放需求,是提升用户体验的关键。本文将围绕使用Spring Boot结合Redis队列技术来实现视频文件上传及FFmpeg转码的过程,分享一系列技术干货。
61 3
|
27天前
|
缓存 NoSQL Java
【Azure Redis 缓存】示例使用 redisson-spring-boot-starter 连接/使用 Azure Redis 服务
【Azure Redis 缓存】示例使用 redisson-spring-boot-starter 连接/使用 Azure Redis 服务
|
22天前
|
Java Devops 持续交付
探索Java中的Lambda表达式:简化代码,提升效率DevOps实践:持续集成与部署的自动化之路
【8月更文挑战第30天】本文深入探讨了Java 8中引入的Lambda表达式如何改变了我们编写和管理代码的方式。通过简化代码结构,提高开发效率,Lambda表达式已成为现代Java开发不可或缺的一部分。文章将通过实际例子展示Lambda表达式的强大功能和优雅用法。
|
22天前
|
缓存 安全 Java
Java服务器端技术:Servlet与JSP的集成与扩展
Java服务器端技术:Servlet与JSP的集成与扩展
15 3
|
21天前
|
持续交付 jenkins Devops
WPF与DevOps的完美邂逅:从Jenkins配置到自动化部署,全流程解析持续集成与持续交付的最佳实践
【8月更文挑战第31天】WPF与DevOps的结合开启了软件生命周期管理的新篇章。通过Jenkins等CI/CD工具,实现从代码提交到自动构建、测试及部署的全流程自动化。本文详细介绍了如何配置Jenkins来管理WPF项目的构建任务,确保每次代码提交都能触发自动化流程,提升开发效率和代码质量。这一方法不仅简化了开发流程,还加强了团队协作,是WPF开发者拥抱DevOps文化的理想指南。
39 1
|
22天前
|
jenkins 持续交付 网络安全
利用 Jenkins 实现持续集成与持续部署-代码拉取终端的配置
【8月更文挑战第30天】在Jenkins服务器中,git和Gitee是常用的代码拉取终端。Git作为分布式版本控制系统,具备出色的灵活性和可扩展性;而Gitee则在国内网络环境下表现更佳,适合团队协作。Git配置包括安装、设置用户信息及生成SSH密钥等步骤;Gitee配置也类似,需注册账号、创建仓库、配置基本信息并设置远程仓库地址。开发人员提交代码后,可通过Webhook、定时轮询或事件监听等方式触发Jenkins动作,确保持续集成和部署高效运行。正确配置这些触发机制并通过测试验证其有效性至关重要。
44 2
|
27天前
|
NoSQL Redis 容器
【Azure Cache for Redis】Redis的导出页面无法配置Storage SAS时通过az cli来完成
【Azure Cache for Redis】Redis的导出页面无法配置Storage SAS时通过az cli来完成
|
27天前
|
缓存 NoSQL 测试技术
【Azure Redis 缓存】Azure Redis 功能性讨论三: 调优参数配置
【Azure Redis 缓存】Azure Redis 功能性讨论三: 调优参数配置
|
18天前
|
jenkins 持续交付 网络安全
利用 Jenkins 实现持续集成与持续部署-代码拉取终端的配置
安装Git、配置用户信息、生成SSH密钥以及在Gitee上创建项目仓库等。
43 0