Redis进阶学习

Redis进阶学习

一、发布订阅模式

Redis也可以实现类似与消息队列的功能,也就是发布订阅模式。拥有两个角色,发布者和订阅者。

  • 订阅者:可以订阅一个或多个频道(channel),但只能获取到订阅之后的消息。可以订阅同一个频道多次,这将会重复收到消息。

  • 发布者:发布的消息可以被多个订阅者消费,发布的消息不会进行持久化,这也是订阅者不能获取到订阅前的消息的原因。

1.简单使用
# 向test频道发送一条消息hello world
127.0.0.1:6379> publish test "hello world"
# 返回值表示这条消息被多少个消费者消费
(integer) 0
# 订阅test频道
127.0.0.1:6379> subscribe test
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "channel:test"
3) (integer) 1

psubscribe可以订阅多个频道,若订阅相同频道,将收到多条重复消息。发布者也会显示有多个消费者。

2.总结

1). 这个模式经常被用于群聊,即时聊天等场景。在Redis中,我们可以对一个key进行发布订阅,那么在key上发布消息后,订阅者将收到消息。
2). 虽然Redis也提供了类似消息队列的功能,但仅仅是简单的发布订阅,和消息队列还是有很大差别的,比如说持久化,消息协议,消息传输保障等。所以redis仅适用于只需要简单实现发布订阅功能的项目,对于需要消息持久化,消息重发等场景的项目,还是要老老实实使用消息队列。


二、主从复制与哨兵模式

1.主从复制
1.1 简单介绍

默认的情况下,每个Redis实例都是以自己为主节点的(master),而生产环境下是必须保证高可用的,单机自然不可取的。

主从复制是指将数据从主Redis(master)复制到其他的从Redis(slave)。在使用主从复制时我们最少要保证一主二从,并且master节点用于写,slave节点用于读。主从复制有几个优点

  • 数据冗余:主从复制相当于数据的热备份。
  • 容灾恢复:可以理解为服务的冗余,当主节点出现问题,其他的节点可以进行替换。
  • 读写分离:主从复制配合读写分离,主节点负责写,从节点负责读,分摊了服务器的压力。
  • 高可用:主从复制是哨兵模式的基础,而哨兵模式是高可用的。
1.2原理

主从复制的原理是:从节点连接上主节点后,发送一条sync同步指令,然后master节点会收集所有的写命令,在后台收集完毕后发送给slave节点。主从复制有两种,一种是全量复制一种是增量复制,在slave连接上master后首先会进行一次全量复制,然后进行增量复制。

1.3简单使用
# 成为127.0.0.1:6379的子节点
slaveof 127.0.0.1:6379
info replication	# 查看信息

但这种通过命令的方式在每次重启都要重新搭建集群。更推荐使用修改redis配置文件的方式

replicaof 127.0.0.1 6379
masterauth <password>
1.4总结

大多是情况下我们都是对缓存进行读取,而读取的速率远高于写,所以读写分离是十分重要的。因为生产环境需要保证高可用,所以单机集群是不可取的,为了保证服务的稳定性,一主二从是最基本的结构


2.哨兵模式
2.1简单介绍

哨兵模式可以简单的理解为将主从复制自动化。主从复制当主节点出现问题的时候,我们需要手动的切换主节点,而哨兵模式则是自动检测各个节点,若master出现问题,则重新选举一个新的master。当旧master正常工作后,将成为一个slave节点。

2.2原理

启动一个新的进程,向各个节点发送指令让其返回运行状态,若发现master死亡,就通过发布订阅模式让slave节点自动选举并切换为master。如果有多个哨兵,哨兵之间也会互相监控

2.3简单使用

编写配置文件sentinel.conf

vim sentinel.conf

# 端口
port 26379
# sentinel monitor 名称 host port 1
# 监视的redis是master
sentinel monitor mymaster 127.0.0.1 6379 1

启动哨兵

redis-sentinel dtconfig/sentinel.conf
2.4总结

哨兵模式基于主从复制,所以具备主从复制的所有优点,并且不用手动切换master。哨兵模式主从之间可以切换,所以额外具备故障转移的优点。但哨兵模式配置比较麻烦,并且当集群容量达到上限时不好在线扩容。


三、缓存穿透、击穿、雪崩

