Spring Data Redis學習

本文是從爲知筆記上覆制過來的,懶得調整格式了,爲知筆記版本是帶格式的,內容也比這裏全。點這裏 爲知筆記版本

Spring Data Redis 學習
Version 1.8.4.Release


 
 
 

前言

Spring Data Redis project,應用了Spring概念來開發使用鍵值形式的數據存儲的解決方案。咱們(官方)提供了一個 "template" ,這是一個高級別的抽象,來發送和接收消息。你會注意到它與Spring框架對JDBC的支持有些相似。

一、新功能

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

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.二、Spring Data Redis 1.7 新特性

  • 支持RedisCluster。
  • 支持Spring Data Repository抽象。

1.三、Spring Data Redis 1.6 新特性

  • Lettuce Redis驅動,由wg/lettuce切換到mp911de/lettuce。
  • 支持ZRANGEBYLEX.
  • 加強了ZSET的range操做,包括 +inf 、 -inf。
  • RedisCache的性能改進,更早釋放鏈接。
  • Generic Jackson2 RedisSerializer,利用了Jackson的多態反序列化

1.四、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 的概念。

二、爲何選擇Spring Data Redis?

Spring框架,是引領潮流的全棧Java/JEE應用框架。它提供了一個輕量級容器,一種非侵入式的編程模型 -- 這是由依賴注入、AOP、以及便攜的服務抽象開啓的。
 
NoSQL存儲,提供了傳統RDBMS以外的一種選擇。
 
SDR框架,使得利用Redis鍵值存儲很是簡單,消除了繁複冗餘的任務和呆板的代碼(指獲取鏈接、釋放資源)。

三、要求

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

四、開始

學習一個新框架並不簡單直接。在本部分,咱們(官方)試圖提供一個 咱們認爲的 簡單易懂的指導,來開始使用SDR。固然,你能夠建立適合本身的學習路徑,若是能夠,請告訴咱們,以便幫助其餘人。

4.一、第一步

如同前面所解釋的,SDR提供了Spring框架和Redis鍵值存儲的集成。所以,掌握這兩個框架很是重要。
雖然本文檔的每一部分都提供了相關資源的鏈接,但最好仍是提早熟悉下。
4.1.一、瞭解Spring
Spring Data嚴重依賴Spring框架的核心功能,例如IoC容器、資源抽象、或者AOP。重要的不是掌握Spring的APIs,而是理解它們背後的概念。至少,應該熟悉IoC。簡單的說,你對Spring瞭解的越多,越容易上手SDR。

4.1.二、瞭解NoSQL和鍵值存儲

略。

4.1.三、嘗試案例

在  http://github.com/spring-projects/spring-data-keyvalue-examples上,你能夠找到各類各樣的鍵值存儲的例子。retwisj。

4.二、須要幫助?

4.2.一、社區幫助

stackoverflow上面,Spring Data 標籤。

4.2.二、專業幫助

Pivotal Software, Inc。

4.三、跟隨開發

略。

參考文檔

五、Redis支持

Spring Data支持的鍵值存儲中包括了Redis。
SDR提供了簡單的配置和訪問Redis的方式 -- 在Spring應用中。它提供了low-level和high-level抽象 -- 與存儲交互,解放了用戶。

5.一、Redis要求

Redis 2.6及以上、Java SE 6.0及以上。在connectors方面,Spring Redis集成了Jedis、JRedis(自1.7起已廢棄)、SRP(自1.7起已廢棄)、以及Lettuce,四個最流行的開源Java Redis庫。

5.二、Redis支持高級視圖

Redis支持提供了幾個組件(按照依賴順序):
對於大多數人來講,high-level抽象和支持服務是最佳選擇。請注意,用戶能夠在不一樣的層次之間切換 -- 例如,獲取low-level鏈接(甚至native庫)來與Redis通訊。

5.三、鏈接到Redis

使用Redis和Spring的第一步就是經過IoC容器鏈接到存儲。想要實現鏈接,一個java connector(或者binding)是必需的。不管選擇什麼庫,都只有一套SDR API,叫作 org.springframework.data.redis.connection package,以及RedisConnection和RedisConnectionFactory接口,來獲取到Redis的活動鏈接。

5.3.一、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.二、配置Jedis connector

Jedis最簡單的形式的配置:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!-- Jedis ConnectionFactory -->
    <bean id="jedisConnectionFactory" 
               class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"/>
</beans>

 

