从0开始回顾Redis---系列十

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: 布隆过滤器1、讲一讲布隆过滤器?布隆过滤器,它是一个连续的数据结构,每个存储位存储都是一个bit,即0或者1, 可以用来快速判断某个数据是否存在。 标记某个数据时: 我们使用K个不同的哈希函数将这个数据映射为bit数组上的K个点,并把它们置为1。查询某个数据时:先使用K个哈希函数得到这个数据在bit数组中对应的k个位置 ,然后判断bit值是不是1:● 只要有一个不是1,就说明布隆过滤器没有对该数据做过标,即该数据不存在 ;● 如果都是1,也只是表示数据可能存在。优点:1. 布隆过滤器的查询速度很快,一般只需要几毫秒;2. 布隆过滤器只需要很少的空间,因为它只是一个位数组。

布隆过滤器

1、讲一讲布隆过滤器?

布隆过滤器,它是一个连续的数据结构,每个存储位存储都是一个bit,即0或者1, 可以用来快速判断某个数据是否存在。

标记某个数据时: 我们使用K个不同的哈希函数将这个数据映射为bit数组上的K个点,并把它们置为1。

查询某个数据时先使用K个哈希函数得到这个数据在bit数组中对应的k个位置 ,然后判断bit值是不是1:

  • 只要有一个不是1,就说明布隆过滤器没有对该数据做过标,即该数据不存在
  • 如果都是1,也只是表示数据可能存在。

优点

  1. 布隆过滤器的查询速度很快,一般只需要几毫秒;
  2. 布隆过滤器只需要很少的空间,因为它只是一个位数组。

缺点

  1. 它在判断元素是否在集合中时是有一定错误机率,因为哈希算法有一定的碰撞的概率。
  2. 不支持删除元素。

2、布隆过滤器的误判率如何解决优化?

布隆过滤器的误判率可以通过调整布隆过滤器的参数来优化:

主要有两个参数:

  1. 位数组的大小:越大,误判率就越小。但是,位数组越大,所需的空间就越大。
  2. 哈希函数的个数:越多,误判率就越小。但是,哈希函数越多,查询时间就越长。

优化

  1. 一般来说,当位数组的大小和哈希函数的个数同时增大时,布隆过滤器的误判率会越来越小。但是,要注意的是,当位数组的大小或哈希函数的个数超过某个值时,布隆过滤器的性能可能不再提升,甚至可能下降。
  2. 此外,还可以通过使用更高效的哈希函数来优化布隆过滤器的性能。一般来说,使用高质量的哈希函数能够提高布隆过滤器的性能,减小误判率。
  3. 另外,还可以通过使用多个布隆过滤器,并将它们组合起来使用,来进一步优化布隆过滤器的性能。例如,可以使用多个布隆过滤器,并将它们的结果用位或运算结合起来,从而降低误判率。

应用

1、Redis如何实现去重?

  1. 使用set类型:Redis中的set类型是一个无序的集合,它可以用于存储不重复的元素。使用set类型可以方便地实现去重,每次添加元素时会自动去重,如果元素已经存在于set中,则不会重复添加。set类型的优点是快速且内存占用较小,但不支持元素的顺序操作。
  2. 使用sorted set类型:Redis中的sorted set类型是一个有序的集合,它可以用于存储不重复的元素,并且支持按照分数进行排序。使用sorted set类型可以实现去重,并且可以按照指定的分数对元素进行排序。sorted set类型的优点是支持按照分数进行排序,并且可以使用zrange和zrevrange等命令获取有序集合中的元素,但相比set类型内存占用更大。
  3. 使用bitmap类型:Redis中的bitmap类型是一个位图,可以用于存储一组二进制位。使用bitmap类型可以实现去重,每个元素对应bitmap中的一位,如果该位为1,则表示该元素已经存在。bitmap类型的优点是内存占用较小,但相比set类型和sorted set类型只支持二进制位的操作。
  4. 使用HyperLogLog类型:Redis中的HyperLogLog类型是一种基数算法,可以用于估计一个集合中不重复元素的数量。使用HyperLogLog类型可以实现去重,但是无法获取具体的元素,只能获取去重后的元素数量。HyperLogLog类型的优点是内存占用非常小,但估计的元素数量可能会存在误差。

2、Redis如何实现分布式锁?

2.1 基于单个节点

加锁

在基于单个Redis实例实现分布式锁时,对于加锁操作,我们需要满足四个条件:

  1. 加锁包括了读取锁变量、检查锁变量值和设置锁变量值三个操作,但需要以原子操作的方式完成,所以,我们使用SET命令带上NX选项来实现加锁
  2. 锁变量需要设置过期时间,以免客户端拿到锁后发生异常,导致锁一直无法释放,所以,我们在SET命令执行时加上EX/PX选项,设置其过期时间;
  3. 锁变量的值需要能区分来自不同客户端的加锁操作,以免在释放锁时,出现误释放操作,所以,我们使用SET命令设置锁变量值时,每个客户端设置的值是一个唯一值,用于标识客户端。
  4. 为了实现可重入,为每个锁关联一个请求计数器和一个占有它的线程。
  • 当计数为0时,认为锁是未被占有的;
  • 线程请求一个未被占有的锁时,JVM将记录锁的占有者,并且将请求计数器置为1 。

解锁

和加锁类似,释放锁也包含了读取锁变量值、判断锁变量值和删除锁变量三个操作,不过,我们无法使用单个命令来实现,所以,我们可以采用Lua脚本执行释放锁操作,通过Redis原子性地执行Lua脚本,来保证释放锁操作的原子性。

2.2 基于多个节点

