Spring Data Redis学习

Posted LarryZeal

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring Data Redis学习相关的知识,希望对你有一定的参考价值。

本文是从为知笔记上复制过来的,懒得调整格式了,为知笔记版本是带格式的。点这里 为知笔记版本

Spring Data Redis 学习
Version 1.8.4.Release


 
 
 

前言

Spring Data Redis project,应用了Spring概念来开发使用键值形式的数据存储的解决方案。我们(官方)提供了一个 "template" ,这是一个高级别的抽象,来发送和接收消息。你会注意到它与Spring框架对JDBC的支持有些类似。

1、新功能

最近更新中 新的、且 值得一提的功能。

1.1、Spring Data Redis 1.8 新特性

  • Jedis升级到2.9。
  • Lettuce升级到4.2。(注意,Lettuce 4.2要求Java8)。
  • 支持Redis GEO 命令。
  • 使用Spring Data Repository抽象来支持Geo索引。
  • 基于HashMapper实现的MappingRedisConverter。
  • 在repository支持中支持PartialUpdate。
  • 对于连接到Redis cluster的SSL支持。
  • 当使用Jedis时,支持通过ConnectionFactory来设置client name。

1.2、Spring Data Redis 1.7 新特性
  • 支持RedisCluster。
  • 支持Spring Data Repository抽象。

1.3、Spring Data Redis 1.6 新特性

  • Lettuce Redis驱动,由wg/lettuce切换到mp911de/lettuce。
  • 支持ZRANGEBYLEX.
  • 增强了ZSET的range操作,包括 +inf 、 -inf。
  • RedisCache的性能改进,更早释放连接。
  • Generic Jackson2 RedisSerializer,利用了Jackson的多态反序列化

 

1.4、Spring Data Redis 1.5 新特性

  • 添加对Redis HyperLogLog命令的支持:PFADD、PFCOUNT、PFMERGE。
  • 可配置的JavaType查找,用于基于RedisSerializers的Jackson。
  • 基于PropertySource的配置,用于连接到Redis Sentinel。

介绍

本文档是Spring Data Redis (SDR) Support的引用指导。它结束了Key Value模块概念和语法,以及不同存储命名空间的语义。
 
如果想要key value存储或者Spring的介绍,或者Spring Data例子,请转到 Getting Started,本文档仅涉及到Spring Data Redis支持,并默认用户熟悉key value存储 以及Spring 的概念。

2、为什么选择Spring Data Redis?

Spring框架,是引领潮流的全栈Java/JEE应用框架。它提供了一个轻量级容器,一种非侵入式的编程模型 -- 这是由依赖注入、AOP、以及便携的服务抽象开启的。
 
NoSQL存储,提供了传统RDBMS之外的一种选择。
 
SDR框架,使得利用Redis键值存储非常简单,消除了繁复冗余的任务和呆板的代码(指获取连接、释放资源)。

3、要求

  • SDR 1.x要求JDK 6.0及以上,要求Spring框架4.3.9.RELEASE及以上。
  • Redis 2.6.x及以上。

4、开始

学习一个新框架并不简单直接。在本部分,我们(官方)试图提供一个 我们认为的 简单易懂的指导,来开始使用SDR。当然,你可以创建适合自己的学习路径,如果可以,请告诉我们,以便帮助其他人。

4.1、第一步

如同前面所解释的,SDR提供了Spring框架和Redis键值存储的集成。因此,掌握这两个框架非常重要。
虽然本文档的每一部分都提供了相关资源的连接,但最好还是提前熟悉下。
4.1.1、了解Spring
Spring Data严重依赖Spring框架的核心功能,例如IoC容器、资源抽象、或者AOP。重要的不是掌握Spring的APIs,而是理解它们背后的概念。至少,应该熟悉IoC。简单的说,你对Spring了解的越多,越容易上手SDR。

4.1.2、了解NoSQL和键值存储

略。

4.1.3、尝试案例

在 http://github.com/spring-projects/spring-data-keyvalue-examples上,你可以找到各种各样的键值存储的例子。retwisj。

