每日一考-9.13

什么是Redis的哈希槽

哈希槽其实就是一个数组,数组[0, 1, 2, ..., 2^14-1]形成hash slot空间

Redis 集群中内置了 16384 个哈希槽,当需要在 Redis 集群中放置一个 key-value时,redis 先对 key 使用 crc16 算法算出一个结果,然后把结果对 16384 求余数,这样每个 key 都会对应一个编号在 0-16383 之间的哈希槽,redis 会根据节点数量大致均等的将哈希槽映射到不同的节点。

目的:保证数据倾斜一致,为了方便的添加或移除节点,当需要增加节点,只需把其他节点上某些哈希槽挪到新节点,要移除同理。

redis哈希槽分区的特点:
1)解耦数据和节点之间的关系,例如:数据的读写只要计算出槽号就可以,节点的扩容和收缩只要重新均衡分配槽区间即可;故简化了节点扩容和收缩难度
2)节点自身维护槽的映射关系,不需要客户端(spring)或者代理服务维护槽分区和数据
3)支持节点、槽、键之间的映射查询,用于数据路由、在线伸缩等场景

什么是redis?优缺点

  • redis是一种开源的Key-Value类型的高性能缓存数据库,整个数据库的操作全部加载在内存中进行操作。
  • 可用作缓存(最广泛),消息中间件,支持数据持久化(RDB和AOF)
  • 支持多种数据类型,常用5种 String,Hash,List,Set,ZSet。其他三种 Bitmap(位图),HyperLogLog(超级日志),Geospatial(地理空间)。
  • 支持master-slave(主从) 模式的数据备份。
  • 内置了复制,Lua脚本,LRU驱动事件,事务和不同级别的磁盘持久化,并通过Redis哨兵模式(Sentinel)和集群模式(Cluster)提供高可用性。

优点

  • 速度快,使用标准的c实现,所以数据操作都在内存中完成。 Redis能读的速度是110000次/s,写的速度是81000次/s。
  • 支持数据持久化,支持AOF和RDB两种持久化方式。
  • 支持事务,Redis的所有操作都是原子性的,同时Redis还支持对几个操作合并后的原子性执行。
  • 数据结构丰富,除了支持string类型的value外还支持hash、set、zset、list等数据结构。
  • 支持主从复制,主机会自动将数据同步到从机,可以进行读写分离。

缺点

  • Redis的数据库容量受到物理内存的限制,不能用作海量数据的高性能读写,因此Redis适合的场景主要局限在较小数据量的高性能操作和运算上;
  • 在主节点宕机前有部分数据不能及时同步到从节点上;
  • Redis 不具备自动容错和恢复功能,主机从机的宕机都会导致前端部分读写请求失败,需要等待机器重启或者手动切换前端的IP才能恢复。
  • Redis 较难支持在线扩容,在集群容量达到上限时在线扩容会变得很复杂。为避免这一问题,运维人员在系统上线时必须确保有足够的空间,这对资源造成了很大的浪费。

如何保证Redis的高并发和高可用

主从+哨兵+集群

Redis主从架构Sentinel,一主多从,可以满足高可用和高并发。出现实例宕机自动进行主备切换,配置读写分离缓解Master读写压力。Redis 的集群模式。

Redis高可用方案具体怎么实施

使用官方推荐的哨兵(sentinel)机制就能实现,当主节点出现故障时,由Sentinel自动完成故障发现和转移,并通知应用方,实现高可用性。它有四个主要功能:

  1. 集群监控,负责监控redis master和slave进程是否正常工作。
  2. 消息通知,如果某个redis实例有故障,那么哨兵负责发送消息作为报警通知给管理员。
  3. 故障转移,如果master node挂掉了,会自动转移到slave node上。
  4. 配置中心,如果故障转移发生了,通知client客户端新的master地址。

介绍Redis事务的概念和Redis事务三个阶段

redis 事务是一次可以执行多个命令,它的本质是一组命令的集合。一个事务中所有的命令都会被序列化,在事务执行的过程中会按照顺序执行队列中的命令。其它客户端提交的命令请求会等到事务执行完毕再执行。

redis事务是分为三个阶段

  • 开启 :以MULTI开始一个事务
  • 入队 :将多个命令入队到事务中,接到这些命令并不会立即执行,而是放到等待执行的事务队列里面
  • 执行 :由EXEC命令触发事务

为什么 Redis 不支持回滚?

  • Redis 命令只会因为错误的语法而失败(并且这些问题不能在入队时发现),或是命令用在了错误类型的键上面:这也就是说,从实用性的角度来说,失败的命令是由编程错误造成的,而这些错误应该在开发的过程中被发现,而不应该出现在生产环境中。
  • 因为不需要对回滚进行支持,所以 Redis 的内部可以保持简单且快速。

注意:通常状况下,其实事务回滚并不能解决编程错误带来的问题。

什么是缓存穿透问题,如何解决

缓存穿透是指缓存和数据库中都没有的数据 ,而用户不断发起请求。由于缓存是不命中时被动写的,并且出于容错考虑,如果从存储层查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到存储层去查询,失去了缓存的意义。

如:发起为id为“-1”的数据或id为特别大不存在的数据。这时的用户很可能是攻击者,攻击会导致数据库压力过大,在流量足够大是,可能就会导致DB挂掉。

解决方案:

  1. 接口层增加校验,如用户鉴权校验,id做基础校验,id<=0的直接拦截;
  2. 从缓存取不到的数据,在数据库中也没有取到,这时也可以将key-value对写为key-null,缓存有效时间可以设置短点,如30秒(设置太长会导致正常情况也没法使用)。这样可以防止攻击用户反复用同一个id暴力攻击
  3. 布隆过滤器。bloomfilter就类似于一个hash set,用于快速判某个元素是否存在于集合中,其典型的应用场景就是快速判断一个key是否存在于某容器,不存在就直接返回。布隆过滤器的关键就在于hash算法和容器大小

