为什么使用redis

redis是开源的,基于内存的key-value数据库。 redis的高性能:

  1. 完全基于内存,数据存在内存汇总,类似于HashMap,其优势就是查找和操作的时间复杂度为O(1)。
  2. 数据结构简单。对数据操作也简单。
  3. 采用单线程,避免不必要的上下文切换和竞争条件,也不存在多进程或多线程导致的切换而消耗CPU,不用koala各种锁的问题。
  4. 使用多路IO复合模型,非阻塞IO。依次顺序处理就绪的流,避免大量的无用操作。
  5. redis的序列化协议,文本协议,虽然浪费流量,但解析迅速。
  6. 持久化采用子线程进行磁盘操作

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);
    }
}