1.缓存穿透
1.1 介绍

当用户需要查询一个redis中没有的数据时,这个请求就会去查询数据库,若数据库中也没有,则无法将该数据缓存在redis中。如果有人恶意攻击大量请求这条数据时,请求就会全部落在数据库上导致数据库承受不住压力而崩溃。

1.2 解决方法

其实理解了缓存穿透的原理就很好解决了,导致数据库崩溃的原因是redis和数据库中都没有这条数据,那么我们只需要允许redis缓存这条空值即可,或者拦截这条请求。

  • 布隆过滤器:布隆过滤器的原理就是对参数进行校验,将不符合规则的请求拦截在外,从而降低数据库的压力。

  • 缓存空对象:若数据库中没有这条数据,则保存一个空值到redis中。这样做虽然可以解决问题,但是也带来了问题:redis中可能存在过多的空值;redis和数据库可能出现数据不一致。

2.缓存击穿
2.1 介绍

一个热点key承载着高并发,在达到它失效时间的一瞬间,可能会导致大量的请求直接落在数据库上从而导致数据库瘫痪。

2.2 解决方案

解决之前首先要理解出现缓存击穿的原因,是因为一个承载高并发的key到达了失效时间,而由于高并发的原因,在没来得及更新redis中的数据之前,数据库就已经崩溃了。所以有两种解决方法

  • 设置热点key永不失效,这就让请求永远不会直接落在数据库上,但这样做实际不合理。
  • 数据库增加互斥锁:一次只能有一个请求进入数据库,其他的线程则等待一段时间。这样当其他请求恢复运行的时候就会发现redis中的数据已经更新了,就不会请求到数据库中。
3.缓存雪崩
3.1 介绍

当大量的key同时达到失效时间时,就会导致大量请求落在数据库中。

3.2 解决方案

因为时大量key同时过期导致的问题,所以我们可以给key设置不同的过期时间。

  • 分析用户行为,让key的过期时间尽可能的均匀分布。
  • 如果是因为redis宕机导致的雪崩,可以搭建redis主从集群,但也需要注意主从集群可能导致读到脏数据的问题。
  • 数据库加锁,同一时间只允许一个线程执行。
4.总结

穿透,击穿,雪崩的根本原因都是redis中无数据或数据过期导致数据库不能负担压力。同一的解决方法就是数据库加锁,但很明显会导致效率大大降低。对于可能出现的问题,我们可以从发生前,发生时,发生后入手。发生前我们可以做过滤,合理设置过期时间,发生时我们可以给数据库加锁,发生后我们可以对redis做集群扩展。


四、缓存与数据库更新

一般的项目里引入redis缓存后,数据就存在两份,一份在数据库中,一份在redis中。而为了保证数据的一致性,在更新数据时我们也需要对redis进行更新。那么就有几种方法

  1. 先更新数据库在更新缓存
  2. 先删缓存在更新数据库
  3. 先删除缓存再更新数据库最后再延迟删除缓存
  4. 先更新数据库再删除缓存

但其实这几种方法在高并发下各有各的问题:

  1. 先更新数据库在更新缓存,可能会导致数据不一致。线程A更新了数据库,在更新缓存之前,线程更新了数据库并更新了缓存,最后线程B又更新了缓存。这就导致了数据不一致。
  2. 先删缓存在更新数据库,redis中可能使脏数据。线程1删除了缓存,在更新数据库前,线程B将数据库中的数据读取到redis中,最后线程A才更新数据库。这就导致了redis中的数据使脏数据。
  3. 延迟双删,解决了数据一致性问题,但带来了性能问题。说一下为什么要延迟删除,因为要确保数据库已经更新之后再删除缓存
  4. 先更新数据库再删除缓存,当更新缓存的同时key过期,例如线程A读取数据,发现过期就读库,线程B更新数据库并删除缓存,此时线程A更新缓存,可能就会导致redis中的数据是脏数据。
