1. 程式人生 > >Springboot Redis詳解

Springboot Redis詳解

1. 在springboot中使用redis,只需要依賴spring-boot-starter-data-redis,然後在配置檔案中配置spring.redis開頭的一些配置,根據Redis的架構選擇單節點,主從或叢集模式,詳情如下(2.0.0.REALSE):

# 單節點模式,無密碼時置空或者不寫配置,可以使用url,也可以使用host和port
spring.redis.database=0 # Database index used by the connection factory.
spring.redis.url= # Connection URL. Overrides host, port, and password. User is ignored. Example: redis://user:[email protected]:6379
spring.redis.host=localhost # Redis server host.
spring.redis.port=6379 # Redis server port.
spring.redis.password= # Login password of the redis server.
#主從模式
spring.redis.sentinel.master= # Name of the Redis server.
spring.redis.sentinel.nodes= # Comma-separated list of "host:port" pairs.
#叢集模式
spring.redis.cluster.max-redirects= # Maximum number of redirects to follow when executing commands across the cluster.
spring.redis.cluster.nodes= # Comma-separated list of "host:port" pairs to bootstrap from.

2. springboot reids執行緒池,只要增加commons-pool2依賴,springboot自動配置。注意springboot預設選擇lettuce作為客戶端(這種方式是redis官方推薦的),如果需要使用jedis,需要在redis的starter依賴包排除lettuce,並依賴主動新增jedis依賴。執行緒池配置如下:

spring.redis.jedis.pool.max-active=8 # Maximum number of connections that can be allocated by the pool at a given time. Use a negative value for no limit.
spring.redis.jedis.pool.max-idle=8 # Maximum number of "idle" connections in the pool. Use a negative value to indicate an unlimited number of idle connections.
spring.redis.jedis.pool.max-wait=-1ms # Maximum amount of time a connection allocation should block before throwing an exception when the pool is exhausted. Use a negative value to block indefinitely.
spring.redis.jedis.pool.min-idle=0 # Target for the minimum number of idle connections to maintain in the pool. This setting only has an effect if it is positive.
spring.redis.lettuce.pool.max-active=8 # Maximum number of connections that can be allocated by the pool at a given time. Use a negative value for no limit.
spring.redis.lettuce.pool.max-idle=8 # Maximum number of "idle" connections in the pool. Use a negative value to indicate an unlimited number of idle connections.
spring.redis.lettuce.pool.max-wait=-1ms # Maximum amount of time a connection allocation should block before throwing an exception when the pool is exhausted. Use a negative value to block indefinitely.
spring.redis.lettuce.pool.min-idle=0 # Target for the minimum number of idle connections to maintain in the pool. This setting only has an effect if it is positive.
spring.redis.lettuce.shutdown-timeout=100ms # Shutdown timeout.

3. 有了以上兩步,就可以很完美的使用redis了。此時springboot預設提供了StringRedisTemplate和RedisTemplate<Object, Object>兩個物件(還有一個物件在第4步中講)。注意這兩個物件使用的是同一個redisConnectionFactory(lettuce或者jedis的),即同一個執行緒池。區別是序列化和反序列化方式不同(關於Redis序列化和反序列化,springboot預設提供了StringRedisSerializer,JdkSerializationRedisSerializer和GenericJackson2JsonRedisSerializer三種方式,超出本文範圍),前者是使用StringRedisSerializer作為redis的key,value,hashkey,hashvalue的序列化方式,後者使用JdkSerializationRedisSerializer。筆者推薦key和hashkey使用StringRedisSerializer,value和hashvalue使用GenericJackson2JsonRedisSerializer。使用方法可以模擬原始碼自己寫,原始碼參見RedisAutoConfiguration。

4. Springboot還提供了Redis的另外一種使用,即作為EnableCache的快取使用。當EnableCache開啟後,需要在專案中配置spring.cache.*的相關配置。EnableCache使用本文不講解,只講解Redis有關的部分。相關配置如下:

spring.cache.type= # Cache type. By default, auto-detected according to the environment.
spring.cache.cache-names= # Comma-separated list of cache names to create if supported by the underlying cache manager.
spring.cache.redis.cache-null-values=true # Allow caching null values.
spring.cache.redis.key-prefix= # Key prefix.
spring.cache.redis.time-to-live=0ms # Entry expiration. By default the entries never expire.
spring.cache.redis.use-key-prefix=true # Whether to use the key prefix when writing to Redis.

這個EnableCache主要用到了Spring的CacheManager物件,不同的子類即對應不同的快取策略的實現。我們先講一下ConcurrentMapCacheManager,這是一個記憶體快取方案,說直白點就是把資料用物件形式放到記憶體裡,通過名字也知道是使用ConcurrentMap儲存這些資料的,其被包裹在ConcurrentMapCache中供manager持有(有興趣可以詳細看看原始碼,可以從SimpleCacheConfiguration開始)。Springboot還有很逗的一個實現NONE,意思是快取了,但是什麼也沒做,哈哈~,可以分析原始碼NoOpCacheConfiguration。迴歸正題,Redis的實現從RedisCacheConfiguration開始,這裡springboot預設生成了RedisCacheManager物件,這個物件和第3步中的兩個物件使用相同的連線池。RedisCacheManager持有的是RedisCache物件,其自身的引數請去扒原始碼(一般用不著),只有一個defaultCongfig的引數是用來生成RedisCache物件的,defaultCongfig有6個配置(其實是7個,另外一個不太懂,也沒用過),其中4個如上面配置列表所示,列表中的配置是在生成manager的時候設定到manager中的,這樣在manager建立持有物件的時候就會被設定到持有物件RedisCache中。另外還有2個key和value的序列化方法,Springboot沒有對外暴露出來,但是我們可以自己建立manager並設定,或者通過springboot暴露的customer方法重新建立manager,其實都是建立。預設的序列化方法和RedisTemplate一樣,key是String,value是jdk,注意沒有hashkey和hashvalue,還有就是要包裹在SerializationPair中。最後講一下RedisCache操作Redis預設使用的是DefaultRedisCacheWriter,其持有RedisConnectionFactory,只有8個方法,其中5個clean,get,put,putIfAbsent,remove是基本操作,,和鎖有關的一個方法(這個這裡先不講)及繼承自介面的兩個預設方法(使用鎖和不適用鎖)。下面貼一下自己建立RedisCacheManager的簡單實現:

    @Bean
    public RedisCacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
        RedisCacheConfiguration redisCacheConfiguration =
            RedisCacheConfiguration.defaultCacheConfig().serializeValuesWith(
                RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));
        return RedisCacheManager.builder(RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory))
            .cacheDefaults(redisCacheConfiguration).build();
    }

其實主要就是對把RedisCacheConfiguration的7個變數設定成自己想要的,然後用它build出來一個manager就行啦。遺漏兩點,上面配置列表中type和names,type很簡單,要用什麼快取方法就寫什麼,注意要系統支援的,自己找文件或者扒原始碼(是一個列舉)。names是列表,一個值對應的就是manager持有的一個redisCache物件,在使用的時候可以指定使用cache物件的名字,好處就是給cache配置不同的引數,比如字首呀,過期時間等。這裡就有點尷尬啦,本來rediscache就是通過manager建立的,而manager的預設配置只有一份,也就是建立的所有cache物件都是一樣的,建立多個又想不一樣。下一節,我們講講自定義manager。

5. 模擬ConcurrentMapCacheManager和RedisCacheManager。一般我們會把redistemplate放到自定義rediscache中,這樣就很簡單啦。暫略。

6. shiro中實