生產使用時,用戶可能想要調整設置,例如host或者password:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="jedisConnectionFactory" 
          class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" 
          p:host-name="server" 
          p:port="6379" />
</beans>

5.3.三、配置JRedis connector(自1.7起廢棄)

略。

5.3.四、配置SRP connector(自1.7起廢棄)

略。

5.3.五、配置Lettuce connector

Lettuce是SDR支持的第四個開源connector。
它的配置很好猜:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="lettuceConnectionFactory" 
          class="org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory" 
          p:hostname="server" 
          p:port="6379"/>
</beans>
一樣,也有一些Lettuce特有的鏈接參數能夠調整。默認,LettuceConnectionFactory建立的全部LettuceConnection都共享相同的線程安全的native 鏈接 -- 針對非阻塞式和非事務性操做而言。
注意:能夠設置shareNativeConnection爲false,這樣每次都使用專有的鏈接。
注意:LettuceConnectionFactory 也能夠爲pooling blocking和事務鏈接配置一個LettucePool,或者,爲全部鏈接配置一個LettucePool -- 若是shareNativeConnection設爲false的話。

5.四、Redis Sentinel支持

爲了處理高可用Redis,可使用RedisSentinelConfiguration來支持Redis Sentinel。
注意:目前,只有Jedis和Lettuce支持Redis Sentinel。
/**
* jedis
*/
@Bean
public RedisConnectionFactory jedisConnectionFactory() {
    RedisSentinelConfiguration sentinelConfig = new RedisSentinelConfiguration().master("mymaster").sentinel("127.0.0.1", 26379) .sentinel("127.0.0.1", 26380);
    return new JedisConnectionFactory(sentinelConfig);
}
/**
* lettuce
*/
@Bean
public RedisConnectionFactory lettuceConnectionFactory() {
    RedisSentinelConfiguration sentinelConfig = new RedisSentinelConfiguration().master("mymaster").sentinel("127.0.0.1", 26379) .sentinel("127.0.0.1", 26380);
    return new LettuceConnectionFactory(sentinelConfig);
}

RedisSentinelConfiguration也能夠經過PropertySource來定義。
  • spring.redis.sentinel.master: master節點的名字
  • spring.redis.sentinel.nodes: 以逗號間隔的host:port列表
有時候,須要直接與Sentinels中的某一個進行交互。使用RedisConnectionFactory.getSentinelConnection() 或者RedisConnection.getSentinelCommands(),可讓你訪問第一個活動的Sentinel。

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
Interface Description

Key Type Operationsjava

ValueOperationsnode

Redis string (or value) operationsgit

ListOperationsgithub

Redis list operationsredis

SetOperationsspring

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中便可:容器會自動執行轉換:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="jedisConnectionFactory" 
          class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" 
          p:use-pool="true"/>
    <!-- redis template definition -->
    <bean id="redisTemplate" 
          class="org.springframework.data.redis.core.RedisTemplate"
          p:connection-factory-ref="jedisConnectionFactory"/>
    ...
</beans>
public class Example {
    // inject the actual template
    @Autowired
    private RedisTemplate<String, String> template;
    // inject the template as ListOperations -- 自動轉換
    @Resource(name="redisTemplate")
    private ListOperations<String, String> listOps;
    public void addLink(String userId, URL url) {
        listOps.leftPush(userId, url.toExternalForm());
    }
}

 

 

5.六、聚焦String的便捷類

鑑於使用java.lang.String來做爲key/value 存儲到Redis中 很是常見,該Redis模塊還提供了RedisConnection和RedisTemplate的兩個擴展:StringRedisConnection(以及其DefaultStringRedisConnection實現)和StringRedisTemplate。此外,該template和鏈接,底層使用了StringRedisSerializer。例如:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="jedisConnectionFactory" 
          class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" 
          p:use-pool="true"/>
    <bean id="stringRedisTemplate" 
          class="org.springframework.data.redis.core.StringRedisTemplate" 
          p:connection-factory-ref="jedisConnectionFactory"/>
    ...
</beans>
public class Example {
    @Autowired
    private StringRedisTemplate redisTemplate;
    
    public void addLink(String userId, URL url) {
        redisTemplate.opsForList().leftPush(userId, url.toExternalForm());
    }
}

 

如同其餘的Spring template,RedisTemplate和StringRedisTemplate容許開發者經過RedisCallback接口直接與Redis對話。這賦予了開發者完整的控制,由於是直接與RedisConnection交互。注意,當使用StringRedisTemplate時,該callback接收的是一個StringRedisConnection實例。
public void useCallback() {
    redisTemplate.execute(new RedisCallback<Object>() {
        public Object doInRedis(RedisConnection connection) throws DataAccessException {
            Long size = connection.dbSize();
            // Can cast to StringRedisConnection if using a StringRedisTemplate
            ((StringRedisConnection)connection).set("key", "value");
        }
    });
}

 

5.七、序列化器 Serializers

從框架角度來講,存儲在Redis中的數據都是bytes。然而,Redis自己支持不一樣的類型,更多時候這些是指data存儲的方式,而非其表現形式。由用戶來決定 信息是否須要轉成String或者其餘對象。SDR中,用戶的類型和原生類型之間的轉換,是經過RedisSerializer接口來實現的,如名所示,負責序列化過程。SDR提供了多個開箱即用的實現,其中的兩個已經在上面提到了:StringRedisSerializer和JdkSerializationRedisSerializer。然而,用戶也可使用OxmSerializer來處理Object/XML映射 -- 經過Spring 3OXM支持;或者,使用JacksonJsonRedisSerializer、Jackson2JsonRedisSerializer、或者GenericJackson2JsonRedisSerializer 來實現JSON格式的存儲。
注意,存儲格式不只限於值,它能夠用於鍵、值、哈希,沒有任何限制。

5.八、Hash映射

Redis中,數據可使用不一樣的數據結構來存儲。你已經知道 Jackson2JsonRedisSerializer能夠將objects轉成JSON格式。JSON可使用字符串來存儲。而經過使用Redis Hashes,能夠實現一種更復雜的結構化對象的映射。SDR提供了不一樣的策略來將數據映射成hashes -- 取決於使用狀況:
  1. 使用HashOperations和一個序列化器,直接映射。
  2. 使用Redis Repositories。
  3. 使用HashMapper和HashOperations。

5.8.一、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。
public class Person {
    String firstname;
    String lastname;
    //
}
public class HashMapping {
    @Autowired
    HashOperations<String, byte[], byte[]> hashOperations;

    HashMapper<Object, byte[], byte[]> mapper = new ObjectHashMapper();

    public void writeHash(String key, Person person) {
        Map<byte[], byte[]> mappedHash = mapper.toHash(person);
        hashOperations.putAll(key, mappedHash);
    }

    public Person loadHash(String key) {
        Map<byte[], byte[]> loadedHash = hashOperations.entries("key");
        return (Person) mapper.fromHash(loadedHash);
    }
}

 

 

5.8.二、Jackson2HashMapper

Jackson2HashMapper 使用FasterXML Jackson爲Redis Hash來映射domain objects。
Jackson2HashMapper 能夠映射數據映射高級properties做爲Hash字段名字,以及可選的扁平結構。簡單類型映射成簡單的值。複雜類型(嵌套的objects、集合、maps)會表現成嵌套的JSON。
扁平化 爲全部的嵌套properties建立了獨立的hash entries,將複雜類型用簡單類型表示。
public class Person {
    String firstname;
    String lastname;
    Address address;
}

public class Address {
    String city;
    String country;
}

 

Table 2. Normal Mapping
Hash Field Value

firstname

Jon

lastname

Snow

address

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

Table 3. Flat Mapping
Hash Field Value

firstname

Jon

lastname

Snow

address.city

Castle Black

address.country

The North

注意:扁平化,要求全部的property name不能與JSON path衝突。在map中使用點或者括號做爲key,或者在實體中做爲property name,都不行。若是非要這樣作,那獲得的hash是沒法被映射回對象的。

5.九、Redis 消息/發佈訂閱

 
5.9.一、發送/發佈消息
5.9.二、接收/訂閱消息

5.十、Redis事務

5.10.一、@Transactional 支持
5.十一、Pipelining  管道
5.十二、Redis 腳本

5.1三、支持類

5.13.一、對於Spring Cache抽象的支持
六、Redis Cluster
6.一、啓用Redis Cluster
6.二、Redis Cluster鏈接
6.三、使用RedisTemplate 和 ClusterOperations

七、Redis Repositories
7.一、使用
7.二、Object to Hash Mapping
7.三、Keyspaces

7.四、Secondary Indexes

7.4.一、Simple Property Index

7.4.二、Geospatial Index

7.五、Time To Live  存活時間7.六、持久化參考7.七、Persisting Partial Updates7.八、查詢和查詢方法7.九、運行在Cluster上的Redis Repositories7.十、CDI集成

相關文章
相關標籤/搜索