gpt4 book ai didi

Spring框架接入单机Redis两种实现方式解析

转载 作者:qq735679552 更新时间:2022-09-27 22:32:09 27 4
gpt4 key购买 nike

CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.

这篇CFSDN的博客文章Spring框架接入单机Redis两种实现方式解析由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.

1、Redis的简单介绍 。

1)Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。 它支持多种类型的数据结构,如 字符串(strings), 散列(hashes), 列表(lists), 集合(sets), 有序集合(sorted sets) 与范围查询, bitmaps, hyperloglogs 和 地理空间(geospatial) 索引半径查询。 这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。Redis 内置了 复制(replication),LUA脚本(Lua scripting), LRU驱动事件(LRU eviction),事务(transactions) 和不同级别的 磁盘持久化(persistence), 并通过 Redis哨兵(Sentinel)和自动 分区(Cluster)提供高可用性(high availability)。Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库.

2)Redis的内存管理机制:

在Redis中,并不是所有的数据都一直存储在内存中的。当物理内存用完时,Redis可以将一些很久没用到的value交换到磁盘。Redis只会缓存所有的key的信息,如果Redis发现内存的使用量超过了某一个阀值,将触发swap的操作,Redis根据“swappability = age*log(size_in_memory)”计算出哪些key对应的value需要swap到磁盘。然后再将这些key对应的value持久化到磁盘中,同时在内存中清除。这种特性使得Redis可以保持超过其机器本身内存大小的数据.

3)Redis性能和集群管理:

Redis虽然支持数据的持久化,但是全内存毕竟才是其高性能的本质。作为基于内存的存储系统来说,机器物理内存的大小就是系统能够容纳的最大数据量。如果需要处理的数据量超过了单台机器的物理内存大小,就需要构建分布式集群来扩展存储能力。Redis更偏向于在服务器端构建分布式存储.

4)Redis 同其他 key - value 缓存数据库比较具有以下 。

  • Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。
  • Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。
  • Redis支持数据的备份,即master-slave模式的数据备份。

5)Redis优势 。

  • .性能极高 – Redis能读的速度是110000次/s,写的速度是81000次/s 。
  • .丰富的数据类型 – Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。
  • .原子 – Redis的所有操作都是原子性的,意思就是要么成功执行要么失败完全不执行。单个操作是原子性的。多个操作也支持事务,即原子性,通过MULTI和EXEC指令包起来。
  • .丰富的特性 – Redis还支持 publish/subscribe, 通知, key 过期等等特性。
  • .Redis运行在内存中但是可以持久化到磁盘,所以在对不同数据集进行高速读写时需要权衡内存,因为数据量不能大于硬件内存。在内存数据库方面的另一个优点是,相比在磁盘上相同的复杂的数据结构,在内存中操作起来非常简单,这样Redis可以做很多内部复杂性很强的事情。同时,在磁盘格式方面他们是紧凑的以追加的方式产生的,因为他们并不需要进行随机访问。

2、spring框架中接入redis的两种方式

步骤1:引入相关依赖 。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<!--使用jedis 需要引入 commons-pool 的依赖,否则Jedis会实例化失败-->
     < dependency >
       < groupId >redis.clients</ groupId >
       < artifactId >jedis</ artifactId >
       < version >2.7.1</ version >
     </ dependency >
     < dependency >
       < groupId >commons-pool</ groupId >
       < artifactId >commons-pool</ artifactId >
       < version >1.5.6</ version >
     </ dependency >
 
     < dependency >
       < groupId >org.springframework.data</ groupId >
       < artifactId >spring-data-redis</ artifactId >
       < version >1.6.2.RELEASE</ version >
     </ dependency >
 
     <!-- redis中 如果存储的是Map<String,Object>需要导入jackson相关的包,存储的时候使用json序列化器存储。如果不导入jackson的包会报错。 -->
     < dependency >
       < groupId >com.fasterxml.jackson.core</ groupId >
       < artifactId >jackson-core</ artifactId >
       < version >2.5.1</ version >
     </ dependency >
     < dependency >
       < groupId >com.fasterxml.jackson.core</ groupId >
       < artifactId >jackson-databind</ artifactId >
       < version >2.5.1</ version >
     </ dependency >
     < dependency >
       < groupId >com.fasterxml.jackson.core</ groupId >
       < artifactId >jackson-annotations</ artifactId >
       < version >2.5.1</ version >
     </ dependency >

步骤2:Redis相关属性文件:redis.properties 。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#访问地址
redis.host=127.0.0.1
#访问端口
redis.port=6379
#注意,如果没有password,此处不设置值,但这一项要保留
redis.password=@redisLearn
 
#最大空闲数,数据库连接的最大空闲时间。超过空闲时间,数据库连接将被标记为不可用,然后被释放。设为0表示无限制。
redis.maxIdle=300
#连接池的最大数据库连接数。设为0表示无限制
redis.maxActive=600
 
#最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示无限制。
redis.maxWait=1000
 
#在borrow一个jedis实例时,是否提前进行alidate操作;如果为true,则得到的jedis实例均是可用的;
redis.testOnBorrow= true
 
#客户端连接超时时间
redis.timeout=30000
 
#可用数据库数
redis.database = 0

步骤3:Spring中引入Redis配置、及调用实例(方式1和方式2选择其中一种进行配置) 。

  方式1:通过spring-data-redis工具实现对Redis的操作 spring-redis.xml 。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
<? xml version = "1.0" encoding = "UTF-8" ?>
< beans xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
     xmlns = "http://www.springframework.org/schema/beans" xmlns:context = "http://www.springframework.org/schema/context"
     xmlns:aop = "http://www.springframework.org/schema/aop" xmlns:tx = "http://www.springframework.org/schema/tx"
     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
">
 
   <!-- 连接池基本参数配置,类似数据库连接池 -->
   < context:property-placeholder location = "classpath:conf/redis.properties" ignore-unresolvable = "true" />
 
   <!-- redis连接池 -->
   < bean id = "poolConfig" class = "redis.clients.jedis.JedisPoolConfig" >
     < property name = "maxTotal" value = "${redis.maxActive}" />
     < property name = "maxIdle" value = "${redis.maxIdle}" />
     < property name = "testOnBorrow" value = "${redis.testOnBorrow}" />
   </ bean >
 
   <!-- 连接池配置,类似数据库连接池 -->
   < bean id = "jedisConnectionFactory"
      class = "org.springframework.data.redis.connection.jedis.JedisConnectionFactory" >
     < property name = "hostName" value = "${redis.host}" ></ property >
     < property name = "port" value = "${redis.port}" ></ property >
     <!-- <property name="password" value="${redis总结.pass}"></property> -->
     < property name = "poolConfig" ref = "poolConfig" ></ property >
   </ bean >
 
   <!--redis操作模版,使用该对象可以操作redis -->
   < bean id = "redisTemplate" class = "org.springframework.data.redis.core.RedisTemplate" >
     < property name = "connectionFactory" ref = "jedisConnectionFactory" />
     <!--如果不配置Serializer,那么存储的时候缺省使用String,如果用User类型存储,那么会提示错误User can't cast to String!! -->
     < property name = "keySerializer" >
       < bean class = "org.springframework.data.redis.serializer.StringRedisSerializer" />
     </ property >
     < property name = "valueSerializer" >
       < bean class = "org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer" />
     </ property >
     < property name = "hashKeySerializer" >
       < bean class = "org.springframework.data.redis.serializer.StringRedisSerializer" />
     </ property >
     < property name = "hashValueSerializer" >
       < bean class = "org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer" />
     </ property >
     <!--开启事务 -->
     < property name = "enableTransactionSupport" value = "true" ></ property >
   </ bean >
 
</ beans >

方式2:通过jedis客户端工具实现对Redis的操作 spring-jedis.xml 。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<? xml version = "1.0" encoding = "UTF-8" ?>
< beans xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
     xmlns = "http://www.springframework.org/schema/beans" xmlns:context = "http://www.springframework.org/schema/context"
     xmlns:aop = "http://www.springframework.org/schema/aop" xmlns:tx = "http://www.springframework.org/schema/tx"
     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
