本文是從爲知筆記上覆制過來的,懶得調整格式了,爲知筆記版本是帶格式的,內容也比這裏全。點這裏
爲知筆記版本
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.三、嘗試案例
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 -- 取決於使用狀況:
- 使用HashOperations和一個序列化器,直接映射。
- 使用Redis Repositories。
- 使用HashMapper和HashOperations。
5.8.一、Hash mappers 哈希映射器
Hash mappers是將objects與Map<K, V>互相轉換的轉換器。HashMapper用於Redis Hashes。
- BeanUtilsHashMapper,使用Spring的BeanUtils。
- ObjectHashMapper,使用Object to Hash Mapping。
- 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.十、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集成