redis的应用

maven配置

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>redis-demo</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <lombok.version>1.18.22</lombok.version>
        <jackson-annotations-version>2.10.1</jackson-annotations-version>
        <jackson.core.version>2.10.1</jackson.core.version>
        <jackson.databind.version>2.10.1</jackson.databind.version>
        <fastjson.version>1.2.66</fastjson.version>
    </properties>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.4</version>
        <relativePath/>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>${lombok.version}</version>
        </dependency>

        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
            <version>${jackson-annotations-version}</version>
            <scope>compile</scope>
        </dependency>

        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>${jackson.databind.version}</version>
            <exclusions>
                <exclusion>
                    <groupId>com.fasterxml.jackson.core</groupId>
                    <artifactId>jackson-annotations</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>${jackson.core.version}</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>${fastjson.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

        <dependency>
            <groupId>org.redisson</groupId>
            <artifactId>redisson-spring-boot-starter</artifactId>
            <version>3.10.6</version>
        </dependency>

        <!-- redis依赖commons-pool 这个依赖一定要添加 -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
        </dependency>

        <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-all</artifactId>
            <version>4.1.72.Final</version>
        </dependency>



    </dependencies>



</project>

application.yml

spring:
  redis:
    port: 6379
    host: 127.0.0.1
    lettuce:
      pool:
        # 连接池最大连接数(使用负值表示没有限制)
        max-active: 8
        # 连接池中的最大空闲连接
        max-idle: 8
        # 连接池中的最小空闲连接
        min-idle: 0
        # 连接池最大阻塞等待时间(使用负值表示没有限制)
        max-wait: 1000
      # 关闭超时时间
      shutdown-timeout: 100

application.properties

redisson.host.config=redis://127.0.0.1:6379

redis的配置

package com.example.config;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;

import javax.annotation.PostConstruct;

@Configuration
@Slf4j
//使用 @Cacheable, @CachePut, @CacheEvit
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {

    @Autowired
    RedisTemplate redisTemplate;


    //任务池
    private ThreadPoolTaskScheduler taskScheduler;


    /**
     * redis连接工厂
     */
    @Autowired
    RedisConnectionFactory redisConnectionFactory;


    @PostConstruct
    public void init() {
        initRedisTemplate();
    }

    public void initRedisTemplate() {
        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(
                Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        RedisSerializer stringSerializer = redisTemplate.getStringSerializer();
        redisTemplate.setKeySerializer(stringSerializer);
        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
        redisTemplate.setHashKeySerializer(stringSerializer);
        redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
        redisTemplate.afterPropertiesSet();
    }

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        return redisTemplate;
    }


    /**
     * 创建线程池,等待线程处理redis的消息
     * @return
     */
    @Bean
    public ThreadPoolTaskScheduler initTaskScheduler() {
        if(taskScheduler!=null) {
            return taskScheduler;
        }
        taskScheduler = new ThreadPoolTaskScheduler();
        taskScheduler.setPoolSize(20);
        return taskScheduler;
    }





}

redisson的配置

package com.example.config;

import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.redisson.config.TransportMode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;

/**
 * @description:
 * @author: chengjiapeng
 * @date 2023/7/6 10:46
 */
@Configuration
public class RedissonConfig {

    @Autowired
    Environment environment;

    @Bean
    public RedissonClient redissonClient() {
        Config config = new Config();
        //传输模式可以设置为epoll也可以设置为nio
        config.setTransportMode(TransportMode.NIO);
        //集群模式配置
        //config.useClusterServers().addNodeAddress(environment.getProperty("redisson.host.config"));
        //单节点模式配置
        config.useSingleServer().setAddress(environment.getProperty("redisson.host.config")).setKeepAlive(true);
        return Redisson.create(config);
    }

}

redis的工具类

@Component
public class RedisUtil {
    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 维护一个本类的静态变量
     */
    private static RedisUtil redisUtil;

    @PostConstruct
    public void init() {
        redisUtil = this;
        redisUtil.redisTemplate = this.redisTemplate;
    }

    /**
     * 将参数中的字符串值设置为键的值,不设置过期时间
     *
     * @param key
     * @param value 必须要实现 Serializable 接口
     */
    public static void set(String key, String value) {
        redisUtil.redisTemplate.opsForValue().set(key, value);
    }

    /**
     * 将参数中的字符串值设置为键的值,设置过期时间
     *
     * @param key
     * @param value   必须要实现 Serializable 接口
     * @param timeout
     */
    public static void set(String key, String value, Long timeout) {
        redisUtil.redisTemplate.opsForValue().set(key, value, timeout, TimeUnit.SECONDS);
    }

    /**
     * 获取与指定键相关的值
     *
     * @param key
     * @return
     */
    public static Object get(String key) {
        return redisUtil.redisTemplate.opsForValue().get(key);
    }

    /**
     * 设置某个键的过期时间
     *
     * @param key 键值
     * @param ttl 过期秒数
     */
    public static boolean expire(String key, Long ttl) {
        return redisUtil.redisTemplate.expire(key, ttl, TimeUnit.SECONDS);
    }

    /**
     * 判断某个键是否存在
     *
     * @param key 键值
     */
    public static boolean hasKey(String key) {
        return redisUtil.redisTemplate.hasKey(key);
    }

    /**
     * 向集合添加元素
     *
     * @param key
     * @param value
     * @return 返回值为设置成功的value数
     */
    public static Long sAdd(String key, String... value) {
        return redisUtil.redisTemplate.opsForSet().add(key, value);
    }

    /**
     * 获取集合中的某个元素
     *
     * @param key
     * @return 返回值为redis中键值为key的value的Set集合
     */
    public static Set sGetMembers(String key) {
        return redisUtil.redisTemplate.opsForSet().members(key);
    }

    /**
     * 将给定分数的指定成员添加到键中存储的排序集合中
     *
     * @param key
     * @param value
     * @param score
     * @return
     */
    public static Boolean zAdd(String key, String value, double score) {
        return redisUtil.redisTemplate.opsForZSet().add(key, value, score);
    }

    /**
     * 返回指定排序集中给定成员的分数
     *
     * @param key
     * @param value
     * @return
     */
    public static Double zScore(String key, String value) {
        return redisUtil.redisTemplate.opsForZSet().score(key, value);
    }

    /**
     * 删除指定的键
     *
     * @param key
     * @return
     */
    public static Boolean delete(String key) {
        return redisUtil.redisTemplate.delete(key);
    }

    /**
     * 删除多个键
     *
     * @param keys
     * @return
     */
    public static Long delete(Collection keys) {
        return redisUtil.redisTemplate.delete(keys);
    }
}

基于redis 实现延迟队列

使用offer 推送到延迟队列(RDelayedQueue), 延迟队列的消息到期后, 会移动至RBlockingQueue(阻塞队列中), 订阅者从阻塞队列中获取消息进行消费

@Component
@Slf4j
public class DelayQueuePublisher {

    @Autowired
    RedissonClient redissonClient;

    public void sendDelayMsg(UserLoginDTO dto, long ttl) {
        try {
            RBlockingQueue<UserLoginDTO> rBlockingQueue = redissonClient.getBlockingQueue(RedisKeyConstant.REDISSON_DELAY_QUEUE);
            RDelayedQueue<UserLoginDTO> rDelayedQueue = redissonClient.getDelayedQueue(rBlockingQueue);
            rDelayedQueue.offer(dto, ttl, TimeUnit.SECONDS);
            log.info("redisson延迟队列生产者发送消息:{}", dto);
        }catch (Exception e) {
            log.error(e.getMessage());
        }
    }
}

@Component
@EnableScheduling
@Slf4j
public class DelayQueueConsumer {

    @Autowired
    RedissonClient redissonClient;

    @Scheduled(cron = "*/1 * * * * ?")
    public void consumeMsg() throws InterruptedException {
        RBlockingQueue<UserLoginDTO> rBlockingQueue = redissonClient.getBlockingQueue(RedisKeyConstant.REDISSON_DELAY_QUEUE);
        UserLoginDTO dto = rBlockingQueue.take();
        if(dto!=null) {
            log.info("redisson 延迟队列-消息者-收到消息:{}", dto);
        }
    }


}

测试

@RunWith(SpringRunner.class)
@SpringBootTest(classes = App.class)
@Slf4j
public class Test1 {

    @Autowired
    DelayQueuePublisher delayQueuePublisher;

    @Test
    public void test1() {
        RedisUtil.set("testKey1", "testValue");
        System.out.println(RedisUtil.get("testKey1"));
    }

    @Test
    public void test2() throws InterruptedException {
        UserLoginDTO dto = new UserLoginDTO();
        dto.setUserName("zhangsan");
        delayQueuePublisher.sendDelayMsg(dto, 2);
        Thread.sleep(4000);
    }
}

redis 各种数据结构的使用

 string:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = App.class)