">
 
   <!-- 连接池基本参数配置,类似数据库连接池 -->
   < context:property-placeholder location = "classpath:conf/redis.properties" ignore-unresolvable = "true" />
 
   <!-- redis连接池 -->
   < bean id = "poolConfig" class = "redis.clients.jedis.JedisPoolConfig" >
     < property name = "maxTotal" value = "${redis.maxActive}" />
     < property name = "maxIdle" value = "${redis.maxIdle}" />
     < property name = "testOnBorrow" value = "${redis.testOnBorrow}" />
   </ bean >
 
   < bean id = "jedisPool" class = "redis.clients.jedis.JedisPool" >
     < constructor-arg name = "poolConfig" ref = "poolConfig" />
     < constructor-arg name = "host" value = "${redis.host}" />
     < constructor-arg name = "port" value = "${redis.port}" type = "int" />
     < constructor-arg name = "timeout" value = "${redis.timeout}" type = "int" />
     < constructor-arg name = "password" value = "${redis.password}" />
     < constructor-arg name = "database" value = "${redis.database}" type = "int" />
   </ bean >
 
</ beans >

步骤4:在web.xml中进行 进行 servletContext上下文读取 。

?
1
2
3
4
5
6
7
< context-param >
   < param-name >contextConfigLocation</ param-name >
   < param-value >
    <!--classpath:spring/spring-redis.xml,-->
     classpath:spring/spring-jedis.xml,
   </ param-value >
  </ context-param >

步骤5:接入测试 。

方式1:测试代码 。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
@Controller
@RequestMapping ( "/redis" )
public class RedisController {
 
@Resource (name= "redisTemplate" )
   private RedisTemplate redisTemplate;
 
   @RequestMapping ( "/operate.do" )
   @ResponseBody
   public Map springRedisDo() {
     Map result= new HashMap();
 
     // stringRedisTemplate的操作
     // String读写
     redisTemplate.delete( "myStrKey" );
     redisTemplate.opsForValue().set( "myStrKey" , "strValue" );
     String strValue= (String) redisTemplate.opsForValue().get( "myStrKey" );
     result.put( "strValue" ,strValue);
 
     // List读写
     redisTemplate.delete( "myListKey" );
     redisTemplate.opsForList().rightPush( "myListKey" , "listValue1" );
     redisTemplate.opsForList().rightPush( "myListKey" , "listValue2" );
     redisTemplate.opsForList().leftPush( "myListKey" , "listValue3" );
     List<String> myListKeyValues = redisTemplate.opsForList().range( "myListKey" , 0 , - 1 );
     for (String s : myListKeyValues) {
       System.out.println( "myListKey数据元素>>>" +s);
     }
     result.put( "myListKeyValues" ,myListKeyValues);
 
     // Set读写
     redisTemplate.delete( "mySet" );
     redisTemplate.opsForSet().add( "mySetKey" , "setValue1" );
     redisTemplate.opsForSet().add( "mySetKey" , "setValue2" );
     redisTemplate.opsForSet().add( "mySetKey" , "setValue3" );
     redisTemplate.opsForSet().add( "mySetKey" , "setValue3" );
     redisTemplate.opsForSet().add( "mySetKey" , "setValue3" );
     Set<String> setValues = redisTemplate.opsForSet().members( "mySetKey" );
     for (String s : setValues) {
       System.out.println( "mySetKey数据元素>>>" +s);
     }
     result.put( "setValues" ,setValues);
 
     // Hash读写
     redisTemplate.delete( "myHashKey" );
     redisTemplate.opsForHash().put( "myHashKey" , "BJ" , "北京" );
     redisTemplate.opsForHash().put( "myHashKey" , "SH" , "上海" );
     redisTemplate.opsForHash().put( "myHashKey" , "TJ" , "天津" );
     Map<String, String> hashValues = redisTemplate.opsForHash().entries( "myHashKey" );
     List myHashList= redisTemplate.opsForHash().values( "myHashKey" );
     System.out.println( "myHashList数据信息>>>" +myHashList);
     for (Map.Entry entry : hashValues.entrySet()) {
       System.out.println( "myHashValues>>>" +entry.getKey() + " - " + entry.getValue());
     }
     result.put( "hashValues" ,hashValues);
 
     return result;
   }
}

