Redis为什么这么快?
- 基于内存,不会受到硬盘io速度的限制。
- 单线程,避免了多线程切换导致的io消耗,并且多线程的情况下会产生数据不一致问题,从而需要加锁导致性能消耗。
-
使用io多路复用模型。(io多路复用模型利用select,poll和epoll来监听多个io流事件,从而让单个线程来处理多个连接请求)
Redis为什么是单线程?
Redis是基于内存的操作,cpu不是redis的瓶颈,redis的瓶颈要么是内存大小要么是网络带宽。多线程的时候线程切换会消耗cpu的性能,并且多线程会导致数据不一致问题,需要加锁,从而造成性能消耗。
Redis什么时候会多进程?
Redis进行持久化的时候,系统会fork一个子进程来进行处理。linux使用fork产生的父子进程读时共享,写时复制。例如:一个变量在没有被修改的时候,父子进程访问的是同一份数据。但如果数据被修改后,那么这份数据会被存储两份,父子进程各拥有一份副本。
Redis的数据类型,底层数据结构以及使用场景?
1.string类型
- 底层结构(1.int: 8个字节长整型 2. embstr: 小于等于39个字节的字符串 3. raw: 大于39个字节的字符串)
- 使用场景(缓存功能,共享session)
2.list类型
- 底层结构(1.ziplist压缩列表[1.列表对象保存的所有字符串元素的长度小于64字节2.列表对象保存的元素数量小于512],2.likedlist链表)
- 使用场景(文章或者物品列表)
3.set类型
- 底层结构(1.inset[value为整数并数量小于512]2.dict字典)
- 使用场景(标签)
4.zset类型
- 底层结构(1.ziplist压缩列表[1.zset对象中字符串的长度小于64字节并且元素数量小于128] 2.skiplist跳表)
- (skiplist就是在链表的基础上加索引来实现,相当于空间换时间,增加和查找和删除的事件负责度为logn,每个结点按score进行排序,socre相同,就按照成员对象的大小进行排序)
- 使用场景(排行榜)
5.hash类型
- 底层结构(ziplist压缩列表[1.哈希对象保存的所有键值对的键和值的字符串长度小于64并且保存的键值对的数量小于512],hashtable哈希表)
- 对象存储(string也可以用于对象存储:1.key:用户id,value缓存的对象,这也需要对象的序列化和反序列化,并且操作也不方面2.将用户id和属性作为key来存储,这也会重复用户id存储,造成内存浪费。hash存储对象就可以解决这个问题。)
Redis过期策略和内存淘汰机制
Redis过期策略
定期删除(每隔100ms随机抽取key来检查和删除)和惰性删除(查找key的时候检查是否过期)
缺点:大量过期的key堆积在内存,导致内存耗尽。
Redis内存淘汰策略
noeviction:当内存不足以容纳新写入数据时,新写入操作会报错,这个一般没人用吧
allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的key
allkeys-random:当内存不足以容纳新写入数据时,在键空间中,随机移除某个key,这个一般没人用吧
volatile-lru:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,移除最近最少使用的key
volatile-random:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,随机移除某个key
volatile-ttl:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,有更早过期时间的key优先移除
Redis持久化方式?
1.RDB
RDB默认开启(在配置文件中配置rdb文件位置和触发方式)
触发机制:
- save 60 5 (60秒内key刷新5次)
- 执行flush all命令
- 退出redis
优点:
- 适合大规模数据恢复
- 对数据的完整性要求不高
缺点:
- 需要一定时间间隔操作,如果意外宕机,就会丢失最后一次修改的数据
- fork进程的时候会占用一定的内容空间
过程:
2.AOF
优点:
- 每一次修改都同步,文件完整性更好
- 每秒同步一次,可能会丢失一秒数据
- 从不同步,效率最高
缺点:
- 相对于数据文件来说,aof远远大于rdb,修复速度也比rdb慢
- aof运行效率比rdb慢,所以默认rdb持久化就是aof
哨兵模式和哨兵集群模式
哨兵作用:1.通过发送命令,让redis服务器返回运行状态,包括主服务器和从服务器。2.监测master宕机,自动将salve切换成master,然后通过发布订阅模式通过其他服务器,修改配置文件,切换主机。
哨兵集群:一个哨兵可能会出问题,多个哨兵相互监控更稳定。当一定数量的哨兵检测到master宕机,哨兵就会发起投票,进行故障转移,通过发布订阅模式让各个哨兵监控的服务器修改配置文件,切换主机。
优点:1.哨兵集群基于主从复制,主从配置优点都有。2.主从切换,自动故障转移,系统高可用。
缺点:1.redis不好在线扩容。2.哨兵模式配置很麻烦。
Redis缓存存在的问题:
缓存穿透(redis内存没有,mysql数据库也没有)
- 布隆过滤器(布隆过滤器是一种数据结构,对所有可能查询的参数以hash形式存储,在控制层进行校验,不符合规则丢弃)采用二进制数组,将可能的参数以多次hash形式存储,然后查询时搜索二进制数组是否都为1,如果是则可能存在。
- 缓存空对象(返回的空对象缓存起来,同时设置一个过期时间)[1.空值被缓存,意味着需要更多的空间存储更多的键2.空值设置过期时间,会导致缓存和存储层的数据在一段时间内数据不一致]
缓存雪崩(某个时间段,缓存集中过期,redis宕机)
- redis高可用
- 限流降级(rocketmq)
- 数据预热
缓存击穿(量太大,缓存过期)
- 设置热点数据永不过期
- 分布式锁(保证每个key同时只有一个线程去查询后端服务,其他线程没有获得分布式锁的权限