1. 程式人生 > >spring-data-redis 使用過程中踩過的坑

spring-data-redis 使用過程中踩過的坑

spring-data-redis簡介

Spring-data-redis是spring大家族的一部分,提供了在srping應用中通過簡單的配置訪問redis服務,對reids底層開發包(Jedis, JRedis, and RJC)進行了高度封裝,RedisTemplate提供了redis各種操作、異常處理及序列化,支援釋出訂閱,並對spring 3.1 cache進行了實現。

spring-data-redis針對jedis提供瞭如下功能:

  • 連線池自動管理,提供了一個高度封裝的“RedisTemplate”類
  • 針對jedis客戶端中大量api進行了歸類封裝,將同一型別操作封裝為operation介面
  • ValueOperations:簡單K-V操作
  • SetOperations:set型別資料操作
  • ZSetOperations:zset型別資料操作
  • HashOperations:針對map型別的資料操作
  • ListOperations:針對list型別的資料操作

踩坑1:序列化問題

SDR預設採用的序列化策略有兩種,一種是String的序列化策略,一種是JDK的序列化策略。

StringRedisTemplate預設採用的是String的序列化策略,儲存的key和value都是採用此策略序列化儲存的。

RedisTemplate預設採用的是JDK的序列化策略,儲存的key和value都是採用此策略序列化儲存的。

就是因為序列化策略的不同,即使是同一個key用不同的Template去序列化,結果是不同的。所以根據key去操作資料的時候就出現了操作失敗的問題。

    <bean id="stringRedisSerializer"  class="org.springframework.data.redis.serializer.StringRedisSerializer" />
    <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
        <property name="connectionFactory" ref="connectionFactory" /> 
        <property name="keySerializer" ref="stringRedisSerializer" />
        <property name="hashKeySerializer" ref="stringRedisSerializer" />
        <property name="valueSerializer" ref="stringRedisSerializer"/>
    </bean>

建議:
redis 序列化策略 ,建議採用String序列化策略

踩坑2:設定一個鍵值及其過期時間

錯誤的設定方式:

    /**
     * Overwrite parts of {@code key} starting at the specified {@code offset} with given {@code value}.
     *
     * @param key must not be {@literal null}.
     * @param value
     * @param offset
     * @see <a href="http://redis.io/commands/setrange">Redis Documentation: SETRANGE</a>
     */
    void set(K key, V value, long offset);

正確的設定方式:


    /**
     * Set the {@code value} and expiration {@code timeout} for {@code key}.
     *
     * @param key must not be {@literal null}.
     * @param value
     * @param timeout
     * @param unit must not be {@literal null}.
     * @see <a href="http://redis.io/commands/setex">Redis Documentation: SETEX</a>
     */
    void set(K key, V value, long timeout, TimeUnit unit);

踩坑3:模糊刪除

錯誤的方式1:

    Set<String> keys=redisTemplate.keys(prex+"*");

        for test    
         Iterator<String> it=keys.iterator();
           while(it.hasNext()){
            redisTemplate.delete((String)it.next());
        }

錯誤的方式2:

Set<String> keys=redisTemplate.keys(prex+"*");
 redisTemplate.delete(keys);

在鍵值較多的時候,keys查詢會block住。

建議
在鍵值較多的時候,通常指百萬以上級別,可以使用scan命令進行分頁刪