<think> 嗯,用户明确提出了想获取Redis高级进阶学习的相关知识。从用户引用的多个资料片段来看,用户应该已经掌握了Redis的基础知识,现在希望向更深入的领域探索。 用户引用的资料[1]特别提到了一份涵盖原理、集群、应用、拓展、源码五个方面的Redis高级笔记,这正好符合用户当前的需求阶段。资料[2]也验证了这个知识框架的完整性。而资料[3]提到的数据类型深度解析和优化方法,资料[5]涉及的持久化配置细节,都是进阶学习的关键内容。 考虑到用户可能的发展方向,需要覆盖以下几个方面:首先是底层原理,包括内存管理、线程模型等;其次是集群方案,特别是分布式场景下的解决方案;然后是实战优化,如何提升Redis在生产环境中的表现;最后是源码层面,为深度定制做准备。 在组织回复时,应该突出知识体系的层次性。把最核心的原理放在第一部分,因为这是理解后续内容的基础。集群方案要强调主从复制和分片的区别,这是很多开发者容易混淆的点。优化部分需要给出具体可操作的技巧,比如连接池配置和慢查询分析方法。源码学习路径要降低用户的学习门槛,建议从核心数据结构开始。 用户提到"面试跟日常开发肯定够用",说明可能有职业发展需求,所以补充了面试加分项这个实用模块。同时注意到资料[4]提到面试官会随机考察知识广度,因此在集群方案中特意加入了Codis等生态工具的介绍。 最后用资料[1]的"原来Redis还能这么玩"作为结尾呼应,保持轻松专业的语气。相关问题设计覆盖了用户可能继续探索的方向,特别是源码和性能优化这类深度话题。 </think> 以下是Redis高级进阶学习的核心知识体系,结合权威资料整理为系统化框架,助你全面提升Redis实战原理理解: --- ### **一、底层原理深度解析** [^1][^2] 1. **内存管理机制** - 动态字符串(SDS)设计优势 - 字典(rehash)渐进式迁移策略 - 跳表(zskiplist)实现有序集合 - 内存碎片优化方案 2. **多线程模型演进** - Redis 6.0+多线程IO原理 - 单线程命令处理的原子性保障 - 后台线程处理过期键和AOF ```c // SDS结构示例(源码简化版) struct sdshdr { int len; // 实际字符串长度 int free; // 剩余空间 char buf[]; // 字节数组 }; ``` --- ### **二、高可用集群架构** [^1][^2] | **方案** | **核心机制** | **适用场景** | |----------------|------------------------------|-------------------------| | 主从复制 | 全量同步+增量同步 | 读写分离基础架构 | | Redis Sentinel | 哨兵选举、故障自动转移 | 高可用监控解决方案 | | Redis Cluster | 虚拟槽分区(16384 slots) | 分布式横向扩展 | | Codis | Proxy层分片方案 | 大规模集群迁移过渡方案 | --- ### **三、性能优化实战** [^3][^5] 1. **持久化调优** - RBD配置策略:`save 900 1` vs `save 60 10000` - AOF重写优化:`auto-aof-rewrite-percentage 100` - 混合持久化:`aof-use-rdb-preamble yes` 2. **高并发陷阱规避** - Pipeline批量操作减少RTT - 连接池配置:`maxTotal``maxIdle`比例 - 慢查询监控:`slowlog-log-slower-than 10000` --- ### **四、源码级深度探索** [^1][^2] 1. **学习路径建议:** - ① 事件驱动框架:`aeEventLoop` - ② 数据结构实现:`dict.c` / `ziplist.c` - ③ 网络通信模型:`networking.c` 2. **调试技巧:** ```bash # GDB调试Redis实例 gdb --args ./src/redis-server redis.conf break processCommand ``` --- ### **五、应用场景进阶** [^3][^4] 1. **分布式锁方案** - Redlock算法实现争议 - SETNX + Lua原子释放 2. **二级索引构建** - 利用ZSet实现多维度排序 - GEO模块实现地理位置查询 3. **流处理系统** - Stream数据结构实现消息队列 - 消费者组(Consumer Group)负载均衡 --- ### **六、面试深度考点** [^4] ```markdown 高频问题示例: 1. Redis事务MySQL事务的本质区别? 2. 缓存雪崩/穿透/击穿解决方案对比 3. 集群脑裂(Split-Brain)的产生预防 4. Redis7新特性(Function API、ACL增强) ``` > 资料建议:结合《Redis设计实现》+ Redis官方源码注释学习[^1][^3],实战推荐通过`redis-benchmark`压测不同配置的性能差异[^5]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值