1. 程式人生 > >SpringCloud+Redis簡介

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;

}