@Slf4j
public class StringTest {

    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    StringRedisTemplate stringRedisTemplate;

    @Autowired
    ObjectMapper objectMapper;

    /**
     * 使用redisTemplate 操作字符串
     */
    @Test
    public void test1() {
        String key = "redis:template:one:string";
        String context = "redisTemplate实战字符串实战";
        ValueOperations valueOperations = redisTemplate.opsForValue();
        valueOperations.set(key, context);
        Object result = valueOperations.get(key);
        log.info("读出来的内容:{}", result);
    }

    /**
     * 使用redisTemplate 操作对象
     */
    @Test
    public void test2() throws IOException {
        User user = new User(1, "debug", "阿修罗");
        ValueOperations valueOperations = redisTemplate.opsForValue();
        final String key = "redis:template:two:object";
        final String content = objectMapper.writeValueAsString(user);
        valueOperations.set(key, content);
        Object result = valueOperations.get(key);
        if(result!=null) {
            User resultUser = objectMapper.readValue(result.toString(), User.class);
            log.info("读取缓存并反序列化:{}", resultUser);
        }
    }

    /**
     * 使用stringRedisTemplate 操作字符串
     */
    @Test
    public void test3() {
        final String key = "redis:three";
        final String content = "StringRedisTemplate实战字符串信息";
        ValueOperations valueOperations = stringRedisTemplate.opsForValue();
        valueOperations.set(key, content);
        Object result = valueOperations.get(key);
        log.info("读取出来的内容:{}", result);
    }