4.2、需要帮助?

4.2.1、社区帮助

stackoverflow上面,Spring Data 标签。

4.2.2、专业帮助

Pivotal Software, Inc。

4.3、跟随开发

略。

参考文档

5、Redis支持

Spring Data支持的键值存储中包括了Redis。
SDR提供了简单的配置和访问Redis的方式 -- 在Spring应用中。它提供了low-level和high-level抽象 -- 与存储交互,解放了用户。

5.1、Redis要求

Redis 2.6及以上、Java SE 6.0及以上。在connectors方面,Spring Redis集成了Jedis、JRedis(自1.7起已废弃)、SRP(自1.7起已废弃)、以及Lettuce,四个最流行的开源Java Redis库。

5.2、Redis支持高级视图

Redis支持提供了几个组件(按照依赖顺序):
对于大多数人来说,high-level抽象和支持服务是最佳选择。请注意,用户可以在不同的层次之间切换 -- 例如,获取low-level连接(甚至native库)来与Redis通信。

5.3、连接到Redis

使用Redis和Spring的第一步就是通过IoC容器连接到存储。想要实现连接,一个java connector(或者binding)是必需的。无论选择什么库,都只有一套SDR API,叫做 org.springframework.data.redis.connection package,以及RedisConnection和RedisConnectionFactory接口,来获取到Redis的活动连接。

5.3.1、RedisConnection 和 RedisConnectionFactory

RedisConnection 为Redis通信提供了构建模块,会处理与Redis后端的通信。也会将底层连接库的异常自动翻译成Spring的一致的DAO异常层级,因此,用户能够自由切换connectors,而不必修改代码。
注意:对于需要native库API的情况,RedisConnection提供了专有方法getNativeConnection -- 会返回原生的、底层的用于通信的对象。
活动的RedicConnection由RedisConnectionFactory创建。另外,该工厂还扮演了PersistenceExceptionTranslator,就是说,一旦声明了,它们会允许用户进行透明的异常翻译。例如,通过使用@Repository和AOP的异常翻译。更多信息,见Spring框架的相关部分。
注意:依赖于底层的配置,工厂会返回一个新的连接 或者 一个现有的连接(使用pool或者shared native connection时)。
使用RedisConnectionFactory最简单的方式,是通过IoC容器配置相应的connector,并将其注入使用类中。
重要:不幸的是,目前,不是所有的connector都支持所有的Redis功能。当调用底层库不支持的API时,会抛出UnsupportedOperationException。这种情况在将来可能被解决,视不同的connector的成熟情况。

5.3.2、配置Jedis connector

Jedis最简单的形式的配置:
    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <beans xmlns="http://www.springframework.org/schema/beans"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xsi:schemaLocation="http://www.springframework.org/schema/beans
    5. http://www.springframework.org/schema/beans/spring-beans.xsd">
    6. <!-- Jedis ConnectionFactory -->
    7. <bean id="jedisConnectionFactory" 
    8. class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"/>
    9. </beans>
     
生产使用时,用户可能想要调整设置,例如host或者password:
    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <beans xmlns="http://www.springframework.org/schema/beans"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xmlns:p="http://www.springframework.org/schema/p"
    5. xsi:schemaLocation="http://www.springframework.org/schema/beans
    6. http://www.springframework.org/schema/beans/spring-beans.xsd">
    7. <bean id="jedisConnectionFactory"
    8. class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
    9. p:host-name="server"
    10. p:port="6379" />
    11. </beans>
     

5.3.3、配置JRedis connector(自1.7起废弃)

略。

5.3.4、配置SRP connector(自1.7起废弃)

略。

5.3.5、配置Lettuce connector

Lettuce是SDR支持的第四个开源connector。
它的配置很好猜:
    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <beans xmlns="http://www.springframework.org/schema/beans"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xmlns:p="http://www.springframework.org/schema/p"
    5. xsi:schemaLocation="http://www.springframework.org/schema/beans
    6. http://www.springframework.org/schema/beans/spring-beans.xsd">
    7. <bean id="lettuceConnectionFactory"
    8. class="org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory"
    9. p:hostname="server"
    10. p:port="6379"/>
    11. </beans>
    同样,也有一些Lettuce特有的连接参数可以调整。默认,LettuceConnectionFactory创建的所有LettuceConnection都共享相同的线程安全的native 连接 -- 针对非阻塞式和非事务性操作而言。