什么是缓存击穿,如何解决

缓存击穿是指缓存中没有但数据库中有的数据 (一般是缓存时间到期),这时由于并发用户特别多,同时读缓存没读到数据,又同时去数据库去取数据,引起数据库压力瞬间增大,造成过大压力。

解决方案:

1、设置热点数据永远不过期

2、接口限流与熔断,降级。重要的接口一定要做好限流策略,防止用户恶意刷接口,同时要降级准备,当接口中的某些 服务 不可用时候,进行熔断,失败快速返回机制。

3、加互斥锁

什么是缓存雪崩,如何解决

缓存雪崩是指缓存中数据大批量到过期时间,而查询数据量巨大,引起数据库压力过大甚至down机 。和缓存击穿不同的是,缓存击穿指并发查同一条数据,缓存雪崩是不同数据都过期了,很多数据都查不到从而查数据库。

解决方案:

  1. 缓存数据的过期时间设置随机,防止同一时间大量数据过期现象发生。
  2. 如果缓存数据库是分布式部署,将热点数据均匀分布在不同的缓存数据库中
  3. 设置热点数据永远不过期

缓存更新策略有哪些

缓存更新是指在数据发生变化后即使将变化的数据更新到缓存中,常见的更新策略有以下4种

  • 定时更新:定时将底层数据库内的数据更新到缓存中,比较简单,适合需要缓存的数据量不是很大的场景
  • 过期更新:定时将缓存中过期的数据更新为最新数据并更新缓存过期时间
  • 写请求更新:在用户有写请求是先写数据库同时更新缓存,这适用于用户对缓存数据和数据库数据又实时强一致性要求的情况
  • 读请求更新:在用户有读请求时,先判断该请求数据的缓存是否存在或过期,如果不存在或已经过期,则进行底层数据库查询并将查询数据结果更新到缓存中,同时将查询结果返回给用户。

缓存淘汰策略

在缓存数据过多时,需要使用某些淘汰算法决定淘汰某些数据

  • FIFO(先进先出):判断被缓存的时间,离目前最远的先被淘汰
  • LRU(最近最少使用):判断缓存最近被使用的时间,距离当前时间最远的最先被淘汰
  • LFU(最不经常使用):在一段时间内,被使用次数最少的优先被淘汰
  • random(随机删除):在设置了过期时间的键值对中,进行随机删除

如何保障缓存与数据库双写时数据一致性

实现缓存与数据库的双写一致性大致有四个类别,分别是:

①先更新缓存,再更新数据库

②先更新数据库,再更新缓存

③先删除缓存,再更新数据库

④先更新数据库,再删除缓存

但由于他们各有优缺点,但想更新数据库,再删除缓存是影响更小的方案。如果第二步出现失败的情况,则可以采用重试机制来解决问题。

所以可采用延时双删

  1. 删除缓存
  2. 更新数据库
  3. sleep n 毫秒
  4. 删除缓存

再阻塞一段时间后,再次删除缓存,就可以把这个过程中的缓存中不一致的数据删除,具体阻塞时间要根据业务时间来设置。

为什么需要进行缓存预热

缓存预热是指系统上线后,提前将相关的缓存数据加载到缓存系统中,避免刚上线使用户有太多请求打到数据库上去,然后再去将数据缓存的问题。

优势:缓存预热后,系统用户上线后就可以直接拆线呢实现被预热的缓存数据,如果不进行缓存预热,在系统上线初期,如果存在高并发的流量,大量访问数据库,会对数据库造成流量的压力,甚至导致数据库宕机。

在数据量不大时,可以不进行缓存预热,或是工程启动 后再进行加载缓存动作,但数据量很大的时候,一定要保证热点数据提前加载到缓存

缓存的应用场景有哪些

  1. 冷热分离:将缓存作为热数据层,将关系型数据库作为冷数据层。在数据写入数据库时,也像缓存中存储一份,可以在客户端查询时直接访问缓存,提升查询性能。
  2. 热数据存储:在一些高并发的场景下,如果数据结构简单,则可以直接将数据存在分布式缓存中,以增加系统的并发效率。
  3. 计数器:可通过分布式缓存实时统计一些业务指标,入用户登录次数,核心API访问次数,文章店长次数和阅读次数和密码错误提升,如在5小时内只能输错3次,否则就不允许登录,或冻结账号等。
  4. 限流:对一些核心业务或者核心API调用次数进行统计,但流量请求超过阈值时,执行限流,以保障系统在遭遇流量攻击时能抗住压力。
  5. 排行:基于一些统计数据进行排行榜展示。如统计每个新闻的“点击此处”超链接,从而确定Top10热榜新闻。
  6. 分布式🔒:利用Redis的setnx方法实现分布式🔒。
  7. 分布式Session:在分布式环境下将用户的Session信息存储在分布式缓存中,以实现分布式环境下用户身份验证。当用户登录后会保存一个Session于缓存中,当下次用户再次访问时,如果发现缓存中存在该用户的Session信息,则用户是合法,允许用户对系统接口进行访问。一般需要配置过期时间。如果在该时间用户没任何操作,则清理该Session
  8. 全局ID:利用redis中incrby的原子性操作特性,为分布式表生成全局唯一的ID,用户可以一次获取一个或多个ID。
posted @   别亦难  阅读(14)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
点击右上角即可分享
微信分享提示