导图社区 Redis脑图
击穿:现象:一个热点key,在不停的扛着大并发,某个时间key过期,大量请求直接访问DB。解决方法:1.设置热点永不过期。
社区模板帮助中心,点此进入>>
论语孔子简单思维导图
《傅雷家书》思维导图
《童年》读书笔记
《茶馆》思维导图
《朝花夕拾》篇目思维导图
《昆虫记》思维导图
《安徒生童话》思维导图
《鲁滨逊漂流记》读书笔记
《这样读书就够了》读书笔记
妈妈必读:一张0-1岁孩子认知发展的精确时间表
redis
应用场景
系统削峰、异步、解偶
日志系统
秒杀系统
系统缓存
基础知识
数据结构
5种基本数据结构:String、List、Hash、Set、SortedSet
其他数据结构:HyperLogLog、Geo、Push/Sub
用于防止缓存穿透数据结构:BloomFilter
概念:它实际上是一个很长的二进制向量和一系列随机映射函数
原理:添加时,通过K个散列函数将元素映射成一个位数组中的K个点,把它们置为1。检索时,我们只要看看这些点是不是都是1,如果有任何一个点为0,则被检元素一定不在;如果都是1,则被检元素很可能在。
实现:Guava
应用场景:缓存穿透、垃圾邮件过滤、爬虫过滤已抓到的url就不再抓
设置Key过期:setRedis
分布式锁
先拿setnx来争抢锁,抢到之后,再用expire给锁加一个过期时间防止锁忘记了释放
如果在setnx之后执行expire之前进程意外crash或者要重启维护,则setnx和expire合成一条指令来用
keys命令
Redis单线程的。keys指令会导致线程阻塞一段时间,线上服务会停顿,直到指令执行完毕,服务才能恢复
scan指令可以无阻塞的提取出指定模式的key列表,但是会有一定的重复概率,在客户端做一次去重就可以了,但是整体所花费的时间会比直接用keys指令长
SMEMBERS 命令可以返回集合键当前包含的所有元素
SCAN 这类增量式迭代命令 键可能会被修改,只能对被返回的元素提供有限的保证
异步队列
使用list结构作为队列,rpush生产消息,**lpop**消费消息。当lpop没有消息的时候,要适当sleep一会再重试
list还有个指令叫blpop,在没有消息的时候,它会阻塞住直到消息到来
使用pub/sub主题订阅者模式,可以实现 1:N 的消息队列
在消费者下线的情况下,生产的消息会丢失,得使用专业的消息队列如RocketMQ
延时队列
使用sortedset,拿时间戳作为score,消息内容作为key调用zadd来生产消息,消费者用zrangebyscore指令获取N秒之前的数据轮询进行处理
持久化
RDB做镜像全量持久化,AOF做增量持久化。因为RDB会耗费较长时间,不够实时,在停机的时候会导致大量丢失数据,所以需要AOF来配合使用。在redis实例重启时,会使用RDB持久化文件重新构建内存,再使用AOF重放近期的操作指令来实现完整恢复重启之前的状态
机器断电对数据的影响
取决于AOF日志sync属性的配置,如果不要求性能,在每条写指令时都sync一下磁盘,就不会丢失数据。但是在高性能的要求下每次都sync是不现实的,一般都使用定时sync,比如1s1次,这个时候最多就会丢失1s的数据
RDB原理
fork是指redis通过创建子进程来进行RDB操作,cow指的是copy on write,子进程创建后,父子进程共享数据段,父进程继续提供读写服务,写脏的页面数据会逐渐和子进程分离开来
Pipeline好处
可以将多次IO往返的时间缩减为一次,前提是pipeline执行的指令之间没有因果相关性。使用redis-benchmark进行压测的时候可以发现影响redis的QPS峰值的一个重要因素是pipeline批次指令的数目
集群同步机制
edis可以使用主从同步,从从同步。第一次同步时,主节点做一次bgsave,并同时将后续修改操作记录到内存buffer,待完成后将RDB文件全量同步到复制节点,复制节点接受完成后将RDB镜像加载到内存。加载完成后,再通知主节点将期间修改的操作记录同步到复制节点进行重放就完成了同步过程。后续的增量数据通过AOF日志同步即可,有点类似数据库的binlog
缓存雪崩、穿透、击穿
雪崩
现象:缓存大面积失效,大量请求直接访问DB,DB宕机
解决方法:1.往Redis存数据的时候,把每个Key的失效时间都加个随机值就好了
2.Redis是集群部署,将热点数据均匀分布在不同的**Redis**库中也能避免全部失效的问题
.设置热点数据永远不过期
穿透
现象:用户不断发起存缓存和数据库中都没有的数据的请求,导致数据库压力过大,严重会击垮数据库
解决方法:1.在接口层增加校验
2.Redis用布隆过滤器
3.在网关层Nginx增加配置项,对单个IP每秒访问次数超出阈值的IP都拉黑
击穿
现象:一个热点key,在不停的扛着大并发,某个时间key过期,大量请求直接访问DB。
解决方法:1.设置热点永不过期
2.增加互斥锁
RDB
冷备
RDB 持久化机制,是对 **Redis** 中的数据执行**周期性**的持久化
优点:RDB对Redis的性能影响非常小,是因为在同步数据的时候他只是**fork**了一个子进程去做持久化的,而且他在数据恢复的时候速度比**AOF**来的快
缺点:RDB都是快照文件,都是默认五分钟甚至更久的时间才会生成一次,这意味着你这次同步到下次同步这中间五分钟的数据都很可能全部丢失掉。AOF则最多丢一秒的数据。RDB在生成数据快照的时候,如果文件很大,客户端可能会暂停几毫秒甚至几秒
AOF
热备
AOF 机制对每条写入命令作为日志,以 append-only的模式写入一个日志文件中
优点:AOF在对日志文件进行操作的时候是以`append-only`的方式去写的,他只是追加的方式写数据,自然就少了很多磁盘寻址的开销
AOF是一秒一次去通过一个后台的线程`fsync`操作,那最多丢这一秒的数据操作,那最多丢这一秒的数据
缺点:一样的数据,**AOF**文件比**RDB**还要大
主从同步
你启动一台slave 的时候,他会发送一个psync命令给master ,如果是这个slave第一次连接到master,他会触发一个全量复制。master就会启动一个线程,生成RDB快照,还会把新的写请求都缓存在内存中,RDB文件生成后,master会将这个RDB发送给slave的,slave拿到之后做的第一件事情就是写进本地的磁盘,然后加载进内存,然后master会把内存里面缓存的那些新命名都发给slave
哨兵
哨兵+主从同步实现高可用集群
集群监控:负责监控Redis 的master和save是否运行正常
消息通知:如果某个Redis 实例有故障,那么哨兵负责发送消息作为报警通知给管理员
故障转移:如果 master node 挂掉了,会自动转移到 slave node 上
配置中心:如果故障转移发生了,通知 client 客户端新的 master 地址
内存淘汰机制
即过期策略
定期删除:默认100s就随机抽一些设置了过期时间的key,去检查是否过期,过期了就删了
惰性删除:等你来查询了我看看你过期没,过期就删了还不给你返回
定期没删,我也没查询,内存淘汰机制
实现原理:确保同一时间只有一个系统实例获取锁
最经典的KV、DB读写模式
读的时候,先读缓存,缓存没有的话,就读数据库,然后取出数据后放入缓存,同时返回响应
更新的时候,先更新数据库,然后再删除缓存
与mencache区别
Redis相比 **Memcached** 来说,拥有更多的数据结构,能支持更丰富的数据操作
redis3.x 版本中,便能支持 Cluster 模式,而 Memcached 没有原生的集群模式,需要依靠客户端来实现往集群中分片写入数据
Redis只使用单核,而 Memcached可以使用多核,所以平均每一个核上 Redis 在存储小数据时比 Memcached性能更高
学习思路
事前:Redis高可用:主从+哨兵+Redis cluster ,避免全盘崩盘
事中:本地缓存ehcache+限流组件+降级,避免数据库被打死
事后:RDB+AOF持久化,一旦重启,自动从磁盘上加装数据,快速恢复数据