面试题—Redis篇

1、Redis是什么?

 

 

  • NoSql数据库、内存数据库;key-value形式存储,存储在内存上;优点是结构简单速度快

2、Redis有哪几种数据类型?

  • String:热点数据
  • HashTable:热点数据、用户信息、视频信息
  • LinkedList:微博时间轴
  • Set:标签、点赞、收藏、关注
  • ZSet:排行榜

3、利用redis的bitmap实现用户签到、统计活跃用户、用户在线状态

  • Redis从2.2.0版本开始新增了setbit,getbit,bitcount等几个bitmap相关命令。虽然是新命令,但是并没有新增新的数据类型,因为setbit等命令只不过是在set上的扩展。
<?php
//计算offset
$offset = floor(($todayTime - $startTime) / 86400);
//签到:一年一个用户会占用多少空间呢?大约365/8=45.625个字节,好小,有木有被惊呆?
$redis->setBit($cacheKey, $offset, 1);
//查询签到情况
$bitStatus = $redis->getBit($cacheKey, $offset);
//计算总签到次数
echo $redis->bitCount($cacheKey) . PHP_EOL;

4、微信微博点赞、收藏、标签、关注(使用HashMap数据结构)

  • 用户某篇文章的点赞数:HashMap中的keyarticleIdvalueSetSet中的值为用户ID,即HashMap<String, Set<String>>
  • 用户总的点赞数:HashMap中的keyuserIdvalueString记录总的点赞数
  • 用户点赞、收藏的文章:HashMap中的keyuserIdvalueSetSet中的值为文章ID,即HashMap<String, Set<String>>
  • 标签、关注功能HashMap中的keyuserIdvalueSetSet中的值为标签,即HashMap<String, Set<String>>

5、Redis命令

  • 用于查找所有符合给定模式 pattern 的 key:KEYS PATTERN(比如KEYS runoob*)
  • 如果Redis有1亿个key,使用keys命令是否会影响线上服务?执行keys命令,redis会锁定,如果数据庞大的话可能需要几秒或更长,对于生产服务器上锁定几秒这绝对是灾难了

6、Redis缓存穿透和缓存雪崩是什么?

  • 缓存穿透:redis中没有需要去查数据库;这个正常时候是没问题的,但是被黑客利用发送大量空请求会导致数据库宕机;解决方案是增加布隆过滤器或者缓存空对象
  • 缓存雪崩:大量key同一时间点全部失效,同时又有大量请求打进来,导致流量直接打在DB上,造成DB不可用。

7、MySQL里有2000w数据,redis中只存20w的数据,如何保证redis中的数据都是热点数据?

  • Redis有过期删除策略和内存淘汰机制(针对未设置过期时间的key)

8、过期删除策略

  • 立即删除:过期立马删除,弊端是cpu繁忙给cpu增加了压力
  • 惰性删除:下次使用时发现过期删除
  • 定期删除:每个一段时间执行一次删除

9、内存淘汰管理机制

  • no-enviction(驱逐):禁止驱逐数据
  • 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)中任意选择数据淘汰

10、数据可靠性:持久化机制

  • 为什么需要持久化:Redis数据存在内存中,如果没有配置持久化,redis重启后数据就全丢失了,于是需要开启redis的持久化功能,将数据保存到磁盘上,当redis重启后,可以从磁盘中恢复数据
  • 持久化方式:快照持久化RDB、追加日志持久化AOF文件
  • RDB快照文件:save和bgsave命令打快照;优点是全量备份,缺点时持久化期间可能存在数据丢失
  • AOF命令文件:保存每个命令;aof文件太大会进行瘦身;优点是可靠性高,缺点是aof文件太大,且启动aof会,qps会下降

11、数据一致性

  • 数据库处理强一致性数据,redis不处理强一致性数据;
  • 读写策略:读数据先读redis;写数据,高并发直接写rediscover,定期刷新到redis,非高并发的话先写数据库在刷新到redis

12、Redis集群策略

  • 单机模式:
  • 主从复制:一个master多个slave
  • 哨兵模式:监听者机制(与zookeeper一样),master下线后自动进行故障转移、通知
  • 集群模式:proxy型与直连型

13、redis是多线程还是单线程?

redis中io多路复用器模块是单线程执行,事件处理器也是单线程执行,两个线程不一样。所以实际redis应该是单进程多线程,只是不同的模块都用的单线程实现。(redis4.0以前所有模块是单线程的,4.0以后是异步删除模块和6.0的I/O读写是多线程的)两个维度来举例:

  • 若是client发送命令到server的话,server处理命令是单线程逐条进行的。
  • server内部可以是多线程的,比如aof持久化,假设策略每秒,那就是再单独开启一个线程去执行aof文件持久化操作,这就是多线程了。

14、Redis主线程既然是单线程,为什么还这么快?

基于内存操作、数据结构简单、多路复用和非阻塞IO、避免上下文切换

15、Redis6.0的多线程?

Redis4.0引入了多线程,但4.0的多线程只支持大数量的异步删除。6.0中引入的多线程用于提高IO的读写能力,主要实现思路是将主线程的IO读写任务拆分给一组独立的线程去执行,这样就可以使用多个socket的读写并行化了,但Redis的命令依然是主线程串行执行的

16、Redis的多路复用是什么?

socket的读写方法默认是阻塞的,Redis的非阻塞IO是指IO的读写流程不再是阻塞的,读写方法都是瞬间完成并且返回的,也就是它会采用能读多少就读多少、能写多少就写多少的策略来执行IO操作。非阻塞的IO也面临一个问题,那就是当执行读写操作时,有可能只读写了一部分数据,那么生效的数据何时写就成了一个问题。而IO的多路复用就是解决上面的这个问题的,使用IO多路复用最简单的方式就是使用select函数此函数是操作系统提供给用户程序的API接口,用于监控多个文件描述符的可读和可写情况的,这样就可以监控到文件描述符的读写事件了。当监控到相应的时间之后就可以通知线程处理相应的业务了,这样就保证了Redis读写功能的正常执行。

【不过现在的操作系统已经基本上不适用select函数了,改为调用epoll函数(Linux)了,macOS则是使用Kqueue(继承与Unix),因为select函数在文件描述符非常多的时候性能非常差。】

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值