spring 封装了 RedisTemplate 对象来进行对redis的各种操作,它支持所有的 redis 原生的 api。在RedisTemplate中提供了几个常用的接口方法的使用,分别是

RedisTemplate中定义了对5种数据结构操作 。

  • redisTemplate.opsForValue();//操作字符串
  • redisTemplate.opsForHash();//操作hash
  • redisTemplate.opsForList();//操作list
  • redisTemplate.opsForSet();//操作set
  • redisTemplate.opsForZSet();//操作有序set

注:StringRedisTemplate与 RedisTemplate关系 。

StringRedisTemplate继承RedisTemplate,两者的数据是不共通的;也就是说StringRedisTemplate只能管理StringRedisTemplate里面的数据,RedisTemplate只能管理RedisTemplate中的数据。SDR默认采用的序列化策略有两种,一种是String的序列化策略,一种是JDK的序列化策略。StringRedisTemplate默认采用的是String的序列化策略,保存的key和value都是采用此策略序列化保存的。RedisTemplate默认采用的是JDK的序列化策略,保存的key和value都是采用此策略序列化保存的.

方式2:测试代码 。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
@Controller
@RequestMapping ( "/jedis/" )
public class JedisController {
 
   @Autowired
   private JedisPool jedisPool;
 
  
   /**
    * @Method:
    * @Author:
    * @Description:
    * param: 通过jedis客户端,往Redis中 存入数据
    * @Return:
    * @Exception:
    * @Date: 2020/9/10 10:38
    */
   @RequestMapping ( "save" )
   @ResponseBody
   public Map getSave(String key, String val) {
     Map result= new HashMap();
     boolean executeResult= false ;
     Jedis jedis = null ;
     try {
       jedis = jedisPool.getResource();
       jedis.set(key, val);
       executeResult= true ;
     } catch (Exception e) {
       System.out.println( "获取jedis链接异常" +e);
     }
     result.put( "executeResult" ,executeResult);
     return result;
   }
 
   /**
    * @Method:
    * @Author:
    * @Description:
    * param: 查询Redis中存储的信息
    * @Return:
    * @Exception:
    * @Date: 2020/9/10 10:40
    */
   @RequestMapping ( "queryKeyInfo.do" )
   @ResponseBody
   public Map getKey(String key) {
     Map result= new HashMap();
     Jedis jedis = jedisPool.getResource();
     String redisValue=jedis.get(key);
     result.put( "key" ,redisValue);
     return result;
   }
}

通过redis.clients.jedis.JedisPool来管理,即通过池来管理,通过池对象获取jedis实例,然后通过jedis实例直接操作redis服务,剔除了与业务无关的冗余代码,从工厂类到池的方式变化,就相当于mybatis连接mysql方变化是一样的,代码变得更简洁,维护也更容易了。Jedis使用apache commons-pool2对Jedis资源池进行管理,所以在定义JedisPool时一个很重要的参数就是资源池GenericObjectPoolConfig 。

注:使用JedisPool 的方式进行redis操作时候,需要设置redis服务的登录密码,否则会有相应的错误提示。redis.windows.conf 文件中 通过修改requirepass 信息来进行redis服务访问密码设置,并通过redis-server.exe redis.windows.conf 命令方式进行访问,否则会报错:redis.clients.jedis.exceptions.JedisDataException: ERR Client sent AUTH, but no password is set 。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我.

原文链接:https://www.cnblogs.com/jiarui-zjb/p/13645858.html 。

最后此篇关于Spring框架接入单机Redis两种实现方式解析的文章就讲到这里了,如果你想了解更多关于Spring框架接入单机Redis两种实现方式解析的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com