Redission
概述
-
简介
- Redisson是架设在Redis基础上的一个Java驻内存数据网格(In-Memory Data Grid)。
- 基于NIO(即Non-Blocking IO,非阻塞式的输入输出)的Netty框架实现数据的传输。
- Redisson的宗旨是促进使用者对Redis的关注分离(Separation of Concern),从而让使用者能够将精力更集中地放在处理业务逻辑上。
- Redis具备的功能特性及所起的作用Redisson几乎都涵盖了
- Redisson是架设在Redis基础上的一个Java驻内存数据网格(In-Memory Data Grid)。
-
功能特性
- Redisson虽然只是“客户端”,但它提供了很多“中间件”的功能:
- Redisson虽然只是“客户端”,但它提供了很多“中间件”的功能:
-
典型应用场景
-
“布隆过滤器”(Bloom Filter)
- 应用场景:“去重业务”(去重指的是判断一个元素是否在一个集合中存在。如果存在,则输出“已存在”的结果;如果不存在,则存储该元素并输出“该元素不存在”的结果。)
- 布隆过滤器是一个过滤器,用来过滤已经存在的元素,最终保证集合中的元素是唯一的,即所谓的“去重”。
- 它的作用和JDK自身提供的HashSet作用有异曲同工之妙,只不过它不需要在“判重”之前将数据列表加载至内存中。
- 主要用于“判断一个元素是否存在于大数据量的集合中”。底层逻辑:
- 第一个核心步骤,首先是“初始化”的逻辑,即需要设计并构造K个哈希函数及容量大小为N、每个元素初始取值为0的位数组
- 第二个核心步骤是“判断元素是否存在”的执行逻辑。首先是需要将当前的元素经过K个哈希函数的计算得到K个哈希值,然后判断K个哈希值(数组的下标)对应数组中的取值是否都为1。如果都为1,则代表该元素是“大概率”性存在的,否则,只要有其中一个取值不为1,则表示元素一定不存在。
- 优点在于它不需要开辟额外的内存存储元素,从而节省了存储空间
- 缺点在于判断元素是否在集合中时,有一定的误判率,并且添加进布隆过滤器的元素是无法删除的,因为位数组的下标是多个元素“共享”的,如果删除的话,很有可能出现“误删”的情况
-
消息通信
- 通过Redisson分布式对象中的一个组件“基于发布订阅模式的主题”功能实现
- “基于订阅-发布模式的主题”的数据组件核心主要由主题、生产者、消费者
- “主题”,可以理解为消息队列中的消息;
- 生产者,主要作用在于生产消息,并将消息以主题的形式进行发布;
- 消费者,主要作用在于订阅主题,并时刻监听是否有相应的主题和消息到来,如果有,则接收并执行相应的业务逻辑。
- “基于订阅-发布模式的主题”的数据组件核心主要由主题、生产者、消费者
- 使用:
- 首先需要构造“发布-订阅模式的主题”。
- 当生产者需要发布消息时,只需要将相应的消息或者数据以主题的形式进行发布
- 而消费者只需要订阅相应的主题即可实现自动监听消费主题和消息,从而执行相应的业务逻辑。
- 通过Redisson分布式对象中的一个组件“基于发布订阅模式的主题”功能实现
-
延迟队列
- Redisson的延迟队列跟RabbitMQ的死信队列几乎是“双胞胎”,拥有着几乎相同的功能特性,即生产者将消息发送至队列之后,并不会立即被消费者监听消费,而是等待一定的时间TTL,当TTL一到,消息才会被真正的队列监听消费。
- 阻塞式队列指的是进入到Redisson队列中的消息将会发生阻塞的现象,如果消息设置了过期时间TTL(也叫存活时间),那么消息将会在该阻塞队列“暂时停留”一定的时间,直到过期时间TTL一到,即代表消息该“离开”了,将前往下一个中转站,消息将进入真正的队列,等待着被消费者监听消费。
-
分布式锁
- Redisson的分布式锁可以很好地弥补基于Redis的原子操作实现的分布式锁的缺陷
- Redisson针对不同场合,设计了不同的分布式锁,主要有:
- 可重入锁(Reentrant Lock)
- 当前线程如果没有获取到对共享资源的锁,将会等待一定的时间重新获取。在过个过程中Redisson会提供一个重新获取锁的时间阈值,并在调用tryLock()方法时进行指定。
- 公平锁(Fair Lock)
- 联锁(MultiLock)
- 红锁(RedLock)
- 读写锁(ReadWriteLock)
- 信号量(Semaphore)
- 闭锁(CountDownLatch)
- 可重入锁(Reentrant Lock)
-
SpringBoot整合Redisson
- 导入依赖包
<dependency> <groupId>org.redisson</groupId> <artifactId>redisson-spring-boot-starter</artifactId> <version>3.13.1</version> </dependency>
- 在配置文件application.properties配置变量(地址一定要填正确!)
#redisson配置 redisson.host.config=redis://127.0.0.1:6379
- 加入Redisson自定义的Bean操作组件RedissonClient
//导入依赖包 import org.redisson.Redisson; import org.redisson.api.RedissonClient; import org.redisson.config.Config; 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; /** * Redisson相关开源组件自定义注入 * @Author:debug (SteadyJack) * @Date: 2019/4/27 13:34 **/ @Configuration public class RedissonConfig { //读取环境变量的实例env @Autowired private Environment env; /** * 自定义注入配置操作Redisson的客户端实例 * @return */ @Bean public RedissonClient config(){ //创建配置实例 Config config=new Config(); //可以设置传输模式为EPOLL,也可以设置为NIO等 //config.setTransportMode(TransportMode.NIO); //设置服务节点部署模式:集群模式,单一节点模式,主从模式,哨兵模式等 //config.useClusterServers().addNodeAddress(env.getProperty("redisson.host.config"),env.getProperty("redisson.host.config")); config.useSingleServer() .setAddress(env.getProperty("redisson.host.config")) .setKeepAlive(true); //创建并返回操作Redisson的客户端实例 return Redisson.create(config); } }
- 测试
/**单元测试类 * @Author:debug (SteadyJack) **/ @RunWith(SpringJUnit4ClassRunner.class) @SpringBootTest public class RedissonTest { //定义日志 private static final Logger log= LoggerFactory.getLogger(RedissonTest.class); //定义操作Redisson的客户端实例 @Autowired private RedissonClient redissonClient; //打印输出目前Redisson的配置概况 @Test public void test1() throws Exception{ log.info("redisson的配置信息:{}",redissonClient.getConfig().toJSON()); } }
Bloom Filter实战
- 业务场景“判断一个元素是否存在于一个大数据量的集合中”,测试代码:
@Test public void test() throws Exception{ //定义Redis中的Key final String key="myBloomFilterData"; //初始化构造数组容量的大小 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("该布隆过滤器是否包含数据10000:{}",bloomFilter.contains(10000)); log.info("该布隆过滤器是否包含数据100000000:{}",bloomFilter.contains(100000000)); }
分析小结
- 布隆过滤器能用于高效地判断一个元素是否存在于集合中,因此可以将布隆过滤器应用于Redis的缓存击穿问题中。
- Redisson的延迟队列需要借助“阻塞式队列”作为“中转站”,用于充当消息的第一个暂存区(相当于RabbitMQ的死信交换机)。当TTL即存活时间一到,消息将进入真正的队列被监听消费。
- RabbitMQ和Redisson的区别
- RabbitMQ的死信队列依旧保持着FIFO(First In Fist Out,即先进先出)的机制,即先进入死信队列中的消息将先被真正的队列监听消费,而全然不管不同消息携带的不同的TTL的值;
- Redisson能够弥补RabbitMQ死信队列的这个缺陷,即不管在什么时候,将消息按照TTL从小到大的顺序先后被真正的队列监听、消费。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 【.NET】调用本地 Deepseek 模型
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· 我与微信审核的“相爱相杀”看个人小程序副业
· DeepSeek “源神”启动!「GitHub 热点速览」
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库