从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可以实现更为复杂的消息队列,支持消息的优先级、持久化和高可用等高级功能。
相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
NoSQL Redis
31Redis - 如何启动多个Redis
31Redis - 如何启动多个Redis
135 0
|
6月前
|
存储 NoSQL 定位技术
从0开始回顾Redis---系列三
数据结构 1、讲一讲Redis数据类型及底层数据结构? Redis 的五大常用数据类型:String(字符串)、List(列表)、Hash(哈希)、Set(集合)和Sorted Set(有序集合) 1.1 String(SDS) 简介 ● 是 Redis 最基本的数据类型,普通的key- value 存储都可以归为此类。二进制安全的,可以包含任何数据,比如 JPG 图片或者序列化的对象,最大能存储 512 MB。 应用场景:计数的场景,用户的访问次数、热点文章的点赞转发数量。 底层实现:String对象底层的数据结构实现主要是 int 和简单动态字符串 SDS。 struct sdshdr{
|
6月前
|
NoSQL Linux Redis
Redis -- 安装客户端redis-plus-plus
Redis -- 安装客户端redis-plus-plus
352 0
|
6月前
|
消息中间件 缓存 NoSQL
从0开始回顾Redis---系列八
缓存 1、缓存穿透? 缓存穿透是指缓存和数据库中都没有的数据,而用户不断发起请求,如发起为id为“-1”的数据或id为特别大不存在的数据。这时的用户很可能是攻击者,攻击会导致数据库压力过大。 解决方案: 1. 接口校验:在正常业务流程中可能会存在少量访问不存在 key 的情况,但是一般不会出现大量的情况,所以这种场景最大的可能性是遭受了非法攻击。可以在最外层先做一层校验:用户鉴权、数据合法性校验等,例如商品查询中,商品的ID是正整数,则可以直接对非正整数直接过滤等等。 2. 缓存空值:当访问缓存和DB都没有查询到值时,可以将空值写进缓存,但是设置较短的过期时间,该时间需要根据产品业务特性来
|
6月前
|
NoSQL 算法 Redis
从0开始回顾Redis---系列七
切片集群 1、为什么要集群? 在实际应用Redis时,随着用户或业务规模的扩展,保存大量数据的情况通常是无法避免的。 我们可以用两种方案: 1. 纵向扩展:升级单个Redis实例的资源配置,包括增加内存容量、增加磁盘容量、使用更高配置的CPU。 2. 横向扩展:横向增加当前Redis实例的个数 。 那么,这两种方式的优缺点分别是什么呢? 1. 纵向扩展: ● 优点:实施起来简单、直接。 ● 缺点: ○ 当使用RDB对数据进行持久化时,如果数据量增加,需要的内存也会增加,主线程fork子进程时就可能会阻塞(比如刚刚的例子中的情况) ○ 纵向扩展会受到硬件和成本的限制。 2.
|
6月前
|
存储 NoSQL Redis
从0开始回顾Redis---系列二
Redis单线程 1、单线程Redis为什么这么快? 1. 单线程实现:避免了多线程编程模式面临的共享资源的并发访问控制问题,比如线程切换和锁资源争用的开销。 2. 内存存储:Redis是使用内存存储,没有磁盘IO上的开销。 3. 高效的数据结构: 采用了高效的数据结构,例如哈希表和跳表,这是它实现高性能的一个重要原因。 4. 采用多路复用机制:使其在网络IO操作中能并发处理大量的客户端请求,实现高吞吐率。 2、基于多路复用的高性能I/O模型 多路复用机制是指一个线程处理多个IO流,就是我们经常听到的select/epoll机制。简单来说,在Redis只运行单线程的情况下,该机制允许内
|
6月前
|
运维 监控 NoSQL
从0开始回顾Redis---系列六
哨兵机制 1、什么是哨兵,哨兵的作用是什么? 哨兵其实就是一个运行在特殊模式下的Redis进程,主从库实例运行的同时,它也在运行。哨兵主要负责的就是三个任务:监控、选主(选择主库)和通知。 ● 监控:哨兵进程在运行时,周期性地给所有的主从库发送PING命令,检测它们是否仍然在线运行。如果从库没有在规定时间内响应哨兵的PING命令,哨兵就会把它标记为“下线状态”;同样,如果主库也没有在规定时间内响应哨兵的PING命令,哨兵就会判定主库下线,然后开始自动切换主库的流程。 ● 选主:主库挂了以后,哨兵就需要从很多个从库里,按照一定的规则选择一个从库实例,把它作为新的主库。这一步完成后,现在的集群里
|
6月前
|
缓存 NoSQL 关系型数据库
从0开始回顾Redis---系列一
基础 1、Redis是什么?简述它的优缺点? Redis是用 C 语言开发的一个开源的高性能键值对(key-value)内存数据库。经常被用来做缓存,消息队列,分布式锁。 Redis 提供了多种数据类型来支持不同的业务场景,如 字符串(strings),散列(hashes), 列表(lists), 集合(sets), 有序集合(sorted sets)与范围查询。 Redis 还支持事务 、持久化、Lua 脚本、多种集群方案。 优点: ● 读写性能极高, Redis能读的速度是110000次/s,写的速度是81000次/s。 ● 支持数据持久化,支持AOF和RDB两种持久化方式。 ●
|
6月前
|
存储 NoSQL 定位技术
从0开始回顾Redis---系列四
数据结构 1、讲一讲Redis数据类型及底层数据结构? Redis 的五大常用数据类型:String(字符串)、List(列表)、Hash(哈希)、Set(集合)和Sorted Set(有序集合) 1.1 String(SDS) 简介 ● 是 Redis 最基本的数据类型,普通的key- value 存储都可以归为此类。二进制安全的,可以包含任何数据,比如 JPG 图片或者序列化的对象,最大能存储 512 MB。 应用场景:计数的场景,用户的访问次数、热点文章的点赞转发数量。 底层实现:String对象底层的数据结构实现主要是 int 和简单动态字符串 SDS。 struct sdshdr{
|
6月前
|
负载均衡 NoSQL Redis
从0开始回顾Redis---系列五
主从复制 1、什么是Redis主从复制? ● 主从复制,是指将一台Redis服务器的数据,复制到其他的Redis服务器。前者称为主节点(master),后者称为从节点(slave);数据的复制是单向的,只能由主节点到从节点。 ● 默认情况下,每台Redis服务器都是主节点;且一个主节点可以有多个从节点(或没有从节点),但一个从节点只能有一个主节点。 2、主从复制有哪些好处? ● 读写分离:master 写、slave 读,提高服务器的读写负载能力; ● 负载均衡:基于主从结构,配合读写分离,由 slave 分担 master 负载,并根据需求的变化,改变 slave 的数量,通过多个从节点分担
下一篇
无影云桌面