    /**
     * 使用stringRedisTemplate 操作对象
     */
    @Test
    public void test4() throws IOException {
        final String key = "redis:four";
        User user = new User(2, "SteadyJack", "阿修罗");
        final String content = objectMapper.writeValueAsString(user);
        ValueOperations valueOperations = stringRedisTemplate.opsForValue();
        valueOperations.set(key, content);
        Object result = valueOperations.get(key);
        if(result!=null) {
            User resultUser = objectMapper.readValue(result.toString(), User.class);
            log.info("读取缓存并反序列化:{}", resultUser);
        }
    }



}

list:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = App.class)
@Slf4j
public class ListTest {

    @Autowired
    RedisTemplate redisTemplate;

    /**
     * 操作列表
     */
    @Test
    public void test1() {
        List<User> list = Arrays.asList(
                new User(1, "debug", "修罗"),
                new User(2, "jack", "大圣"),
                new User(3, "lee", "盘古")
        );
        final String key = "redis:test:2";
        redisTemplate.delete(key);
        ListOperations listOperations = redisTemplate.opsForList();
        for(User u:list) {
            //从队列尾部添加
            //1,2,3
            listOperations.leftPush(key, u);
        }
        Object res = listOperations.rightPop(key);
        User user;
        while (res!=null) {
            user = (User) res;
            log.info("当前数据:{}", user);
            //1, 2, 3
            res = listOperations.rightPop(key);
        }
    }

}

set:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = App.class)
@Slf4j
public class SetTest {

    @Autowired
    RedisTemplate redisTemplate;

    /**
     * 集合-无序,不重复
     */
    @Test
    public void test1() {
        List<String> list = Arrays.asList("debug", "jack", "lee", "debug");
        final String key = "redis:test:3";
        redisTemplate.delete(key);
        SetOperations setOperations = redisTemplate.opsForSet();
        for(String str:list) {
            setOperations.add(key, str);
        }
        Object res = setOperations.pop(key);
        while (res!=null) {
            log.info("从缓存中获取的用户集合-当前用户:{}", res);
            res = setOperations.pop(key);
        }
    }

}

