一、使用redis有哪些好处?node
速度快,由于数据存在内存中,相似于HashMap,HashMap的优点就是查找和操做的时间复杂度都是O(1)
支持丰富数据类型,支持string,list,set,sorted set,hash
支持事务,操做都是原子性,所谓的原子性就是对数据的更改要么所有执行,要么所有不执行
丰富的特性:可用于缓存,消息,按key设置过时时间,过时后将会自动删除
二、redis相比memcached有哪些优点?面试
memcached全部的值均是简单的字符串,redis做为其替代者,支持更为丰富的数据类型
redis的速度比memcached快不少
redis能够持久化其数据
三、redis常见性能问题和解决方案:redis
Master最好不要作任何持久化工做,如RDB内存快照和AOF日志文件
若是数据比较重要,某个Slave开启AOF备份数据,策略设置为每秒同步一次
为了主从复制的速度和链接的稳定性,Master和Slave最好在同一个局域网内
尽可能避免在压力很大的主库上增长从库
主从复制不要用图状结构,用单向链表结构更为稳定,即:Master <- Slave1 <- Slave2 <- Slave3...
这样的结构方便解决单点故障问题,实现Slave对Master的替换。若是Master挂了,能够马上启用Slave1作Master,其余不变。数据库
四、redis 最适合的场景后端
Redis最适合全部数据in-momory的场景,虽然Redis也提供持久化功能,但实际更多的是一个disk-backed的功能,跟传统意义上的持久化有比较大的差异,那么可能你们就会有疑问,彷佛Redis更像一个增强版的Memcached,那么什么时候使用Memcached,什么时候使用Redis呢?缓存
若是简单地比较Redis与Memcached的区别,大多数都会获得如下观点:安全
Redis不只仅支持简单的k/v类型的数据,同时还提供list,set,zset,hash等数据结构的存储。
Redis支持数据的备份,即master-slave模式的数据备份。
Redis支持数据的持久化,能够将内存中的数据保持在磁盘中,重启的时候能够再次加载进行使用。
(1)会话缓存(Session Cache) 最经常使用的一种使用Redis的情景是会话缓存(session cache)。用Redis缓存会话比其余存储(如Memcached)的优点在于:Redis提供持久化。当维护一个不是严格要求一致性的缓存时,若是用户的购物车信息所有丢失,大部分人都会不高兴的,如今,他们还会这样吗? 幸运的是,随着 Redis 这些年的改进,很容易找到怎么恰当的使用Redis来缓存会话的文档。甚至广为人知的商业平台Magento也提供Redis的插件。服务器
(2)全页缓存(FPC) 除基本的会话token以外,Redis还提供很简便的FPC平台。回到一致性问题,即便重启了Redis实例,由于有磁盘的持久化,用户也不会看到页面加载速度的降低,这是一个极大改进,相似PHP本地FPC。 再次以Magento为例,Magento提供一个插件来使用Redis做为全页缓存后端。 此外,对WordPress的用户来讲,Pantheon有一个很是好的插件 wp-redis,这个插件能帮助你以最快速度加载你曾浏览过的页面。网络
(3)队列 Reids在内存存储引擎领域的一大优势是提供 list 和 set 操做,这使得Redis能做为一个很好的消息队列平台来使用。Redis做为队列使用的操做,就相似于本地程序语言(如Python)对 list 的 push/pop 操做。 若是你快速的在Google中搜索“Redis queues”,你立刻就能找到大量的开源项目,这些项目的目的就是利用Redis建立很是好的后端工具,以知足各类队列需求。例如,Celery有一个后台就是使用Redis做为broker,你能够从这里去查看。session
(4)排行榜/计数器 Redis在内存中对数字进行递增或递减的操做实现的很是好。集合(Set)和有序集合(Sorted Set)也使得咱们在执行这些操做的时候变的很是简单,Redis只是正好提供了这两种数据结构。因此,咱们要从排序集合中获取到排名最靠前的10个用户–咱们称之为“user_scores”,咱们只须要像下面同样执行便可: 固然,这是假定你是根据你用户的分数作递增的排序。若是你想返回用户及用户的分数,你须要这样执行: ZRANGE user_scores 0 10 WITHSCORES Agora Games就是一个很好的例子,用Ruby实现的,它的排行榜就是使用Redis来存储数据的,你能够在这里看到。
(5)发布/订阅 最后(但确定不是最不重要的)是Redis的发布/订阅功能。发布/订阅的使用场景确实很是多。我已看见人们在社交网络链接中使用,还可做为基于发布/订阅的脚本触发器,甚至用Redis的发布/订阅功能来创建聊天系统!(不,这是真的,你能够去核实)。
Redis提供的全部特性中,我感受这个是喜欢的人最少的一个,虽然它为用户提供若是此多功能。
五、redis的一些其余特色
(1)Redis是单进程单线程的 redis利用队列技术将并发访问变为串行访问,消除了传统数据库串行控制的开销
(2)读写分离模型 经过增长Slave DB的数量,读的性能能够线性增加。为了不Master DB的单点故障,集群通常都会采用两台Master DB作双机热备,因此整个集群的读和写的可用性都很是高。 读写分离架构的缺陷在于,无论是Master仍是Slave,每一个节点都必须保存完整的数据,若是在数据量很大的状况下,集群的扩展能力仍是受限于单个节点的存储能力,并且对于Write-intensive类型的应用,读写分离架构并不适合。
(3)数据分片模型 为了解决读写分离模型的缺陷,能够将数据分片模型应用进来。 能够将每一个节点当作都是独立的master,而后经过业务实现数据分片。 结合上面两种模型,能够将每一个master设计成由一个master和多个slave组成的模型。
(4)Redis的回收策略
volatile-lru:从已设置过时时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰
volatile-ttl:从已设置过时时间的数据集(server.db[i].expires)中挑选将要过时的数据淘汰
volatile-random:从已设置过时时间的数据集(server.db[i].expires)中任意选择数据淘汰
allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰
allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰
no-enviction(驱逐):禁止驱逐数据
注意这里的6种机制,volatile和allkeys规定了是对已设置过时时间的数据集淘汰数据仍是从所有数据集淘汰数据,后面的lru、ttl以及random是三种不一样的淘汰策略,再加上一种no-enviction永不回收的策略。
使用策略规则:
若是数据呈现幂律分布,也就是一部分数据访问频率高,一部分数据访问频率低,则使用allkeys-lru
若是数据呈现平等分布,也就是全部的数据访问频率都相同,则使用allkeys-random
六、mySQL里有2000w数据,redis中只存20w的数据,如何保证redis中的数据都是热点数据
相关知识:redis 内存数据集大小上升到必定大小的时候,就会施行数据淘汰策略。redis提供6种数据淘汰策略见上面一条
七、假如Redis里面有1亿个key,其中有10w个key是以某个固定的已知的前缀开头的,若是将它们所有找出来?
使用keys指令能够扫出指定模式的key列表。
对方接着追问:若是这个redis正在给线上的业务提供服务,那使用keys指令会有什么问题?
这个时候你要回答redis关键的一个特性:redis的单线程的。keys指令会致使线程阻塞一段时间,线上服务会停顿,直到指令执行完毕,服务才能恢复。这个时候可使用scan指令,scan指令能够无阻塞的提取出指定模式的key列表,可是会有必定的重复几率,在客户端作一次去重就能够了,可是总体所花费的时间会比直接用keys指令长。
八、Redis 常见的性能问题都有哪些?如何解决?
Master写内存快照,save命令调度rdbSave函数,会阻塞主线程的工做,当快照比较大时对性能影响是很是大的,会间断性暂停服务,因此Master最好不要写内存快照。
Master AOF持久化,若是不重写AOF文件,这个持久化方式对性能的影响是最小的,可是AOF文件会不断增大,AOF文件过大会影响Master重启的恢复速度。Master最好不要作任何持久化工做,包括内存快照和AOF日志文件,特别是不要启用内存快照作持久化,若是数据比较关键,某个Slave开启AOF备份数据,策略为每秒同步一次。
Master调用BGREWRITEAOF重写AOF文件,AOF在重写的时候会占大量的CPU和内存资源,致使服务load太高,出现短暂服务暂停现象。
Redis主从复制的性能问题,为了主从复制的速度和链接的稳定性,Slave和Master最好在同一个局域网内
九、Redis有哪些数据结构?
字符串String、字典Hash、列表List、集合Set、有序集合SortedSet。
若是你是Redis中高级用户,还须要加上下面几种数据结构HyperLogLog、Geo、Pub/Sub。
若是你说还玩过Redis Module,像BloomFilter,RedisSearch,Redis-ML,面试官得眼睛就开始发亮了。
十、使用过Redis分布式锁么,它是什么回事?
先拿setnx来争抢锁,抢到以后,再用expire给锁加一个过时时间防止锁忘记了释放。
这时候对方会告诉你说你回答得不错,而后接着问若是在setnx以后执行expire以前进程意外crash或者要重启维护了,那会怎么样?
这时候你要给予惊讶的反馈:唉,是喔,这个锁就永远得不到释放了。紧接着你须要抓一抓本身得脑壳,故做思考片刻,好像接下来的结果是你主动思考出来的,而后回答:我记得set指令有很是复杂的参数,这个应该是能够同时把setnx和expire合成一条指令来用的!对方这时会显露笑容,内心开始默念:摁,这小子还不错。
十一、使用过Redis作异步队列么,你是怎么用的?
通常使用list结构做为队列,rpush生产消息,lpop消费消息。当lpop没有消息的时候,要适当sleep一会再重试。
若是对方追问可不能够不用sleep呢?list还有个指令叫blpop,在没有消息的时候,它会阻塞住直到消息到来。
若是对方追问能不能生产一次消费屡次呢?使用pub/sub主题订阅者模式,能够实现1:N的消息队列。
若是对方追问pub/sub有什么缺点?在消费者下线的状况下,生产的消息会丢失,得使用专业的消息队列如rabbitmq等。
若是对方追问redis如何实现延时队列?我估计如今你很想把面试官一棒打死若是你手上有一根棒球棍的话,怎么问的这么详细。可是你很克制,而后神态自若的回答道:使用sortedset,拿时间戳做为score,消息内容做为key调用zadd来生产消息,消费者用zrangebyscore指令获取N秒以前的数据轮询进行处理。
到这里,面试官暗地里已经对你竖起了大拇指。可是他不知道的是此刻你却竖起了中指,在椅子背后。
十二、若是有大量的key须要设置同一时间过时,通常须要注意什么?
若是大量的key过时时间设置的过于集中,到过时的那个时间点,redis可能会出现短暂的卡顿现象。通常须要在时间上加一个随机值,使得过时时间分散一些。
1三、为何Redis须要把全部数据放到内存中?
Redis为了达到最快的读写速度将数据都读到内存中,并经过异步的方式将数据写入磁盘。因此redis具备快速和数据持久化的特征。若是不将数据放在内存中,磁盘I/O速度为严重影响redis的性能。在内存愈来愈便宜的今天,redis将会愈来愈受欢迎。 若是设置了最大使用的内存,则数据已有记录数达到内存限值后不能继续插入新值。
1四、Redis 持久化机制
bgsave作镜像全量持久化,aof作增量持久化。由于bgsave会耗费较长时间,不够实时,在停机的时候会致使大量丢失数据,因此须要aof来配合使用。在redis实例重启时,会使用bgsave持久化文件从新构建内存,再使用aof重放近期的操做指令来实现完整恢复重启以前的状态。
对方追问那若是忽然机器掉电会怎样?取决于aof日志sync属性的配置,若是不要求性能,在每条写指令时都sync一下磁盘,就不会丢失数据。可是在高性能的要求下每次都sync是不现实的,通常都使用定时sync,好比1s1次,这个时候最多就会丢失1s的数据。
对方追问bgsave的原理是什么?你给出两个词汇就能够了,fork和cow。fork是指redis经过建立子进程来进行bgsave操做,cow指的是copy on write,子进程建立后,父子进程共享数据段,父进程继续提供读写服务,写脏的页面数据会逐渐和子进程分离开来。
1五、Redis提供了哪几种持久化方式?
RDB持久化方式可以在指定的时间间隔能对你的数据进行快照存储。
AOF持久化方式记录每次对服务器写的操做,当服务器重启的时候会从新执行这些命令来恢复原始的数据,AOF命令以redis协议追加保存每次写的操做到文件末尾。Redis还能对AOF文件进行后台重写,使得AOF文件的体积不至于过大。
若是你只但愿你的数据在服务器运行的时候存在,你也能够不使用任何持久化方式。
你也能够同时开启两种持久化方式, 在这种状况下, 当redis重启的时候会优先载入AOF文件来恢复原始的数据,由于在一般状况下AOF文件保存的数据集要比RDB文件保存的数据集要完整。
最重要的事情是了解RDB和AOF持久化方式的不一样,让咱们以RDB持久化方式开始。
1六、如何选择合适的持久化方式?
通常来讲, 若是想达到足以媲美PostgreSQL的数据安全性, 你应该同时使用两种持久化功能。若是你很是关心你的数据, 但仍然能够承受数分钟之内的数据丢失,那么你能够只使用RDB持久化。
有不少用户都只使用AOF持久化,但并不推荐这种方式:由于定时生成RDB快照(snapshot)很是便于进行数据库备份, 而且 RDB 恢复数据集的速度也要比AOF恢复的速度要快,除此以外, 使用RDB还能够避免以前提到的AOF程序的bug。
1七、Pipeline有什么好处,为何要用pipeline?
能够将屡次IO往返的时间缩减为一次,前提是pipeline执行的指令之间没有因果相关性。使用redis-benchmark进行压测的时候能够发现影响redis的QPS峰值的一个重要因素是pipeline批次指令的数目。
1八、Redis的同步机制了解么?
Redis可使用主从同步,从从同步。第一次同步时,主节点作一次bgsave,并同时将后续修改操做记录到内存buffer,待完成后将rdb文件全量同步到复制节点,复制节点接受完成后将rdb镜像加载到内存。加载完成后,再通知主节点将期间修改的操做记录同步到复制节点进行重放就完成了同步过程。
1九、Redis 集群方案与实现
Redis Sentinal着眼于高可用,在master宕机时会自动将slave提高为master,继续提供服务。
Redis Cluster着眼于扩展性,在单个redis内存不足时,使用Cluster进行分片存储。
20、一个Redis实例最多能存放多少的keys?List、Set、Sorted Set他们最多能存放多少元素?
理论上Redis能够处理多达232的keys,而且在实际中进行了测试,每一个实例至少存放了2亿5千万的keys。咱们正在测试一些较大的值。
任何list、set、和sorted set均可以放232个元素。
换句话说,Redis的存储极限是系统中的可用内存值。
2一、Redis持久化数据和缓存怎么作扩容?
若是Redis被当作缓存使用,使用一致性哈希实现动态扩容缩容。若是Redis被当作一个持久化存储使用,必须使用固定的keys-to-nodes映射关系,节点的数量一旦肯定不能变化。不然的话(即Redis节点须要动态变化的状况),必须使用能够在运行时进行数据再平衡的一套系统,而当前只有Redis集群能够作到这样。