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

网友投稿 273 2022-11-20


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:引入相关依赖

redis.clients

jedis

2.7.1

commons-pool

commons-pool

1.5.6

org.springframework.data

spring-data-redis

1.6.2.RELEASE

com.fasterxml.jackson.core

jackson-core

2.5.1

com.fasterxml.jackson.core

jackson-databind

2.5.1

com.fasterxml.jackson.core

jackson-annotations

2.5.1

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

#访问地址

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

xmlns="http://springframework.org/schema/beans" xmlns:context="http://springframework.org/schema/context"

xmlns:aop="http://springframework.org/schema/aop" xmlns:tx="http://springframework.org/schema/tx"

xsi:schemaLocation="http://springframework.org/schema/beans http://springframework.org/schema/beans/spring-beans-3.0.xsd http://springframework.org/schema/context http://springframework.org/schema/context/spring-context-3.0.xsd http://springframework.org/schema/aop http://springframework.org/schema/aop/spring-aop-3.0.xsd http://springframework.org/schema/tx http://springframework.org/schema/tx/spring-tx-3.0.xsd

">

class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">

xmlns="http://springframework.org/schema/beans" xmlns:context="http://springframework.org/schema/context"

xmlns:aop="http://springframework.org/schema/aop" xmlns:tx="http://springframework.org/schema/tx"

xsi:schemaLocation="http://springframework.org/schema/beans http://springframework.org/schema/beans/spring-beans-3.0.xsd http://springframework.org/schema/context http://springframework.org/schema/context/spring-context-3.0.xsd http://springframework.org/schema/aop http://springframework.org/schema/aop/spring-aop-3.0.xsd http://springframework.org/schema/tx http://springframework.org/schema/tx/spring-tx-3.0.xsd

">

class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">

class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">

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

xmlns="http://springframework.org/schema/beans" xmlns:context="http://springframework.org/schema/context"

xmlns:aop="http://springframework.org/schema/aop" xmlns:tx="http://springframework.org/schema/tx"

xsi:schemaLocation="http://springframework.org/schema/beans http://springframework.org/schema/beans/spring-beans-3.0.xsd http://springframework.org/schema/context http://springframework.org/schema/context/spring-context-3.0.xsd http://springframework.org/schema/aop http://springframework.org/schema/aop/spring-aop-3.0.xsd http://springframework.org/schema/tx http://springframework.org/schema/tx/spring-tx-3.0.xsd

">

xmlns="http://springframework.org/schema/beans" xmlns:context="http://springframework.org/schema/context"

xmlns:aop="http://springframework.org/schema/aop" xmlns:tx="http://springframework.org/schema/tx"

xsi:schemaLocation="http://springframework.org/schema/beans http://springframework.org/schema/beans/spring-beans-3.0.xsd http://springframework.org/schema/context http://springframework.org/schema/context/spring-context-3.0.xsd http://springframework.org/schema/aop http://springframework.org/schema/aop/spring-aop-3.0.xsd http://springframework.org/schema/tx http://springframework.org/schema/tx/spring-tx-3.0.xsd

">

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

contextConfigLocation

classpath:spring/spring-jedis.xml,

步骤5:接入测试

方式1:测试代码

@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 myListKeyValues = redisTemplhttp://ate.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 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 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:测试代码

@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


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:解决springboot 多线程使用MultipartFile读取excel文件内容报错问题
下一篇:解决mybatis plus 驼峰式命名规则问题
相关文章

 发表评论

暂时没有评论,来抢沙发吧~