Redis面试题总结
参考
https://blog.csdn.net/zdp072/article/details/50991116
https://blog.csdn.net/qq_34337272/article/details/80012284#commentBox
坑人无数的Redis面试题(未整理,写的很棒,超出了理论范围,结合实际中的问题,给出不错的解决方案) https://blog.csdn.net/u011405515/article/details/79190652
0 什么是Redis?
Redis 是一个使用 C 语言写成的,开源的,基于内存的 key-value 数据库。
支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set –有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。
与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。目前,Vmware在资助着redis项目的开发和维护。
1 使用redis有哪些好处?
速度快:因为数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1),每秒可以处理超过 10万次读写操作,是已知性能最快的Key-Value DB。支持丰富数据类型:支持string,list,set,sorted set,hash单个value的最大限制是1GB,不像 memcached只能保存1MB的数据
支持事务:操作不是原子性的,即使某些操作失败,也不会影响别的操作的执行丰富的特性:可用于缓存,按key设置过期时间,过期后将会自动删除
2 redis相比memcached有哪些优势?
memcached所有的值均是简单的字符串,redis作为其替代者,支持更为丰富的数据类型
redis的速度比memcached快很多
redis可以持久化其数据,也可以做数据备份
单个value的最大限制是1GB,不像 memcached只能保存1MB的数据
3 Redis与Memcached的区别与比较
Memcached:一款完全开源、高性能的、分布式的内存系统;
Redis:一个开源的、Key-Value型、基于内存运行并支持持久化的NoSQL数据库;
Memcached追求的高性能的内存服务;而Redis追求的不仅仅是内存运行,还有数据持久化的需求。
存储方式
Memecache把数据全部存在内存之中,断电后会挂掉,数据不能超过内存大小。
Redis有部份存在硬盘上,这样能保证数据的持久性(即master-slave模式的数据备份)。数据支持类型
Memcache对数据类型支持相对简单String。
Redis有复杂的数据类型:String,list,set,zset,hash。value大小
redis的value大小最大可以达到1GB,而memcache只有1MBMemcached是多线程,非阻塞IO复用的网络模型;Redis使用单线程的IO复用模型。
网络IO之间的对比:Memcached是多线程,非阻塞IO复用的网络模型,分为
监听主线程和worker子线程,监听线程监听网络连接,接受请求后,将连接描述字pipe传递给worker线程,进行读写IO,网络层使用libevent封装的事件库,多线程模型可以发挥多核作用,但是引入了cache coherency和锁的问题,比如:memcached最常用的stats命令,实际memcached所有操作都要对这个全局变量加锁,进行技术等工作,带来了性能损耗。Redis使用单线程的IO复用模型,自己封装了一个简单的AeEvent事件处理框架,主要实现了epoll, kqueue和select,对于单存只有IO操作来说,单线程可以将速度优势发挥到最大,但是redis也提供了一些简单的计算功能,比如排序、聚合等,对于这些操作,单线程模型施加会严重影响整体吞吐量,CPU计算过程中,整个IO调度都是被阻塞的。
redis利用队列技术将并发访问变为串行访问,消除了传统数据库串行控制的开销。基于以上的内容大致可以总结如下:
在高并发场景的压力下,多线程非阻塞式IO的Memcached表现会更加优异。过期删除策略的不同
memcached只是用了惰性删除,而redis同时使用了惰性删除与定期删除,这也是二者的一个不同点(可以看做是redis优于memcached的一点)详情见 Redis过期策略 实现原理
4 redis常见性能问题和解决方案:
Master最好不要做任何持久化工作,如RDB内存快照和AOF日志文件
如果数据比较重要,某个Slave开启AOF备份数据,策略设置为每秒同步一次(AOF有3种同步方式:1.每秒同步,2.每修改同步,3.不同步)
为了主从复制的速度和连接的稳定性,Master和Slave最好在同一个局域网内
尽量避免在压力很大的主库上增加从库
主从复制不要用图状结构,用单向链表结构更为稳定,即:Master <- Slave1 <- Slave2 <- Slave3…
这样的结构方便解决单点故障问题,实现Slave对Master的替换。如果Master挂了,可以立刻启用Slave1做Master,其他不变。
5 Redis与Memcached的选择
如果大家对持久化要求不高,更希望快速高效,建议大家优先考虑Memcached;
追求多类型支撑,持久化要求相对比较高的情况下,优先使用Redis;
使用Redis的String类型做的事,都可以用Memcached替换,以此换取更好的性能提升; 除此以外,优先考虑Redis;
6 Redis常见数据结构使用场景
6.1 String
常用命令: set,get,decr,incr,mget 等。1
String数据结构是简单的key-value类型,value其实不仅可以是String,也可以是
数字。常规key-value缓存应用;
计数功能的缓存:微博数,粉丝数等。
6.2 Hash
常用命令: hget,hset,hgetall 等。1
Hash是一个string类型的field和value(<key,value>)的映射表,hash特别适合用于存储对象。 比如我们可以Hash数据结构来存储用户信息,商品信息等等。
在做单点登录的时候,就是用这种数据结构存储用户信息,
以cookieId作为key,设置30分钟为缓存过期时间,能很好的模拟出类似session的效果。
6.3 List
常用命令: lpush,rpush,lpop,rpop,lrange等1
list就是链表,Redis list的应用场景非常多,也是Redis最重要的数据结构之一,比如微博的关注列表,粉丝列表,最新消息排行等功能都可以用Redis的list结构来实现。
Redis list的实现为一个双向链表,即可以支持反向查找和遍历,更方便操作,不过带来了部分额外的内存开销。
使用List的数据结构,可以做简单的消息队列的功能。另外还有一个就是,可以利用lrange命令,做基于redis的分页功能,性能极佳,用户体验好。
6.4 Set
常用命令: sadd,spop,smembers,sunion 等12
set对外提供的功能与list类似是一个列表的功能,特殊之处在于set是可以自动排重的(没有重复的数据)。
可以做全局去重的功能。为什么不用JVM自带的Set进行去重?因为我们的系统一般都是集群部署,使用JVM自带的Set,比较麻烦,难道为了一个做一个全局去重,再起一个公共服务,太麻烦了。
另外,就是利用交集、并集、差集等操作,可以计算共同喜好,全部的喜好,自己独有的喜好等功能。
6.5 Sorted Set
常用命令: zadd,zrange,z
原创不易,完成人机校验,阅读全文