
获得徽章 0
- #挑战每日一条沸点#
redis bigkey出现的情况:
Bigkey的出现往往是由于以下几种情况:
存储大量的数据结构。例如,将一个非常大的JSON对象或者一个非常大的哈希表存储在Redis中,就会导致Bigkey的出现。
缓存大量的图片或者文件。如果将大量的图片或者文件缓存到Redis中,就会导致Bigkey的出现。
业务逻辑的问题。有些业务逻辑设计不合理,会导致Redis中存在大量的Bigkey。比如统计用户访问量。
危害:
客户端耗时增加,甚至超时
对大key进行IO操作时,会严重占用带宽和CPU
造成Redis集群中数据倾斜
主动删除、被动删等,可能会导致阻塞展开评论点赞 - #挑战每日一条沸点#
redis中怎么处理hot key?
所谓的热key,就是访问频率比较的key。整个流程分为监控和处理两部分。
对热key的处理,最关键的是对热点key的监控,可以从这些端来监控热点key:
客户端。客户端其实是距离key“最近”的地方,因为Redis命令就是从客户端发出的,例如在客户端设置全局字典(key和调用次数),每次调用Redis命令时,使用这个字典进行记录。
代理端。 像Twemproxy、Codis这些基于代理的Redis分布式架构,所有客户端的请求都是通过代理端完成的,可以在代理端进行收集统计。
Redis服务端。 使用monitor命令统计热点key是很多开发和运维人员首先想到,monitor命令可以监控到Redis执行的所有命令。
只要监控到了热key,对热key的处理就简单了:
把热key打散到不同的服务器,降低压⼒
加⼊⼆级缓存,提前加载热key数据到内存中,如果redis宕机,⾛内存查询展开评论点赞 - #挑战每日一条沸点#
为什么要用多级缓存?
分布式缓存+本地缓存 = 多级缓存
读取数据的时候,先从L1读取,如果没有再从L2读取。如果L2没有,再去数据库读取,然后将数据写入到L1和L2中。
原因
提高缓存访问速度:分布式缓存通常运行在远程服务器上,与本地应用程序之间需要通过网络进行通信,因此访问速度相对较慢。而本地缓存则直接运行在应用程序进程内部,访问速度非常快。因此,使用分布式+本地缓存模式可以通过本地缓存提高缓存访问速度,减少远程网络通信带来的延迟。
提高缓存可靠性:分布式缓存由于运行在远程服务器上,可能会受到网络故障、服务器故障等因素的影响,导致缓存数据丢失或不可用。而本地缓存则运行在应用程序进程内部,相对不容易受到外部因素的影响。因此,使用分布式+本地缓存模式可以通过本地缓存提高缓存的可靠性,减少因分布式缓存故障导致的缓存数据丢失或不可用的风险。
减轻分布式缓存负担:分布式缓存通常需要处理大量的缓存请求,可能会导致缓存服务器的负载过高,影响缓存性能。而本地缓存则可以缓存一部分热点数据,减轻分布式缓存的负担,从而提高整个缓存系统的性能。展开评论点赞 - #挑战每日一条沸点#
redis事务缺陷的解决方案?
Redis 从 2.6 版本开始支持执行 Lua 脚本,它的功能和事务非常类似。我们可以利用 Lua 脚本来批量执行多条 Redis 命令,这些 Redis 命令会被提交到 Redis 服务器一次性执行完成,大幅减小了网络开销。
一段 Lua 脚本可以视作一条命令执行,一段 Lua 脚本执行过程中不会有其他脚本或 Redis 命令同时执行,保证了操作不会被其他指令插入或打扰。
不过,如果 Lua 脚本运行时出错并中途结束,出错之后的命令是不会被执行的。并且,出错之前执行的命令是无法被撤销的,无法实现类似关系型数据库执行失败可以回滚的那种原子性效果。因此, 严格来说的话,通过 Lua 脚本来批量执行 Redis 命令实际也是不完全满足原子性的。同时,Redis Cluster下无法保证所有key在一个hash slot上。
如果想要让 Lua 脚本中的命令全部执行,必须保证语句语法和命令都是对的。
另外,Redis 7.0 新增了 Redis functions 特性,你可以将 Redis functions 看作是比 Lua 更强大的脚本。展开评论点赞 - #挑战每日一条沸点#
Redis中先更新DB,再更新缓存?
如果缓存更新成功了,但数据库更新失败,那么此时缓存中是最新值,但数据库中是「旧值」。
虽然此时读请求可以命中缓存,拿到正确的值,但是,一旦缓存「失效」,就会从数据库中读取到「旧值」,重建缓存也是这个旧值。
这时用户会发现自己之前修改的数据又「变回去」了,对业务造成影响。
同时,从「缓存利用率」的角度来评估这个方案,也是不太推荐的。这是因为每次数据发生变更,都「无脑」更新缓存,但是缓存中的数据不一定会被「马上读取」,这就会导致缓存中可能存放了很多不常访问的数据,浪费缓存资源。
而且很多情况下,写到缓存中的值,并不是与数据库中的值一一对应的,很有可能是先查询数据库,再经过一系列「计算」得出一个值,才把这个值才写到缓存中。
由此可见,这种「更新数据库 + 更新缓存」的方案,不仅缓存利用率不高,还会造成机器性能的浪费。展开评论点赞 - #挑战每日一条沸点#
Redis的并发竞争问题如何解决?
1、分布式锁,确保同一时间,只能有一个系统实例在操作某个key,别人都不允许读和写。每次写之前,先判断一下当前这个value的时间戳是否比缓存里的value的时间戳要更新,如果更新,那么可以写;如果更旧,就不能用旧的数据覆盖新的数据(写入缓存的数据都是从mysql中查处来的。一开始写入mysql的时候必须保存一个时间戳。从mysql查出来的时候,时间戳也需要带上)
2、乐观锁:Redis使用乐观锁来解决竞争问题,乐观锁是一种非阻塞机制,它假设并发问题不会发生,但在执行操作之前会检查数据是否发生了变化。如果数据发生了变化,操作将被回滚并重新尝试。
3、事务:Redis提供了原子事务,可以将多个操作作为一个事务执行,从而避免了并发问题。在事务执行期间,其他客户端无法访问被事务锁定的键,直到事务执行完毕。展开评论点赞