zset:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = App.class)
@Slf4j
public class ZSetTest {

    @Autowired
    RedisTemplate redisTemplate;

    /**
     * ZSet 有序集合
     */
    @Test
    public void test1() {
        List<PhoneUser> list = Arrays.asList(
                new PhoneUser("103", 130.0),
                new PhoneUser("101", 120.0),
                new PhoneUser("102", 80.0)
        );
        final String key = "redis:test:4";
        redisTemplate.delete(key);
        ZSetOperations zSetOperations = redisTemplate.opsForZSet();
        for(PhoneUser phoneUser:list) {
            zSetOperations.add(key, phoneUser, phoneUser.getFare());
        }
        Long size = zSetOperations.size(key);
        //从小到大
        //Set<PhoneUser> set = zSetOperations.range(key, 0L, size);
        //从大到小
        Set<PhoneUser> set = zSetOperations.reverseRange(key, 0L, size);
        for(PhoneUser u:set) {
            log.info("当前记录:{}", u);
        }
    }


}

hash:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = App.class)
@Slf4j
public class HashTest {

    @Autowired
    RedisTemplate redisTemplate;

    /**
     * Hash
     */
    @Test
    public void test1() {
        List<Student> students = Arrays.asList(
                new Student("10010", "debug", "大圣"),
                new Student("10011", "jack", "修罗"),
                new Student("10012", "sam", "上古")
        );
        String key = "redis:test:5";
        redisTemplate.delete(key);
        HashOperations hashOperations = redisTemplate.opsForHash();
        for(Student student:students) {
            hashOperations.put(key, student.getId(), student);
        }
        Map<String, Student> sMap = hashOperations.entries(key);
        for(String id:sMap.keySet()) {
            log.info("id:{}, student:{}", id, sMap.get(id));
        }
        String id = "10012";
        Student student = (Student) hashOperations.get(key, id);
        log.info("指定学生:{}", student);
    }
}

布隆过滤器的使用:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = ServerProvider.class)
@Slf4j
public class RedissonBloomTest {

    @Autowired
    RedissonClient redissonClient;

    @Test
    public void test1() throws IOException {
        System.out.println(redissonClient.getConfig().toJSON());
    }

    /**
     * 布隆过滤器-校验基本类型是否存在
     */
    @Test
    public void test2() {
        final String key = "myBloomFilterDataV2";
        Long total = 100000L;
        //创建布隆过滤器组件
        RBloomFilter<Integer> bloomFilter = redissonClient.getBloomFilter(key);
        //初始化布隆过滤器, 预计统计元素数量为100000, 期望误差为0.01
        bloomFilter.tryInit(total, 0.01);
        for(int i=1;i<total;i++) {
            bloomFilter.add(i);
        }
        log.info("该布隆过滤器是否包含数据1:{}"+bloomFilter.contains(1));
        log.info("该布隆过滤器是否包含数据-1:{}"+bloomFilter.contains(-1));
        log.info("该布隆过滤器是否包含数据1000:{}"+bloomFilter.contains(1000));
    }

    /**
     * 布隆过滤器-校验对象是否存在
     */
    @Test
    public void test3() {
        final String key = "myBloomFilterDataV3";
        Long total = 1000L;
        //创建布隆过滤器组件
        RBloomFilter<BloomDTO> bloomFilter = redissonClient.getBloomFilter(key);
        //初始化布隆过滤器, 预计统计元素数量为1000, 期望误差为0.01
        bloomFilter.tryInit(total, 0.01);

        BloomDTO dto1 = new BloomDTO(1, "1");
        BloomDTO dto2 = new BloomDTO(10, "10");
        BloomDTO dto3 = new BloomDTO(100, "100");
        bloomFilter.add(dto1);
        bloomFilter.add(dto2);
        bloomFilter.add(dto3);

        log.info("该布隆过滤器是否包含数据1:{}"+bloomFilter.contains(new BloomDTO(1, "1")));
        log.info("该布隆过滤器是否包含数据10:{}"+bloomFilter.contains(new  BloomDTO(10, "10")));
        log.info("该布隆过滤器是否包含数据1000:{}"+bloomFilter.contains(new  BloomDTO(1000, "1000")));

    }



}

  • 7
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值