redis

简介

Redis是目前使用最光啊发你的内存数据库存储系统之一,它支持很丰富的数据结构,数据持久化,事务,HA(高可用),双机集群系统,主从库。

Redis是Key-Value存储系统,它支持的value类型包括String、List、Set、Zset(有序集合)和Hash。这些数据类型都支持push,pop,add,remove,取交集,并集,差集等,这些操作都是原子性的,此外,Redis还支持一些排序和算法。

同时,redis会周期性的将更新后的数据写入磁盘,或者把修改操作写入追加的记录文件中(AOF和RDB两种方式),并且在此基础上实现了主从同步,就算机器重启后,也能通过持久化数据自动重建内存,使用Redis作为Cache,那么机器宕机之后热点数据也不会丢失。

可能存在的问题

  • 缓存和数据库的双写一致性
  • 缓存雪崩问题
  • 缓存击穿问题
  • 缓存的并发竞争问题

优点

  • 纯内存操作
  • 单线程操作,避免了频繁的上下文切换
  • 采用了非阻塞I/O多路复用机制

Redis中的数据结构

String

字符串,可以存放任意类型的数据,字符,整数,浮点数等。

一个字符串类型的值的容量有512MB,代表能存储最大512MB的内容。

List

列表,列表是Redis简单的字符串列表,按照插入顺序排序,可以通过LPUSHRPUSH命令添加一个元素到列表的头部或者尾部。

Set

和数据结构一样,在Redis中这是一个无序的,不允许相同的字符串合集。支持集合运算,如并集,交集,差集等。

Hash

散列,在redis中hash是字符串字段和字符串值之间的映射,主要用来表示对象,也能够用来表示对象,也能够存储许多元素。

Zset

有序集合,和之前的Set类似,是不包含相同字符串的合集,每个有序集合的成员都有关联着一个评分,这个评分用于把有序集合中的成员按最低分到最高分排序(如排行榜场景 TOP N)。

使用有序集合,可以非常方便的添加,删除和更新元素,元素是在插入时就做好排序处理的,所以可以很快地通过评分或者位次获得一个范围的元素。

SpringBoot中RedisTemplate

opsFor

在Spring中官方为我们封装了RedisTemplateStringRedisTemplate来对Redis进行操作。它们支持所有的原生Redis操作,在RedisTemplate中定义了5种对数据结构操作的方法。

  • opsForValue :操作字符串
  • opsForHash:操作散列
  • opsForList:操作列表
  • opsForSet:操作集合
  • opsForZSet:操作有序集合

我们通过这个opsFor()方法后可以对后面的操作进行链式调用,比如可以opsForValue().set(...)

Scan

RedisTemplate中操作有序集合,我们可以对其进行遍历操作,需要用到scan,就如下放所写

String [] strs = new String[]{"str1","str2"};
redisTemplate.opsForSet().add("set1",strs);
Cursor<String> cursor = redisTemplate.opsForSet().scan("set1", ScanOptions.NONE);
while (cursor.hasNext()) System.out.println(cursor.next());

我们可以理解为操作一个指针,对Set集合进行遍历操作。

ZSet

我们在RedisTemplate中操作有序集合时,需要设置值的score

ZSetOperations.TypedTuple<String> objectTypedTuple1 = new DefaultTypedTuple<>("zset5",9.6);

一如这般,之后我们使用Set集合来存放我们所有的值,再使用模板类中的add方法进行存入

 @Test
    void ZsetTest(){
        //redisTemplate.opsForZSet().removeRange("zsetTest",0,-1);
        ZSetOperations.TypedTuple<String> objectTypedTuple1 = new DefaultTypedTuple<>("zset5",9.6);
        ZSetOperations.TypedTuple<String> objectTypedTuple2 = new DefaultTypedTuple<>("zset2",9.9);
        ZSetOperations.TypedTuple<String> objectTypedTuple3 = new DefaultTypedTuple<>("zset3",10.5);
        ZSetOperations.TypedTuple<String> objectTypedTuple4 = new DefaultTypedTuple<>("zset1",99.0);
        Set<ZSetOperations.TypedTuple<String>> tuples = new HashSet<>();
        tuples.add(objectTypedTuple1);
        tuples.add(objectTypedTuple2);
        tuples.add(objectTypedTuple3);
        tuples.add(objectTypedTuple4);
        System.out.println(redisTemplate.opsForZSet().add("zsetTest",tuples));
        System.out.println(redisTemplate.opsForZSet().range("zsetTest",0,-1));
    }

我们可以看到控制台输出的结果

4
[zset5, zset2, zset3, zset1]

还有一种添加方法

@Test
    void ZsetAdd(){
        redisTemplate.opsForZSet().add("zsetTestAdd","zset1",55.0);
        redisTemplate.opsForZSet().add("zsetTestAdd","zset2",1.0);
        System.out.println(redisTemplate.opsForZSet().range("zsetTestAdd",0,-1));
        System.out.println(redisTemplate.opsForZSet().removeRange("zsetTestAdd",0,-1));
    }

RedisTemplate和StringRedisTemplate

两者的数据是不互通的,StringRedisTemplate只能管理StringRedisTemplate中的数据,同理亦然。

StringRedisTemplate默认采用的是String的序列化策略,RedisTemplate默认采用的是JDK的序列化策略。

SpringBoot配置Redis

配置Redis配置类(Config)

创建RedisConfig配置类

/**
 * @作者: Seale
 * @时间: 2020/09/07 14:55
 * @说明: Redis 配置类
 * @类名: RedisConfig
 */
@Configuration
public class RedisConfig extends CachingConfigurerSupport {
    //在缓存对象集合中,缓存是以键值对的形式保存的
    //如果没有指定缓存的 key ,则Spring Boot会使用SimpleKeyGenerator生成key
    @Bean
    public  KeyGenerator keyGenerator(){
        return (o, method, objects) -> {
            //自定义缓存数据Key生成策略
            StringBuilder sb = new StringBuilder("imsle-");
            sb.append(o.getClass().getName())
                    .append("-")
                    .append(method.getName());
            for (Object obj : objects){
                sb.append(obj.toString());
            }
            return sb.toString();
        };
    }
    @Bean
    public CacheManager cacheManager(RedisConnectionFactory factory){
        return RedisCacheManager.create(factory);
    }
    @Bean
    public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory factory){
        RedisTemplate<String,Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(factory);
        return redisTemplate;
    }
    @Bean
    public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory factory){
        StringRedisTemplate stringRedisTemplate = new StringRedisTemplate();
        stringRedisTemplate.setConnectionFactory(factory);
        return stringRedisTemplate;
    }
}

那么之后就可以用Spring Boot提供的注解式缓存来进行缓存管理了。


本作品采用知识共享署名 4.0 国际许可协议进行许可。

如果可以的话,请给我钱请给我点赞赏,小小心意即可!

Last modification:September 7, 2020
If you think my article is useful to you, please feel free to appreciate