===数据结构===
===线程模式===
===事务===
===日志===
redis为什么选择lua作为原子性操作?
Redis 选择 Lua 作为原子性操作的原因是 Lua 脚本能够在 Redis 服务器端原子执行,避免了客户端和服务器之间的多次往返操作。Lua 脚本可以将多个 Redis 命令打包成一个原子操作,在执行过程中,不会被其他命令打断,确保了数据的一致性和操作的原子性,同时也减少了网络延迟,提高了性能。
lua脚本执行时间很长,怎么排查?
如果 Lua 脚本在 Redis 中执行时间很长,可能是由于脚本逻辑复杂、操作的数据量大或者有阻塞操作。排查方法包括:查看 Redis 的慢查询日志、使用 MONITOR
命令跟踪命令执行、使用 DEBUG
命令分析脚本性能,或者通过逐步优化 Lua 脚本来减少执行时间。例如,可以通过分批处理大量数据或避免长时间的阻塞操作
===缓存淘汰和过期策略===
===集群===
Redis主从同步中的增量和完全同步怎么实现?
完全同步:
- 初次同步:从第一次连接主
- 从数据丢失:比如掉电等
- 主变化:从长时间没和主同步,数据差异太大
什么是增量同步?
增量同步允许服务器从断点继续同步,而不是每次都完全同步。基于PSYNC,使用运行ID和复制偏移量。
你知道哪些Redis分区实现方式?
- 客户端分区(决定在哪个节点存取)
- 代理分区(转发给代理由代理决定存取)
- 查询路由(随机存取到正确节点)
1、客户端分区
客户端分区就是在客户端就已经决定数据会被存储到哪个redis节点或者从哪个redis节点读取。大多数客户端已经实现了客户端分区。
2、代理分区
客户端将请求发往代理服务器,代理服务器实现了Redis协议,因此代理服务器可以代理客户端和Redis服务器通信。
代理服务器通过配置的分区schema来将客户端的请求转发到正确的Redis实例中,同时将反馈消息返回给客户端。
3、查询路由
查询路由是redis cluster实现的一种redis分区方式
查查询路由(Query routing) 的意思是客户端随机地请求任意一个redis实例,然后由Redis将请求转发给正确的Redis节点。
Redis Cluster实现了一种混合形式的查询路由,但并不是直接将请求从一个redis节点转发到另一个redis节点,而是在客户端的帮助下直接redirected到正确的redis节点。
Redis支持并发操作吗?
单个redis命令是原子性的
多个操作的事务:可以将一些列操作放在一个事务中。确保一系列事务的原子性。
Redis有哪几种部署方式?
三种部署方式:
1、单机模式
这种方式就是直接部署一个redis实例,既:部署一台redis服务。
2、主从模式
部署一台redis主服务master,多台redi从服务slave,master主服务专门用于redis的写操作,所有的slave从服务专门用于redis的读操作。在master主服务接受到写命令的时候,会将数据同步到所有的slave从服务。
3、Sentinel哨兵模式
哨兵模式,主要是为了解决主从模式下,master主服务不可用的情况。
一般都是:一主二从三哨兵
部署三个哨兵服务,一个master主服务,两个slave从服务。哨兵服务会监控所有的主从服务,按照每秒一次的频率向所有主从服务发送ping命令,如果在指定时间里面,没有接收到主服务的PONG回应,则哨兵服务会认为主服务不可用了,此时会根据一定的规则,通过选举投票方式,将一台从服务提升为master主服务,并且告诉所有其他的从服务,跟随这台新的master主服务。当之前那台主服务重新上线后,它会变成从服务,跟谁新的主服务。
如何保证 redis 的稳定性?
为了保证 Redis 的稳定性,可以从以下几个方面着手:
- 合理配置和优化:确保内存使用、命令优化、内存淘汰策略合理。
- 数据持久化:根据实际需求选择合适的持久化方式(RDB 或 AOF),并结合使用混合持久化。
- 高可用性:通过 Redis Sentinel 或 Redis 集群来确保高可用性和自动故障转移。
- 备份和恢复:定期进行数据备份,并确保能够在故障时恢复数据。
- 监控和告警:定期监控 Redis 的状态,并设置合适的告警机制。
- 网络和连接池优化:优化网络环境和 Redis 连接池配置,避免瓶颈。
分布式锁效率太低怎么办?
为了解决分布式锁效率低的问题,可以考虑以下几个方向:
- 减少锁粒度和持有时间:只对必要的操作加锁,锁内代码尽量短。
- 选择更高效的分布式锁实现:如 Redis RedLock、Zookeeper、Etcd 等。
- 使用乐观锁:避免悲观锁,通过版本号或 CAS 实现乐观锁。
- 合理配置锁过期时间:避免锁死锁和锁泄漏。
- 避免过度使用锁:使用消息队列、异步处理等替代锁。
- 引入缓存机制:通过缓存减少锁的使用频率。
- 避免锁的嵌套使用:减少锁竞争和死锁的风险。
介绍一下RedLock?
共享资源是在每个redis节点上都有吗?还是仅仅在主节点上,对其
Redlock 算法的思想是让客户端向 Redis 集群中的多个独立的 Redis 实例依次请求申请加锁,如果客户端能够和半数以上的实例成功地完成加锁操作,那么我们就认为,客户端成功地获得分布式锁,否则加锁失败。
即使部分 Redis 节点出现问题,只要保证 Redis 集群中有半数以上的 Redis 节点可用,分布式锁服务就是正常的。
Redlock 是直接操作 Redis 节点的,并不是通过 Redis 集群操作的,这样才可以避免 Redis 集群主从切换导致的锁丢失问题。
===场景===
3种常用的缓存读写策略详解
写:
- 先更新 db
- 然后直接删除 cache 。
读 :
- 从 cache 中读取数据,读取到就直接返回
- cache 中读取不到的话,就从 db 中读取数据返回
- 再把数据放到 cache 中。
Read/Write Through Pattern(读写穿透)
写(Write Through):
- 先查 cache,cache 中不存在,直接更新 db。
- cache 中存在,则先更新 cache,然后 cache 服务自己更新 db(同步更新 cache 和 db)。
读(Read Through):
- 从 cache 中读取数据,读取到就直接返回 。
- 读取不到的话,先从 db 加载,写入到 cache 后返回响应。
Read/Write Through 是同步更新 cache 和 db,而 Write Behind 则是只更新缓存,不直接更新 db,而是改为异步批量的方式来更新 db。
本地缓存和redis缓存的区别?
本地缓存:将数据存储在本地的应用程序or服务器,加速数据访问和提高响应速度。存储在内存中,提高数据的读写速度。
-
- 优势:访问速度快,减轻网络压力,低延迟
- 不足:可扩展性差。本地硬件资源有限,无法支持大规模数据
Redis缓存:数据存储在多个节点上,高性能数据访问。集群部署,分担数据存储和访问压力。
-
- 优势:可扩展性强,数据一致性高,通过分布式一致性协议,减少数据不一致问题。易于维护:自动化管理方式
- 不足:访问速度相对慢,增大网络开销
缓存预热如何实现?
常见的缓存预热方式有两种:
- 使用定时任务,比如 xxl-job,来定时触发缓存预热的逻辑,将数据库中的热点数据查询出来并存入缓存中。
- 使用消息队列,比如 Kafka,来异步地进行缓存预热,将数据库中的热点数据的主键或者 ID 发送到消息队列中,然后由缓存服务消费消息队列中的数据,根据主键或者 ID 查询数据库并更新缓存。
本地缓存冷数据突然变成热数据导致大量请求打到redis上如何优化?
当本地缓存的冷数据突变为热数据时,大量请求穿透本地缓存直击Redis,本质是缓存失效风暴与热点数据发现延迟的综合问题。
优化方向 | 技术方案 | 适用场景 |
预测性预热 | 基于历史/实时数据分析,提前加载潜在热点数据到本地缓存 | 可预测的周期性热点(如秒杀活动) |
动态TTL调整 | 根据访问频率动态延长本地缓存过期时间 | 突发流量但无法预测具体Key的场景 |
二级缓存屏障 | 本地缓存未命中时,先查Redis,再回源数据库,并增加本地缓存更新同步机制 | 高并发读写混合场景 |
请求合并 | 对同一Key的并发请求,使用SingleFlight模式合并为单个Redis查询 | 突发性不可预测热点 |
熔断限流 | 对高频访问Key启用令牌桶限流,或基于熔断机制临时拒绝部分请求 | Redis资源接近瓶颈的紧急防护 |