zoukankan      html  css  js  c++  java
  • Redis基础

    为啥用Redis

    因为传统的关系型数据库如Mysql已经不能适用所有的场景了,比如秒杀的库存扣减,APP首页的访问流量高峰等等,

    都很容易把数据库打崩,所以引入了缓存中间件,目

    前市面上比较常用的缓存中间件有RedisMemcached不过中和考虑了他们的优缺点,最后选择了Redis。

    Redis有哪些数据结构

    String、Hash、List、Set、SortedSet。这五种类型最适合的场景更好

    但是,如果你是Redis中高级用户,而且你要在这次面试中突出你和其他候选人的不同,还需要加上下面几种数据结构HyperLogLog、Geo、Pub/Sub

    如果你还想加分,那你说还玩过Redis Module,像BloomFilter,RedisSearch,Redis-ML

    如果有大量的key需要设置同一时间过期,一般需要注意什么?

    如果大量的key过期时间设置的过于集中,到过期的那个时间点,Redis可能会出现短暂的卡顿现象严重的话会出现缓存雪崩,我们一般需要在时间上加一个随机值,使得过期时间分散一些。

    电商首页经常会使用定时任务刷新缓存,可能大量的数据失效时间都十分集中,如果失效时间一样,又刚好在失效的时间点大量用户涌入,就有可能造成缓存雪崩

    那你使用过Redis分布式锁么,它是什么回事?

    先拿setnx来争抢锁,抢到之后,再用expire给锁加一个过期时间防止锁忘记了释放。

    如果在setnx之后执行expire之前进程意外crash或者要重启维护了,那会怎么样?

    set指令有非常复杂的参数,这个应该是可以同时把setnxexpire合成一条指令来用的!

    假如Redis里面有1亿个key,其中有10w个key是以某个固定的已知的前缀开头的,如何将它们全部找出来?

    使用keys指令可以扫出指定模式的key列表

    如果这个redis正在给线上的业务提供服务,那使用keys指令会有什么问题?

    Redis的单线程的。keys指令会导致线程阻塞一段时间,线上服务会停顿,直到指令执行完毕,服务才能恢复。

    这个时候可以使用scan指令,scan指令可以无阻塞的提取出指定模式的key列表,但是会有一定的重复概率,

    在客户端做一次去重就可以了,但是整体所花费的时间会比直接用keys指令长。

    不过,增量式迭代命令也不是没有缺点的:

    举个例子, 使用 SMEMBERS 命令可以返回集合键当前包含的所有元素,

    但是对于 SCAN 这类增量式迭代命令来说, 因为在对键进行增量式迭代的过程中, 键可能会被修改,

    所以增量式迭代命令只能对被返回的元素提供有限的保证 。

    使用过Redis做异步队列么,你是怎么用的?

    一般使用list结构作为队列,rpush生产消息,lpop消费消息。

    lpop没有消息的时候,要适当sleep一会再重试。

    可不可以不用sleep呢?

    list还有个指令叫blpop,在没有消息的时候,它会阻塞住直到消息到来。

    如果对方接着追问能不能生产一次消费多次呢?

    使用pub/sub主题订阅者模式,可以实现 1:N 的消息队列。

    如果对方继续追问 pub/su b有什么缺点?

    在消费者下线的情况下,生产的消息会丢失,得使用专业的消息队列如RocketMQ等。

    如果对方究极TM追问Redis如何实现延时队列?

    使用sortedset,拿时间戳作为score,消息内容作为key调用zadd来生产消息,消费者用zrangebyscore指令获取N秒之前的数据轮询进行处理。

    Redis是怎么持久化的?服务主从数据怎么交互的?

    RDB做镜像全量持久化,AOF做增量持久化。

    因为RDB会耗费较长时间,不够实时,在停机的时候会导致大量丢失数据,所以需要AOF来配合使用。

    在redis实例重启时,会使用RDB持久化文件重新构建内存,再使用AOF重放近期的操作指令来实现完整恢复重启之前的状态。

    把RDB理解为一整个表全量的数据,AOF理解为每次操作的日志就好了,服务器重启的时候先把表的数据全部搞进去,

    但是他可能不完整,你再回放一下日志,数据不就完整了嘛。

    不过Redis本身的机制是 AOF持久化开启且存在AOF文件时,优先加载AOF文件;

    AOF关闭或者AOF文件不存在时,加载RDB文件;

    加载AOF/RDB文件城后,Redis启动成功;AOF/RDB文件存在错误时,Redis启动失败并打印错误信息

    对方追问那如果突然机器掉电会怎样?

    取决于AOF日志sync属性的配置,如果不要求性能,在每条写指令时都sync一下磁盘,就不会丢失数据。

    但是在高性能的要求下每次都sync是不现实的,一般都使用定时sync,比如1s1次,这个时候最多就会丢失1s的数据。

    对方追问RDB的原理是什么?

    你给出两个词汇就可以了,fork和cow。

    fork是指redis通过创建子进程来进行RDB操作,cow指的是copy on write

    子进程创建后,父子进程共享数据段,父进程继续提供读写服务,写脏的页面数据会逐渐和子进程分离开来。

    注:回答这个问题的时候,如果你还能说出AOF和RDB的优缺点,我觉得我是面试官在这个问题上我会给你点赞,两者其实区别还是很大的,而且涉及到Redis集群的数据同步问题等等。

    Pipeline有什么好处,为什么要用pipeline?

    可以将多次IO往返的时间缩减为一次,前提是pipeline执行的指令之间没有因果相关性。

    使用redis-benchmark进行压测的时候可以发现影响redis的QPS峰值的一个重要因素是pipeline批次指令的数目。

    Redis的同步机制了解么?

    Redis可以使用主从同步,从从同步。

    第一次同步时,主节点做一次bgsave,并同时将后续修改操作记录到内存buffer,

    待完成后将RDB文件全量同步到复制节点,复制节点接受完成后将RDB镜像加载到内存。

    加载完成后,再通知主节点将期间修改的操作记录同步到复制节点进行重放就完成了同步过程。

    后续的增量数据通过AOF日志同步即可,有点类似数据库的binlog。

    是否使用过Redis集群,集群的高可用怎么保证,集群的原理是什么?

    Redis Sentinal 着眼于高可用,在master宕机时会自动将slave提升为master,继续提供服务。

    Redis Cluster 着眼于扩展性,在单个redis内存不足时,使用Cluster进行分片存储。

    总结

    在技术面试的时候,不管是Redis还是什么问题,如果你能举出实际的例子,或者是直接说自己开发过程的问题和收获会给面试官的印象分会加很多,回答逻辑性也要强一点,不要东一点西一点,容易把自己都绕晕的。

    参考:https://mp.weixin.qq.com/s/aOiadiWG2nNaZowmoDQPMQ

  • 相关阅读:
    「UVA12293」 Box Game
    「CF803C」 Maximal GCD
    「CF525D」Arthur and Walls
    「CF442C」 Artem and Array
    LeetCode lcci 16.03 交点
    LeetCode 1305 两棵二叉搜索树中的所有元素
    LeetCode 1040 移动石子直到连续 II
    LeetCode 664 奇怪的打印机
    iOS UIPageViewController系统方法崩溃修复
    LeetCode 334 递增的三元子序列
  • 原文地址:https://www.cnblogs.com/Vincent-yuan/p/15261996.html
Copyright © 2011-2022 走看看