面试常问

1、什么是redis?

redis是一种用c语言编写的、开源的的Key-Value数据库,对于数据的操作完全基于内存、且支持数据的持久化。

2、redis为什么这么快?

 redis测试可达到10w+QPS,有以下几点原因。
    1、只操作内存。不需要读取、刷新磁盘,减少了IO的性能消耗。
    2、单线程操作。减少线程上下文切换带来的性能消耗。
    3、IO多路复用技术。通过epoll、select等多路复用技术,来处理大量的、多客户端的请求。
    4、优秀的底层数据结构。像string类型底层是SDS(简单动态字符串),hash类型底层是hash表,
list类型底层是quickList(ziplist + linkedList)等。

3、redis支持哪些数据类型?每个数据类型的应用场景你知道吗?

redis有5种基本类型和3种高级类型,分别是string、hash、list、set、zset、
Bitmaps、HyperLogLog、GEO。
 1、string:分布式session共享、用户登陆标识、短信验证码、分布式锁、计数器、分布式ID等。
 2、hash:多字段对象。
 3、list:消息队列。
 4、set:点赞人数、签到人数、标签、共同爱好、共同好友等需要去重的列表。
 5、zset:排行榜、带排序的好友列表等需要排序、去重功能的列表。
 6、Bitmaps:用户签到、活跃用户、用户在线状态、布隆过滤器等筛选类的统计。
 7、HyperLogLog:页面实时UV数、网站访问IP数等无需太过追求数值精确的统计。
 8、GEO:附近的人等涉及地理位置保存及计算距离的功能。

4、redis的发布(pub)/订阅(sub)功能有了解过吗?为什么一般不会用来做消息通知服务呢?

redis中定义了一个通道(channel)的概念,订阅者通过订阅该通道,接收生产者写入到该通道的消息。
发布/订阅相关的命令有:
  1、subscribe:订阅单个通道。
  2、unsubscribe:取消订阅单个通道。
  3、Psubscribe:根据匹配符订阅一个或多个通道。
  4、Punsubscribe:根据匹配符取消订阅一个或多个通道。
  5、publish:发布消息到通道。
  6、pubsub:查询所有活跃通道列表、或者根据匹配符查询活跃通道列表。

不能用来做消息通知服务的原因有:
  1、写入消息到通道后,如果没有订阅者,那么该消息就被直接丢弃。
  2、订阅者如果突然断开了,对于该订阅者,从断开到重连这段时间内产生的消息就彻底丢失了。
  3、redis如果宕机重启,宕机前未被消费的消息不会被持久化,会全部丢失。

5、为什么说redis的操作是原子性的?又怎么保证多个操作的原子性?

redis中原子性的理解是,一个操作不允许再分,要么执行、要么不执行。
redis操作是原子性的是因为redis对数据的读写是单线程的,不存在并发情况发生。多个操作要保证原子性。
可以使用redis的事务、或者Redis+Lua的方式。像分布式锁,就可以使用Redis+Lua的方式实现。

6、redis事务怎么实现的?有哪些特点?

redis提供了multi、exec、watch/unwatch、discard指令来操作事务:
 1、multi:开启事务。之后的操作都会加入到事务的操作队列中。
 2、exec:提交事务。执行事务操作队列中的所有操作。
 3、watch:监听。
   在事务开启前开启监听,事务提交时会检查所有被监听的key是否被其他客户端修改过,如果有修改,取消事务。
4、unwatch:取消监听。
事务被取消或者执行成功,所有被监听的key都会取消监听。
 5、discard:取消事务。

>工作原理:
其实就是将一系列的操作组成一个操作队列,由同一个客户端执行。
在开启事务之后,所有的非事务的操作指令都会被保存在该事务的操作队列中。在执行事务前,会先检查操作列表中
的指令是否有语法错误以及被watch的key是否有改动过,如果有,取消事务。如果都没有,将操作队列中的指令写入到AOF文件(```前提是开启了AOF```),开始执行操作队列中的指令。若执行出错,已经执行成功的指令不会回滚,后续的指令也会继续执行,全部执行完成后返回给客户端一个结果数组,表示每个操作的返回结果,最后对所有被watch的key进行unwatch操作。

> redis事务其实还有一个一种替代方案:Lua脚本,通过 EVAL 与 EVALSHA 命令,可以让 Redis 执行 LUA 脚本。例如:redis分布式锁就可以用这种方式来实现。