注意:可以设置shareNativeConnection为false,这样每次都使用专有的连接。
注意:LettuceConnectionFactory 也可以为pooling blocking和事务连接配置一个LettucePool,或者,为所有连接配置一个LettucePool -- 如果shareNativeConnection设为false的话。

5.4、Redis Sentinel支持

为了处理高可用Redis,可以使用RedisSentinelConfiguration来支持Redis Sentinel。
注意:目前,只有Jedis和Lettuce支持Redis Sentinel。
    1. /**
    2. * jedis
    3. */
    4. @Bean
    5. public RedisConnectionFactory jedisConnectionFactory() {
    6. RedisSentinelConfiguration sentinelConfig = new RedisSentinelConfiguration().master("mymaster").sentinel("127.0.0.1", 26379) .sentinel("127.0.0.1", 26380);
    7. return new JedisConnectionFactory(sentinelConfig);
    8. }
    9. /**
    10. * lettuce
    11. */
    12. @Bean
    13. public RedisConnectionFactory lettuceConnectionFactory() {
    14. RedisSentinelConfiguration sentinelConfig = new RedisSentinelConfiguration().master("mymaster").sentinel("127.0.0.1", 26379) .sentinel("127.0.0.1", 26380);
    15. return new LettuceConnectionFactory(sentinelConfig);
    16. }
RedisSentinelConfiguration也可以通过PropertySource来定义。
  • spring.redis.sentinel.master: master节点的名字
  • spring.redis.sentinel.nodes: 以逗号间隔的host:port列表
有时候,需要直接与Sentinels中的某一个进行交互。使用RedisConnectionFactory.getSentinelConnection() 或者RedisConnection.getSentinelCommands(),可以让你访问第一个活动的Sentinel。

5.5、使用RedisTemplate操作Objects

多数用户会喜欢使用RedisTemplate和相应的包org.springframework.data.redis.core,该template是Redis模块的中心类 -- 由于丰富的功能集。该template为Redis交互提供了一个高级别的抽象。当RedisConnection提供了低级别的方法来接受和返还二进制值(byte arrays)时,该template负责了序列化和连接管理,将用户从这里细节中解放了出来。
更多地,该template提供了操作视图(following the grouping from Redis command
reference) -- 提供了丰富的接口 来操作特定类型或特定key(通过KeyBound接口),如下:
Table 1. Operational views
InterfaceDescription

Key Type Operations

ValueOperations

Redis string (or value) operations

ListOperations

Redis list operations

SetOperations

Redis set operations

ZSetOperations

Redis zset (or sorted set) operations

HashOperations

Redis hash operations

HyperLogLogOperations

Redis HyperLogLog operations like (pfadd, pfcount,…)

GeoOperations

Redis geospatial operations like GEOADD, GEORADIUS,…)

Key Bound Operations

BoundValueOperations

Redis string (or value) key bound operations

BoundListOperations

Redis list key bound operations

BoundSetOperations

Redis set key bound operations

BoundZSetOperations

Redis zset (or sorted set) key bound operations

BoundHashOperations

Redis hash key bound operations

BoundGeoOperations

Redis key bound geospatial operations.

一旦配置了,该template就是线程安全的,可被多个实例复用。
开箱即用,RedisTemplate使用一个基于Java的序列化器 用于多数操作。这意味着,该template读/写的任意object会通过Java来序列化/反序列化。
该template的序列化机制可以轻松地修改,该Redis模块提供了几个实现,在org.springframework.data.redis.serializer包中。你也可以不使用序列化器,直接让RedisTemplate使用原生byte数组,只需要将enableDefaultSerializer设为false即可。
注意,该template要求所有的key都不能是null,但value可以是null -- 只要底层的序列化器接受;更多内容,请查看每个序列化器的javadoc。
 
