Redis面试题

一、Redis对比memcached有哪些优势?

  • redis的类型有5大类,分别是string、list、set、sorted set、hash,而memcached只有string一种类型
  • redis数据存储在内存,但是可以持久化,可通过RDB或者AOF的方式持久化数据,RDB方式持久化会生成一个压缩过的二进制文件,它将所有的内存中的数据都保存在该文件中,redis.conf文件提供了RDB方式的三种同步机制,
    save 900 1
    save 300 10
    save 60 10000
    分别表示当在900秒之内对数据库进行了至少1次修改,在300秒之内对数据库进行了至少10次修改,在60秒之内对数据库至少进行了10000次修改,就会触发BGSAVE同步备份数据。
    AOF方式同步需要在redis.conf文件中修改配置,将appendonly no 改成appendonly yes。AOF也有三种方式供选择:
    appendfsync always
    appendfsync everysec
    appendfsync no
    分别表示每次修改操作都将同步,每秒同步一次,不同步
  • 性能问题,由于redis是单核单线程的,而memcached使用多核,所以平均在每一个核上Redis在存储小数据时 比Memcached的性能更高,而在100K以上的数据时,memcached的性能要高于redis的

二、redis是单线程的
redis通过队列技术将并行的操作转换成串行的操作,避免了多线程情况下对资源的竞争产生的开销;

三、redis的淘汰策略

  • volatile-lru:从设置了过期时间的数据集中选择最近最少被使用的数据淘汰;
  • volatile-ttl:从设置了过期时间的数据集中选择即将要过期的数据淘汰;
  • volatile-random:从设置了过期时间的数据集中随机选择数据被淘汰;
  • allkeys-lru:从数据集中选择最近最少被使用的key淘汰;
  • allkeys-random:从数据集中随机选择任意的key淘汰
  • no-enviction:不淘汰机制,当内存不足以存储新写入信息时,新的写入操作会报错,读请求不受影响,这是系统默认的一种淘汰策略;

三、redis为什么是单线程的
Redis是完全基于内存来操作的,不会由于cpu而导致性能的瓶颈,采用单线程可以避免不必要的上下文切换和资源竞争而产生的性能开销,也避免了多线程情况下cpu切换产生的开销

四、RDB持久化和AOF持久化的优缺点

  • RDB文件紧凑,体积小,网络传输较快,数据恢复快,对性能的影响较小
  • RDB文件的持久化方式决定了会丢失一部分数据(丢失的是上一次同步到下一次同步的时候生成已经修改删除的数据),兼容性不好,老版本的rdb文件可能不兼容新版本的
  • 与RDB相比,AOF文件实时性较好,兼容性好(aof文件里面是redis命令),缺点是文件较大,网络传输慢,恢复速度慢,对性能影响较大;

五、AOF文件比较大怎么办
随着redis会不断的将redis的写命令写入到aof文件当中,aof文件会越来越大,如果aof的文件越来越大,那么他的恢复时间也会越来越慢,为了解决aof文件越来越多的命令,用户可以向redis发送重写aof命令,BGREWRITEAOF

六、主从复制
和Mysql主从复制原因一样,由于大量的读请求导致了redis的压力特别大。故redis也支持主从模式,分解读请求的压力,一般主从复制分为全量同步和增量同步。
全量同步:当slave节点启动并连接上master时,slave节点会发送sync命令到master节点,master节点接收到命令时,会新建(fork)一个子进程来执行bgsave命令来生成一个rdb文件,并且会接收新的写命令并写入到缓冲区里面,当rdb文件生成了之后,会发送给所有的slave,并在发送期间继续接收写命令,当slave接收到快照后,会舍弃当前旧数据,生成新的rdb数据,在slave数据初始化完成之后,会往slave发送缓冲区的所有写入命令,slave将会执行master发送的写入命令,完成同步。
增量同步:当slave初始化之后,master每接收一个写入命令都会向slave同步发送一个写入命令,slave接收到之后,会执行该写入命令;
注意点:当slave断线了重新启动之后,会重新向master发送sync命令来同步全量数据,这个时候,若多个slave断线重启了可能会导致master的IO剧增导致宕机;

七:缓存穿透
缓存穿透指的是:当数据库和缓存都不存在某个key的情况下,用户通过访问不存在key,直接将访问落到数据库中,增大数据库的压力,导致系统崩溃,
解决方案:
1、当缓存和数据库里面都没查询到的时候,在缓存中保留一个空value的key,过期时间设置的短一点,比如10s或30秒,避免同一时间同一个key的请求的访问过多,导致数据库崩溃
2、通过布隆过滤器,我们将对所有可能查询的key以hash的形式存储在布隆过滤器中,当请求访问的时候,先在布隆过滤器中校验,若不存在,则直接返回结果,不在继续往下执行;

八、缓存击穿
缓存击穿指的是,缓存中没有但是数据库中有,由于这个时候访问量过大,导致数据库由于访问过多而崩溃
解决方案:
1、设置热点数据,对热点数据设置永不过期;
2、通过锁来实现,对数据库的访问加锁,对于同一时间同一个key的访问做加锁的限制,这样只会有一个请求会访问到数据库,避免访问量过大,而在加锁的代码里,首先会在查一遍缓存是否存在,若不存在则查询数据库,这样做是为了保证只有一个key会查询数据库,其他的相同key也是查询的缓存,提升了加锁的时长,增加吞吐量;

九、缓存雪崩
缓存雪崩指的是,缓存中有大量的key同一时间过期,导致数据库查询量过大,而造成的数据库宕机,和缓存击穿不同的是,缓存击穿指的是并发查询同一个key造成的,而缓存雪崩是多个key过期而被删除导致的
解决方案:
1、设置热点数据,对于热点数据设置永不过期
2、对不同缓存对象的有效期时间设置不同,避免同一时间大面积的key同时失效;
3、加分布式锁处理;

十、哨兵模式
哨兵模式是建立在主从模式之上的,主要是用来对master进行监控,并在master发生故障时,重选选择slave为master的功能。
1.监控所有节点是否是都可用的;
2.master节点发生故障时,通过自动投票机制,重新选举slave为master,实现将从数据库转换成主数据库的自动切换;
在一个一主多从的redis系统里面,可以配置多个哨兵来进行系统监控,保证系统的稳定,哨兵不仅会监控主数据库和从数据库,哨兵之间也会相互监控,因此建议至少建立三个以上的哨兵,并且为奇数位。
redis的哨兵系统一般用于监控多个redis实例,主要执行一下的任务:
1、监控:哨兵会不间断的检查master和slave是否正常
2、提醒:当检测到某个redis实例有问题后,可以通过api向管理员或其他的应用程序发送消息通知;
3、自动故障迁移:当检测到master不可用时,哨兵会进行一次自动故障迁移,会通过内部选举操作,选择失效的master的一个slave作为新的master,并让其他的slave复制新的master,当客户端试图连接新的master时,哨兵也会向集群返回新的master地址。
工作原理:每个哨兵会向其他的哨兵、master、slave进行监控,会定时的发送消息,若超过一定时间(自己设置down-after-milliseconds)内没有收到回应,则主观的认为宕机,当系统内大多数(自己设置)的哨兵都认为他宕机了,则系统会认为他彻底死亡了,当master确定彻底死亡了,哨兵内部会通过选举算法,选出一个新的master节点

你可能感兴趣的:(面试)