5、redis和Memcache的区别?
> ```1、储存方式不同。```redis除了将数据存放到内存中,还支持数据的持久化,而Memcache完全基于内存。程序发生异常挂掉或者服务器宕机,redis可以保证数据的安全性和完整性,而Memcache则完全丢失了所有数据。
> ```2、支持的数据结构不同。```redis支持string、hash、list、set、zset等丰富的数据结构来存储数据,而Memcache只支持简单的K-V数据。
> ```3、底层模型不同。```redis构建了自己的VM机制,为了避免某些系统调用系统函数时,会浪费比较多的时间去移动和请求。
> ```4、线程模型不同。```redis是单线程且使用了epoll这种IO多路复用技术,Memcache则是使用了多线程。在存储大于100k的数据时,Memcache效率稍高些。

6、redis的内存淘汰策略有哪些?什么是LRU?什么又是LFU?除了这两种,你还知道哪些淘汰算法吗?
> 到目前为止,redis一共实现了8种淘汰策略:
```1、noeviction(默认)```:当内存达到设置的最大值时,所有申请内存的操作都会报错(如set,lpush等),只读操作如get命令可以正常执行;
```2、volatile-ttl```:设置了过期时间的key根据过期时间淘汰,越早过期越早淘汰;
```3、volatile-lru```:设置了过期时间的key使用LRU算法淘汰;
```4、allkeys-lru```:所有key使用LRU算法淘汰;
```5、volatile-lfu```:设置了过期时间的key使用LFU算法淘汰;
```6、allkeys-lfu```:所有key使用LFU算法淘汰;
```7、volatile-random```:设置了过期时间的key使用随机淘汰;
```8、allkeys-random```:所有key使用随机淘汰;

> 目前淘汰算法有LRU、LFU、FIFO等。
 LRU:Least Recently Used(最近最少使用),如果数据最近被访问过,那么将来被访问的几率也更高。

redis中的实现:
在redisObject结构体中定义了一个24bit的unsigned类型的字段,用来存储对象最近一次被使用的时间戳lru。
当内存即将达到设置maxmemory的值时,采用随机算法取出maxmemory-samples(默认5)个key进行比较,将lru最小的key移除。
redis 3.0后对该算法进行了升级,维护一个候选池(pool),首次筛选出来的key放在候选池中,在后续筛选中,
只有lru小于池中最小的lru才会放入池子中,当候选池满了,如果还有新的key要进入,那么将候选池中最大的lru的key取出来。
当内存即将达到设置maxmemory的值时,只需要移除掉候选池中lru最小的key即可。


> LFU:全称叫Least frequently used(最近不经常使用),如果一个数据在最近一段时间内使用次数很少,那么在将来一段时间内被使用的可能性也很小。

redis中的实现:
在lru的基础上,lfu做出了改进,引入了频率值couter的概念。
同样是24bit的unsigned类型的字段,在lfu算法下,前16bit用来保存key的最后一次访问的时间,精确为分钟,
而剩下的8bit用来保存一个频率值couter。
当couter越小,它的增长率越快,越大,增长率越慢。当内存即将达到设置maxmemory的值时,会把当前时间与
最后访问时间lru的差除以衰减因素来确定要减去的couter,小于该conter的key将会被移除。



7、redis的持久化方式有哪些?各有什么特点?
> redis的持久化有两种,分别是RDB(redis database)和AOF(append only file)。

RDB的工作原理将redis在内存中的数据以一定的频率刷新到磁盘中。实际操作是fork出一个子进程,现将数据写入一个临时文件dump,写入成功后,再替换之前的文件,用二进制压缩存储。
AOF的工作原理是以日志的形式记录redis的每一个写操作,将记录写入到日志文本中。


8、redis的主从复制有了解吗?全量复制和部分复制的区别?能大概说下全量复制和部分复制的过程吗?
9、什么是哨兵模式?工作原理是什么?
10、redis集群方案有哪些?你们项目中使用的是哪种,怎么实施的?
11、缓存穿透、缓存击穿、缓存雪崩分别描述的是哪些业务场景?谈谈你的理解,以及你的解决方案?
12、redis作为数据缓存使用时,无法避免会出现缓存一致性问题,有什么好的解决方案?
13、redis怎么实现分布式锁,与zookeeper分布式锁的区别是什么?
14、在你的项目中是怎么使用redis的?都使用了哪些功能?
15、商品秒杀功能用redis来实现,你觉得最好的方案是什么?


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343

推荐阅读更多精彩内容