当需要一个特定的template view时,将view声明为依赖,并注入该template中即可:容器会自动执行转换:
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:p="http://www.springframework.org/schema/p"
  5. xsi:schemaLocation="http://www.springframework.org/schema/beans
  6. http://www.springframework.org/schema/beans/spring-beans.xsd">
  7. <bean id="jedisConnectionFactory"
  8. class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
  9. p:use-pool="true"/>
  10. <!-- redis template definition -->
  11. <bean id="redisTemplate"
  12. class="org.springframework.data.redis.core.RedisTemplate"
  13. p:connection-factory-ref="jedisConnectionFactory"/>
  14. ...
  15. </beans>
  1. public class Example {
  2. // inject the actual template
  3. @Autowired
  4. private RedisTemplate<String, String> template;
  5. // inject the template as ListOperations -- 自动转换
  6. @Resource(name="redisTemplate")
  7. private ListOperations<String, String> listOps;
  8. public void addLink(String userId, URL url) {
  9. listOps.leftPush(userId, url.toExternalForm());
  10. }
  11. }
 
5.6、聚焦String的便捷类
鉴于使用java.lang.String来作为key/value 存储到Redis中 非常常见,该Redis模块还提供了RedisConnection和RedisTemplate的两个扩展:StringRedisConnection(以及其DefaultStringRedisConnection实现)和StringRedisTemplate。此外,该template和连接,底层使用了StringRedisSerializer。例如:
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:p="http://www.springframework.org/schema/p"
  5. xsi:schemaLocation="http://www.springframework.org/schema/beans
  6. http://www.springframework.org/schema/beans/spring-beans.xsd">
  7. <bean id="jedisConnectionFactory" 
  8. class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" 
  9. p:use-pool="true"/>
  10. <bean id="stringRedisTemplate" 
  11. class="org.springframework.data.redis.core.StringRedisTemplate" 
  12. p:connection-factory-ref="jedisConnectionFactory"/>
  13. ...
  14. </beans>
  1. public class Example {
  2. @Autowired
  3. private StringRedisTemplate redisTemplate;
  4.  
  5. public void addLink(String userId, URL url) {
  6. redisTemplate.opsForList().leftPush(userId, url.toExternalForm());
  7. }
  8. }
如同其他的Spring template,RedisTemplate和StringRedisTemplate允许开发者通过RedisCallback接口直接与Redis对话。这赋予了开发者完整的控制,因为是直接与RedisConnection交互。注意,当使用StringRedisTemplate时,该callback接收的是一个StringRedisConnection实例。
  1. public void useCallback() {
  2. redisTemplate.execute(new RedisCallback<Object>() {
  3. public Object doInRedis(RedisConnection connection) throws DataAccessException {
  4. Long size = connection.dbSize();
  5. // Can cast to StringRedisConnection if using a StringRedisTemplate
  6. ((StringRedisConnection)connection).set("key", "value");
  7. }
  8. });
  9. }
5.7、序列化器 Serializers
从框架角度来说,存储在Redis中的数据都是bytes。然而,Redis本身支持不同的类型,更多时候这些是指data存储的方式,而非其表现形式。由用户来决定 信息是否需要转成String或者其他对象。SDR中,用户的类型和原生类型之间的转换,是通过RedisSerializer接口来实现的,如名所示,负责序列化过程。SDR提供了多个开箱即用的实现,其中的两个已经在上面提到了:StringRedisSerializer和JdkSerializationRedisSerializer。然而,用户也可以使用OxmSerializer来处理Object/XML映射 -- 通过Spring 3OXM支持;或者,使用JacksonJsonRedisSerializer、Jackson2JsonRedisSerializer、或者GenericJackson2JsonRedisSerializer 来实现JSON格式的存储。
注意,存储格式不仅限于值,它可以用于键、值、哈希,没有任何限制。

5.8、Hash映射

