# Redis理论类知识总结
<font style="background:yellow">
<font style="background: MediumSpringGreen">
2
# 目录
[TOC]
常见NoSQL的安装踩坑记录,《Redis设计与实现》笔记
- Redis:REmote DIctionary Server(远程字典服务器)
# 面试题
# redis有哪些对象?请问Redis的数据类型有哪些,底层怎么实现?
- 1)字符串(string):整数值、embstr编码的简单动态字符串、简单动态字符串(SDS)
- 2)列表(list):压缩列表、双端链表
- 3)哈希(hash):压缩列表、字典
- 4)集合(set):整数集合、字典
- 5)有序集合(zset):压缩列表、跳跃表和字典
# 请你说一说Redis对应的命令和数据类型.
key操作常用命令:del,exists,expire,rename
string 操作常用命令:set get incr decr del apend
hash 操作常用命令:hset hget hdel
list 操作常用命令:lpush rpush lpop rpop lset lindex
set 操作常用命令:sadd srem sunion sdiff sinter
zset 操作常用命令:zadd zrem
参考:牛客网
# 什么是缓存雪崩、缓存击穿、缓存穿透?
Redis作为目前使用最广泛的缓存,相信大家都不陌生。
但是使用缓存并没有这么简单,还要考虑缓存雪崩,缓存击穿,缓存穿透的问题
# 缓存雪崩(cache avalanche)「多个key访问+大规模失效」
- 表示大量缓存都失效了,像雪崩一样。
当某一个时刻出现大规模的缓存失效的情况,那么就会导致大量的请求直接打在数据库上面,导致数据库压力巨大,如果在高并发的情况下,可能瞬间就会导致数据库宕机。
这时候如果运维马上又重启数据库,马上又会有新的流量把数据库打死。这就是缓存雪崩。
造成缓存雪崩的关键在于在同一时间大规模的key失效。为什么会出现这个问题呢,有几种可能,
第一种可能是Redis宕机,第二种可能是采用了相同的过期时间。搞清楚原因之后,那么有什么解决方案呢?
# 缓存击穿?(hotspot invalid)「某1个key被同事大量访问+失效」
==hotspot invalid明明翻译过来是热点失效==,硬是凑一组翻译成缓冲击穿..
表示缓存数据失效了。和cache penetration(缓存穿透)的区别是缓存的key还是存在的,只是这个key的数据失效了
其实跟缓存雪崩有点类似,缓存雪崩是大规模的key失效,而缓存击穿是一个热点的Key,有大并发集中对其进行访问,突然间这个Key失效了,导致大并发全部打在数据库上,导致数据库压力剧增。这种现象就叫做缓存击穿。
# 缓存穿透?(cache penetration)表示程序要访问的缓存key不在缓存key的==取值范围==里。
我们使用Redis大部分情况都是通过Key查询对应的值,假如发送的请求传进来的key是不存在Redis中的,那么就查不到缓存,查不到缓存就会去数据库查询。假如有大量这样的请求,这些请求像“穿透”了缓存一样直接打在数据库上,这种现象就叫做缓存穿透。
==关键在于在Redis查不到key值,这和缓存击穿有根本的区别==,区别在于缓存穿透的情况是传进来的key在Redis中是不存在的。假如有黑客传进大量的不存在的key,那么大量的请求打在数据库上是很致命的问题,所以在日常开发中要对参数做好校验,一些非法的参数,不可能存在的key就直接返回错误提示,要对调用方保持这种“不信任”的心态。
解决方案:
1、把无效的Key存进Redis中。如果Redis查不到数据,数据库也查不到,我们把这个Key值保存进Redis,设置value="null",当下次再通过这个Key查询时就不需要再查询数据库。这种处理方式肯定是有问题的,假如传进来的这个不存在的Key值每次都是随机的,那存进Redis也没有意义。
2、使用==布隆过滤器==。布隆过滤器的作用是某个 key 不存在,那么就一定不存在,它说某个 key 存在,那么很大可能是存在(存在一定的误判率)。于是我们可以在缓存之前再加一层布隆过滤器,在查询的时候先去布隆过滤器查询 key 是否存在,如果不存在就直接返回。
这三个问题==在使用Redis的时候是肯定会遇到的,而且是非常致命性的问题==,所以在日常开发中一定要注意,每次使用Redis时,都要对其保持严谨的态度。还有一个需要注意的是要做好熔断,一旦出现缓存雪崩,击穿,穿透这种情况,至少还有熔断机制保护数据库不会被打死。
# 记忆技巧:
缓存雪崩很形象了,就是大量key没了,请求像雪崩一样打到数据库;
缓存击穿也挺形象,就是单个key没了,但是它是热点,redis这个盾没防住,大量针对一个key的请求像剑一样刺向数据库;
缓存穿透就很好理解了, 穿透了嘛,数据库里也没这个数据,连数据库也一起透心凉心飞扬!
# 1.请你回答一下2种NoSQL的区别mongodb和redis
- 内存管理机制上:
Redis 数据
全部存在内存,定期写入磁盘,当内存不够时,可以选择指定的 LRU 算法删除数据。
MongoDB 数据存在内存,由 linux系统 mmap 实现,当内存不够时,只将热点数据放入内存,其他数据存在磁盘。
- 支持的数据结构上:
Redis 支持的数据结构丰富,包括hash、set、list等。
MongoDB 数据结构比较单一,但是支持丰富的数据表达
,索引,最类似关系型数据库,支持的查询语言非常丰富
# 2.请你来说一下Redis和memcached的区别?
Memcached是一个自由开源的,高性能,分布式内存对象缓存系统。
Memcached的菜鸟教程 (opens new window)
1)数据类型 :
- redis数据类型丰富,支持set liset等类型;
- memcache支持简单数据类型,需要客户端自己处理复杂对象
2)持久性:
- redis支持数据落地持久化存储;
- memcache不支持数据持久存储。
3)分布式存储:
- redis支持master-slave复制模式;
- memcache可以使用一致性hash做分布式。
4)value大小不同:
- memcache是一个内存缓存,key的长度小于250字符,单个item存储要小于1M,不适合虚拟机使用
5)数据一致性不同:
- redis使用的是单线程模型,保证了数据按顺序提交;
- memcache需要使用cas保证数据一致性。CAS(Check and Set)是一个确保并发一致性的机制,属于“乐观锁”范畴;原理很简单:拿版本号,操作,对比版本号,如果一致就操作,不一致就放弃任何操作
6)cpu利用:
- redis单线程模型只能使用一个cpu,可以开启多个redis进程
# 5.2.请你来说一说Redis的定时机制怎么实现的
Redis服务器是一个事件驱动程序,服务器需要处理以下两类事件:
- 文件事件(服务器对套接字操作的抽象)
- 时间事件(服务器对定时操作的抽象)。Redis的定时机制就是借助时间事件实现的。
一个时间事件主要由以下三个属性组成:
- id:时间事件标识号;
- when:记录时间事件的到达时间;
- timeProc:时间事件处理器,当时间事件到达时,服务器就会调用相应的处理器来处理时间。一个时间事件根据时间事件处理器的返回值来判断是定时事件还是周期性事件
# 5.3.请你来说一说Redis是单线程的,但是为什么这么高效呢?
虽然Redis文件事件处理器以单线程方式运行,但是通过使用I/O多路复用程序来监听多个套接字,文件事件处理器既实现了高性能的网络通信模型,又可以很好地与Redis服务器中其他同样以单线程运行的模块进行对接,这保持了Redis内部单线程设计的简单性。
单个reactor?
# 5.4.请自己设计一下如何采用单线程的方式处理高并发
在单线程模型中,可以采用I/O复用来提高单线程处理多个请求的能力,然后再采用事件驱动模型,基于异步回调来处理事件来
# 5.6.请问Redis的rehash怎么做的,为什么要渐进rehash,渐进rehash又是怎么实现的?
因为redis是单线程,当K很多时,如果一次性将键值对全部rehash,庞大的计算量会影响服务器性能,甚至可能会导致服务器在一段时间内停止服务。不可能一步完成整个rehash操作,所以redis是分多次、渐进式的rehash。渐进性哈希分为两种:
- 1)操作redis时,额外做一步rehash
对redis做读取、插入、删除等操作时,会把位于table[dict->rehashidx]位置的链表移动到新的dictht中,然后把rehashidx做加一操作,移动到后面一个槽位。
- 2)后台定时任务调用rehash
后台定时任务rehash调用链,同时可以通过server.hz控制rehash调用频率
# redis分布式锁
# 怎么保证redis和数据库一致性
# 1.旁路缓存
# 2.缓存
# 聊聊Redis的数据热点问题
什么是Redis热点?
数据热点就是数据访问局部性的体现,具体表现就是Redis中某个Key的访问频次远大于其他剩余的Key,我们也有一句俗语来形容这种现象旱的旱死,涝的涝死
我们来举个简单的例子,相信大家都在微博上吃过瓜,当有大瓜出现时,微博上会迅速涌入一批用户检索相关信息,疯狂访问同一份微博(数据),这种情况下这份数据就是热点数据,如果数据太“热”最终会导致微博挂掉,实际上微博挂掉的情况已经出现很多次了,不是因为微博技术不行,而是因为热点问题太可怕。
作者:xindoo 链接:https://juejin.cn/post/7142136519774437390
# Redis热点如何避免?
上文也说到,热点问题其实是局部性问题,而局部性问题的避免其实非常难,任何分布式系统几乎都会受局部性的影响。面对这种问题,说实话没有绝对可以避免的方式,只能提前通过分析数据的特性,做好相应的措施。说白了就是靠经验,不知道大家有啥其他好的思路,可以在评论区探讨下。
- 你项目里用到了redis,说下你怎么用redis的,redis还有哪些具体应用场景
- redis的持久化有哪些方式
- aof和rdb分别有什么优势和缺点,实际应用场景怎么选择
- redis是单线程,为什么性能还这么好,说具体一点
# 说一下redis实现的session分布式登录,能不能从源码角度说一下
# redis实现分布式锁,存在什么问题,怎么解决
# 参考资料
- Redis中文网站 (opens new window)
- Redis英文官网 (opens new window)
- 《Redis设计与实现》
- Redis精讲,狂神说