SpringCloud+Redis簡介
Redis 簡介
REmote DIctionary Server\(Redis\) 是一個由Salvatore Sanfilippo寫的key-value儲存系統。Redis是一個開源的
使用ANSI C語言編寫、遵守BSD協議、支援網路、可基於記憶體亦可持久化的日誌型、Key-Value資料庫,並提供多種語言的API。它通
常被稱為資料結構伺服器,因為值(value)可以是 字串(String), 雜湊(Map), 列表(list), 集合(sets) 和 有序集合
(sorted sets)等型別。
Redis 優勢
效能極高 – Redis能讀的速度是110000次/s,寫的速度是81000次/s 。
豐富的資料型別 – Redis支援二進位制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 資料型別操作。
原子 – Redis的所有操作都是原子性的,意思就是要麼成功執行要麼失敗完全不執行。單個操作是原子性的。多個操作也支援事務,即原子性,
通過MULTI和EXEC指令包起來。豐富的特性 – Redis還支援 publish/subscribe, 通知, key 過期等等特性。
採用了spring-data-redis(以下簡稱SDR)中的Template進行redis的操作。
因為考慮到後期的使用場景,於是同時採用了StringRedisTemplate和RedisTemplate,
並且對儲存String與儲存Java物件採用不同的Template進行了簡單的封裝。
首先是測試 儲存與取出方法。分別用不同的template可以完美通過。
然後在測試刪除的方法中,測試出現了問題。
問題如下:
在採用StringRedisTemplate進行儲存的資料,用StringRedisTemplate去刪除可以成功刪除。
在採用RedisTemplate進行儲存的資料,用RedisTemplate去刪除也可以刪除成功。
在用RedisTemplate去刪除StringRedisTemplate儲存的資料時,發現刪除失敗。
在用StringRedisTemplate去刪除RedisTemplate儲存的資料時,刪除失敗。
因為,需要封裝一套通用的刪除方法,並且需要封裝一個批量刪除的方法。所以研究了下問題出現的原因。
經過檢視SDR官方給出的文件,發現是因為序列化策略的問題。
這裡簡單說下:
SDR預設採用的序列化策略有兩種,一種是String的序列化策略,一種是JDK的序列化策略。
StringRedisTemplate預設採用的是String的序列化策略,儲存的key和value都是採用此策略序列化儲存的。StringRedisSerializer
RedisTemplate預設採用的是JDK的序列化策略,儲存的key和value都是採用此策略序列化儲存的。JdkSerializationRedisSerializer
就是因為序列化策略的不同,即使是同一個key用不同的Template去序列化,結果是不同的。所以根據key去刪除資料的時候就出現了刪除失敗的問題。
RedisTemplate中定義了對5種資料結構操作
redisTemplate.opsForValue();//操作字串
redisTemplate.opsForHash();//操作hash
redisTemplate.opsForList();//操作list
redisTemplate.opsForSet();//操作set
redisTemplate.opsForZSet();//操作有序set
Redis的String資料結構 (推薦使用StringRedisTemplate)
RedisSerializer<String> stringSerializer = new StringRedisSerializer();
template.setKeySerializer(stringSerializer );
template.setValueSerializer(stringSerializer );
template.setHashKeySerializer(stringSerializer );
template.setHashValueSerializer(stringSerializer );
那就先整合試一試咯,前提是你本地安裝了redis
Maven
<!--redis整合-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
配置檔案
application.properties
spring.redis.database=1
spring.redis.host=127.0.0.1
spring.redis.port=6379
spring.redis.password=123456
spring.redis.pool.max-idle=8
spring.redis.pool.min-idle=0
spring.redis.pool.max-active=8
spring.redis.pool.max-wait=-1
spring.redis.timeout=5000
Java程式碼
/**
* redis
* Created by gaomin on 2017/12/26.
*/
@Configuration
@EnableCaching
public class RedisCacheConfig {
@Value("${spring.redis.host}")
private String redisHost;
@Value("${spring.redis.port}")
private int redisPort;
@Value("${spring.redis.password}")
private String password;
@Bean
public RedisConnectionFactory redisCF(){
JedisConnectionFactory jcf=new JedisConnectionFactory();
jcf.setHostName(redisHost);
jcf.setPort(redisPort);
jcf.setPassword(password);
jcf.afterPropertiesSet();
jcf.setUsePool(true);
return jcf;
}
@Bean
public RedisTemplate redisTemplate(){
final RedisTemplate< String, Object > template = new RedisTemplate< String, Object >();
template.setKeySerializer(new StringRedisSerializer());//指定key的序列化
//template.setValueSerializer(new )
template.setConnectionFactory( redisCF() );
return template;
}
@Bean
public CacheManager cacheManager(){
return new RedisCacheManager(redisTemplate());
}
}
使用
@Override
public Object getDataByRedis() {
String key = RedisStaticUtil.MENUEXAMPLE_LIST;
List<Menu> menuList= (List<Menu>) redisTemplate.opsForValue().get(key);
if(menuList==null){
MenuExample menuExample = new MenuExample();
MenuExample.Criteria menuExampleCriteria = menuExample.createCriteria();
menuExampleCriteria.andStateEqualTo(0);
menuList = menuDao.selectByExample(menuExample);
redisTemplate.opsForValue().set(key,menuList);
}
return menuList;
}