Redis中,数据可以使用不同的数据结构来存储。你已经知道 Jackson2JsonRedisSerializer可以将objects转成JSON格式。JSON可以使用字符串来存储。而通过使用Redis Hashes,可以实现一种更复杂的结构化对象的映射。SDR提供了不同的策略来将数据映射成hashes -- 取决于使用情况:
  1. 使用HashOperations和一个序列化器,直接映射。
  2. 使用Redis Repositories。
  3. 使用HashMapper和HashOperations。
5.8.1、Hash mappers   哈希映射器
Hash mappers是将objects与Map<K, V>互相转换的转换器。HashMapper用于Redis Hashes。
多个开箱即用的实现:
  1. BeanUtilsHashMapper,使用Spring的BeanUtils。
  2. ObjectHashMapper,使用Object to Hash Mapping。
  3. Jackson2HashMapper,使用FasterXML Jackson。
  1. public class Person {
  2. String firstname;
  3. String lastname;
  4. // …
  5. }
  6. public class HashMapping {
  7. @Autowired
  8. HashOperations<String, byte[], byte[]> hashOperations;
  9.  
  10. HashMapper<Object, byte[], byte[]> mapper = new ObjectHashMapper();
  11.  
  12. public void writeHash(String key, Person person) {
  13. Map<byte[], byte[]> mappedHash = mapper.toHash(person);
  14. hashOperations.putAll(key, mappedHash);
  15. }
  16.  
  17. public Person loadHash(String key) {
  18. Map<byte[], byte[]> loadedHash = hashOperations.entries("key");
  19. return (Person) mapper.fromHash(loadedHash);
  20. }
  21. }
 
5.8.2、Jackson2HashMapper
Jackson2HashMapper 使用FasterXML Jackson为Redis Hash来映射domain objects。
Jackson2HashMapper 可以映射数据映射高级properties作为Hash字段名字,以及可选的扁平结构。简单类型映射成简单的值。复杂类型(嵌套的objects、集合、maps)会表现成嵌套的JSON。
扁平化 为所有的嵌套properties创建了独立的hash entries,将复杂类型用简单类型表示。
  1. public class Person {
  2. String firstname;
  3. String lastname;
  4. Address address;
  5. }
  6. public class Address {
  7. String city;
  8. String country;
  9. }
Table 2. Normal Mapping
Hash FieldValue

firstname

Jon

lastname

Snow

address

{ "city" : "Castle Black", "country" : "The North" }

Table 3. Flat Mapping
Hash FieldValue

firstname

Jon

lastname

Snow

address.city

Castle Black

address.country

The North

注意:扁平化,要求所有的property name不能与JSON path冲突。在map中使用点或者括号作为key,或者在实体中作为property name,都不行。如果非要这样做,那得到的hash是无法被映射回对象的。

5.9、Redis 消息/发布订阅

 
5.9.1、发送/发布消息
5.9.2、接收/订阅消息

5.10、Redis事务

5.10.1、@Transactional 支持
5.11、Pipelining  管道
5.12、Redis 脚本

5.13、支持类

5.13.1、对于Spring Cache抽象的支持
6、Redis Cluster
6.1、启用Redis Cluster
6.2、Redis Cluster连接
6.3、使用RedisTemplate 和 ClusterOperations

7、Redis Repositories
7.1、使用
7.2、Object to Hash Mapping
7.3、Keyspaces

7.4、Secondary Indexes

7.4.1、Simple Property Index

7.4.2、Geospatial Index


7.5、Time To Live  存活时间
7.6、持久化参考
7.7、Persisting Partial Updates
7.8、查询和查询方法
7.9、运行在Cluster上的Redis Repositories
7.10、CDI集成

 


















































以上是关于Spring Data Redis学习的主要内容,如果未能解决你的问题,请参考以下文章

Spring + Jedis集成Redis

分布式缓存技术redis学习系列----深入理解Spring Redis的使用

redis学习系列--JedisPool与spring集成的实现及一致性哈希分析和基于Redis的分布式锁

Spring Data(数据)Redis

Spring Data Redis两个问题:内存泄露和并发 - europace

spring-data-redis,jedis和redis主从集成和遇到的问题