目標
精通 Spring Data Redis 操作流程,
Spring Data提供了對市場上主流資料庫支持:
Spring Data Commons
Spring Data JPA
Spring Data KeyValue
Spring Data LDAP
Spring Data MongoDB
Spring Data Redis
Spring Data REST
Spring Data for Apache Cassandra
Spring Data for Apache Geode
Spring Data for Apache Solr
Spring Data for Pivotal GemFire
Spring Data Couchbase (community module)
Spring Data Elasticsearch (community module)
Spring Data Neo4j (community module)
而在使用時,難免會不動聲色的寫出一堆 bug,
1 注意讀、取一致性
當使用 Spring Data Redis 時,我們有時候會在專案升級的程序中,發現存盤后的資料有讀取不到的情況;另外,還會出現決議出錯的情況,
案例

使用了 Redis 提供的兩種 Template:
- RedisTemplate
- stringRedisTemplate
但當使用后者去存一個資料后,發現使用前者取不到對應資料:

這不很顯然嗎?是因為這倆 Template 不同呀!
發散一下思維,試想若我們是不同專案的開發,一個專案只負責存盤,另外一個專案只負責讀取,兩個專案之間缺乏溝通,如此看來,這種問題是不是就很常見了?
決議
我們不可能直接將資料存取到 Redis,畢竟一些資料是物件型別,例如 String或自定義物件,因此需要在存取前對資料進行序列化或反序列化,
帶著key去存取資料時,會執行
AbstractOperations#rawKey
在執行存盤 K.V 到 Redis或從 Redis 讀資料前,對 key 進行序列化操作:

可見,若存在 keySerializer,則利用它序列化 key,
對于 StringRedisSerializer,它指定的 StringRedisSerializer:
public class StringRedisSerializer implements RedisSerializer<String> {
private final Charset charset;
@Override
public byte[] serialize(@Nullable String string) {
return (string == null ? null : string.getBytes(charset));
}
}
若使用 RedisTemplate,則使用的JDK序列化:
public class JdkSerializationRedisSerializer implements RedisSerializer<Object> {
@Override
public byte[] serialize(@Nullable Object object) {
if (object == null) {
return SerializationUtils.EMPTY_ARRAY;
}
try {
return serializer.convert(object);
} catch (Exception ex) {
throw new SerializationException("Cannot serialize", ex);
}
}
}
所以最后對 K 的讀取處理,采用的JDK序列化:

反序列化結果的確不同,
那如何指定 RedisSerializer 的?
以 StringRedisSerializer 為例,StringRedisTemplate構造器直接指定了KeySerializer為 RedisSerializer.string():

RedisSerializer.string():


修正
一定要注意一致性,例如讀寫的序列化方法需要一致:
- 檢查自己所有的資料操作,是否使用了相同的 RedisTemplate
- 即使相同,也要檢查所指定各種Serializer是否完全一致
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/302507.html
標籤:java
上一篇:桌面寵物開發——羅小黑(一)
