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最簡單的形式的配置:
<?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.3、配置JRedis connector(自1.7起廢棄)

略。

5.3.4、配置SRP connector(自1.7起廢棄)

略。

5.3.5、配置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.4、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.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 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中即可:容器會自動執行轉換:
<?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.6、聚焦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.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。
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.2、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.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集成

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM