为什么使用redis
redis是开源的,基于内存的key-value数据库。 redis的高性能:
- 完全基于内存,数据存在内存汇总,类似于HashMap,其优势就是查找和操作的时间复杂度为O(1)。
- 数据结构简单。对数据操作也简单。
- 采用单线程,避免不必要的上下文切换和竞争条件,也不存在多进程或多线程导致的切换而消耗CPU,不用koala各种锁的问题。
- 使用多路IO复合模型,非阻塞IO。依次顺序处理就绪的流,避免大量的无用操作。
- redis的序列化协议,文本协议,虽然浪费流量,但解析迅速。
- 持久化采用子线程进行磁盘操作
redis的数据结构:
- SDS(简单动态字符串):预先分配空间,使用len表示目前字符串长度,free表示剩下可用空间。这样,字符串的每次扩展则不一定要再分配新的空间。当字符串长度缩短时,不会立即通过内存分配来回收多余的字节。
- List:双向链表,插入查询效率高,但是查询效率为O(n)。
- hash:
- set:存储不同的数据。
- zset:有序集合,根据分数排序,既可以根据成员访问元素,也可根据分值及分值的排列顺序访问元素。底层是跳表+字典。
redis在springboot的使用
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
引入依赖后,就可以在springboot项目中增加自己的redisUtils工具类,在工具类中,我们可以定义常用的函数:
@Component
public class RedisUtils {
private static RedisTemplate<String, String> redisTemplate;
@Autowired
public void setRedisTemplate(RedisTemplate<String, String> redisTemplate){
RedisUtils.redisTemplate = redisTemplate;
}
/**
* 根据前缀跟key获取redisKey
* @param key
* @param prefixEnum
* @return
*/
public static String getRedisKeyByPrefix(String key, RedisPrefixEnum prefixEnum){
if(null == key || key.length() == 0){
throw new AppTransException(ErrorEnum.DATA_ERROR);
}
return prefixEnum.getPrefix() + key;
}
public static <T> T getValueByKey(String key, RedisPrefixEnum prefixEnum, Class<T> clazz){
String redisKey = getRedisKeyByPrefix(key, prefixEnum);
return getValueByKey(redisKey, clazz);
}
/**
* 根据key跟prefix删除redis缓存,返回删除缓存的数量
* @param key
* @param prefixEnum
* @return
*/
public static int delByKey(String key, RedisPrefixEnum prefixEnum){
String redisKey = getRedisKeyByPrefix(key, prefixEnum);
return delByKey(redisKey);
}
/**
* 根据key获取redis缓存值
* @param key redis key
* @param clazz
* @return
* @param <T> 要返回的类型
*/
private static <T> T getValueByKey(String key, Class<T> clazz){
String value = redisTemplate.opsForValue().get(key);
if(value == null){
return null;
}
return json2Bean(value, clazz);
}
private static void setValueExpired(String key, Object object, Long expiredTime){
if(key == null){
return;
}
redisTemplate.opsForValue().set(key, bean2Json(object), expiredTime, TimeUnit.SECONDS);
}
/**
* bean转json的通用方法,用于redis
* @param object
* @return
*/
private static String bean2Json(Object object){
return JSONObject.toJSONString(object);
}
/**
* bean转json的通用方法,用于redis
* @param json
* @param clazz
* @return
* @param <T>
*/
private static <T> T json2Bean(String json, Class<T> clazz){
return JSONObject.parseObject(json, clazz);
}
}