Redis 具备「高性能」和「高并发」两种特性。
1.操作Redis缓存就是直接操作内存,速度相当快
2.直接访问 Redis 能够承受的请求是远远大于直接访问 MySQL 的
Redis 单线程指的是「接收客户端请求->解析请求 ->进行数据读写等操作->发送数据给客户端」
Redis 程序并不是单线程的,Redis 在启动的时候,是会启动后台线程(BIO)的
6.0启用了多线程来处理网络请求
为什么单线程还这么块:
1.Redis 的大部分操作都在内存中完成
2.采用单线程模型可以避免多线程的竞争
3.采用了I/O多路复用,一个线程处理多个IO
string(key-value) get/set:(适合计数,点赞,计时)
list:按照插入顺序排序:由双向链表,压缩列表实现:可以用作轻量级的消息队列,也可以用做缓存淘汰策略
hash的value可以存两个属性:哈希表(应用在三要素中,如ID,商品ID,数量)
Set 类型内部实现:由哈希表实现的(保证数据的唯一性和统计交集中)
ZSet 类型内部实现:是由跳表实现的(排行榜)
跳表:是一种加强版的排序链表,主要优点是可以提供对元素的单点快速访问,并且支持范围查询,相较于红黑树来说跳表更容易实现,且其扩展性更强可以通过加层来适应更大的数据集
- 多级索引:通过维护多个层来实现高效搜索能力,底层是一个普通的排序链表,在底层之上还有多个额外链表,每一层都是下一层的子集
- 搜索:从最高层链表开始
- 插入:在底层找到合适的位置进行插入
缓存雪崩:
数据过期
1.均匀设置过期时间
2.使用互斥锁,当缓存失效的时候不去直接load db,而是去设置一个锁来保证同一时间只有一个请求来load db。如果获取锁成功,在load db,否则就重试获取缓存.这个锁需要设置超时时间,避免拿到锁后因意外不释放
3.不设置有效期,交给后台更新缓存
不设置有效期不代表不会淘汰,当内存紧张的时候就会淘汰一些数据,然后当业务线程发现缓存数据失效后通过消息队列发送一条消息通知后台线程更新缓存
4.数据预热
预先把可能访问的数据加载到缓存中,从而减少运行的缓存雪崩
redis故障
1.启动服务熔断或者限流,保证数据库不被打崩
2.主从节点的方式构建 Redis 缓存高可靠集群,主节点故障就启动从节点
缓存击穿:热点数据过期
1.使用互斥锁
2.交给后台异步更新缓存
缓存穿透:不在缓存也不在数据库
1.非法请求限制
2.缓存设置空值或默认值
3.使用布隆过滤器快速判断数据是否存在吗,避免查询数据库,这样就算穿透大量请求只会查询 Redis 和布隆过滤器【位图数组+哈希函数组成,通过对数据进行哈希计算得到数组的对应位置并设置为1,检测的时候检测到0,就认为不存在】
Redis过期删除策略和内存淘汰策略
内存淘汰:
不淘汰:
淘汰:
有过期时间:TTL,random,LRU,LFU
无过期时间:random,LRU,LFU
持久化的方式:
AOF日志:每执行一条写操作命令,就把该命令以追加的方式写入到一个文件里
RDB快照:将某一时刻的内存数据,以二进制的方式写入磁盘