为了避免Redis实例故障而导致的锁无法工作的问题,可以使用分布式锁算法Redlock

Redlock算法的基本思路

  • 让客户端和多个独立的Redis实例依次请求加锁,如果客户端能够和半数以上的实例成功地完成加锁操作,那么我们就认为,客户端成功地获得分布式锁了,否则加锁失败。
  • 这样一来, 即使有单个Redis实例发生故障,因为锁变量在其它实例上也有保存,所以,客户端仍然可以正常地进行锁操作,锁变量并不会丢失。

加锁

Redlock算法的实现需要有N个独立的Redis实例,可以分成3步来完成加锁操作:

  • 第一步是,客户端获取当前时间。
  • 第二步是,客户端按顺序依次向N个Redis实例执行加锁操作。
  • 第三步是,一旦客户端完成了和所有Redis实例的加锁操作,客户端就要计算整个加锁过程的总耗时。

客户端只有在满足下面的这两个条件时,才能认为是加锁成功。

  • 条件一:客户端从超过半数(大于等于 N/2+1)的Redis实例上成功获取到了锁;
  • 条件二:客户端获取锁的总耗时没有超过锁的有效时间。

如果客户端在和所有实例执行完加锁操作后,没能同时满足这两个条件,那么,客户端向所有Redis 节点发起释放锁的操作。

释放锁

在Redlock算法中,释放锁的操作和在单实例上释放锁的操作一样,只要执行释放锁的Lua脚本就可以了。

这样一来,只要N个Redis实例中的半数以上实例能正常工作,就能保证分布式锁的正常工作了

3、Redis如何实现消息队列?

  1. 使用list类型:Redis中的list类型可以用于实现队列,每个元素都可以看作是一个消息。使用lpush和rpop等命令可以将消息添加到队列中,并从队列中取出消息。如果需要支持多个消费者,可以使用blpop和brpop等命令,这些命令会在队列中有新的消息时阻塞,直到有消息可以取出为止。使用list类型可以实现简单的消息队列,但不支持消息的优先级和持久化等高级功能。
  2. 使用Redis Streams:Redis 5.0及以上版本提供了Streams类型,可以用于实现更为高级的消息队列。Streams可以存储多个消息,每个消息都有一个唯一的ID和一个内容。使用XADD命令可以向Streams中添加消息,使用XREAD命令可以从Streams中读取消息。Streams还支持多个消费者,每个消费者可以读取不同的消息,并且可以设置消息的最大长度、过期时间等高级属性。使用Redis Streams可以实现更为复杂的消息队列,支持消息的优先级、持久化和高可用等高级功能。
相关文章
|
easyexcel 数据库
公司大佬对excel导入、导出的封装,那叫一个秒啊
封装公司统一使用的组件的主要目标是为了简化开发人员的调用流程,避免各个项目组重复集成和编写不规范的代码。文中提到对阿里EasyExcel进行了二次封装,提供了导入和导出功能,并支持模板的导入和导出。此外,还处理了读取数据与实际保存数据不一致的情况,通过提供自定义转换器来解决。
493 0
|
消息中间件 存储 Kafka
KafKa C++实战
KafKa C++实战
808 0
|
easyexcel Java API
自从用了 EasyExcel,导入导出 Excel 更简单了!
自从用了 EasyExcel,导入导出 Excel 更简单了!
789 0
|
移动开发 网络协议 物联网
用OkHttp实现WebSocket长连接
今天给大家带来一篇老文章,介绍WebSocket,大家可以了解了解。
774 0
用OkHttp实现WebSocket长连接
|
Python
Visual Studio更改编码格式为“UTF-8”
原文:Visual Studio更改编码格式为“UTF-8” 用VS2015新建了个Python文件,在VS2015打开时中文显示正常, 用Visual Studio Code文本编辑器打开时,发现中文乱码 解决方案:在VS2015中修改该文件的编码格式为“UTF-8” 操作方法如下所...
6538 0
|
15天前
|
存储 关系型数据库 分布式数据库
PostgreSQL 18 发布,快来 PolarDB 尝鲜!
PostgreSQL 18 发布,PolarDB for PostgreSQL 全面兼容。新版本支持异步I/O、UUIDv7、虚拟生成列、逻辑复制增强及OAuth认证,显著提升性能与安全。PolarDB-PG 18 支持存算分离架构,融合海量弹性存储与极致计算性能,搭配丰富插件生态,为企业提供高效、稳定、灵活的云数据库解决方案,助力企业数字化转型如虎添翼!
|
10天前
|
缓存 并行计算 PyTorch
144_推理时延优化:Profiling与瓶颈分析 - 使用PyTorch Profiler诊断推理延迟,优化矩阵运算的独特瓶颈
在2025年的大模型时代,推理时延优化已经成为部署LLM服务的关键挑战之一。随着模型规模的不断扩大(从数亿参数到数千亿甚至万亿参数),即使在最先进的硬件上,推理延迟也常常成为用户体验和系统吞吐量的主要瓶颈。
349 147
|
10天前
|
机器学习/深度学习 存储 缓存
92_自我反思提示:输出迭代优化
在大型语言模型(LLM)应用日益普及的今天,如何持续提升模型输出质量成为了业界关注的核心问题。传统的提示工程方法往往依赖一次性输入输出,难以应对复杂任务中的多轮优化需求。2025年,自我反思提示技术(Self-Reflection Prompting)作为提示工程的前沿方向,正在改变我们与LLM交互的方式。这项技术通过模拟人类的自我反思认知过程,让模型能够对自身输出进行评估、反馈和优化,从而实现输出质量的持续提升。
400 136