美文网首页
Redis面试专题

Redis面试专题

作者: 橙一万 | 来源:发表于2023-07-19 20:15 被阅读0次

    基础

    Redis有哪些数据结构?

    • String(最常用)
      是redis中最基本的数据类型,一个key对应一个value。
      String类型是二进制安全的,意思是 redis 的 string 可以包含任何数据。如数字,字符串,jpg图片或者序列化的对象。
      常用命令 get 、 set 、 del 、 incr、 decr
    • List
      链表(redis 使用双端链表实现的 List),是有序的,value可以重复,可以通过下标取出对应的value值,左右两边都能进行插入和删除数据。
      常用命令 lpush、rpush、lpop、rpop、lrange、llen、lindex
    • Hash
      Map集合,key-map! value是一个map集合
      常用命令 hset、hget、hlen、hsetnx
    • Set
      无序集合 1.不允许有重复的元素,2.集合中的元素是无序的,不能通过索引下标获取元素,3.支持集合间的操作,可以取多个集合取交集、并集、差集
      常用命令 sadd、srem 、smembers 、sismember 、scard
    • Zset
      有序集合--有序集合和集合有着必然的联系,保留了集合不能有重复成员的特性,区别是,有序集合中的元素是可以排序的,它给每个元素设置一个分数,作为排序的依据。

    另外

    • Geo
      主要用于存储地理位置信息,并对存储的信息进行操作 例如:查看附近的人,计算与某点之间的距离等操作
    • HyperLogLog
      用来做基数统计的算法,HyperLogLog 的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定 的、并且是很小的。
    • Pub/Sub
      发布订阅

    Redis一个实例能存多少个key?

    Redis一共有0-15总共16个db,默认使用db0
    Redis一个数据库能存储2.5亿的Key,一个value的最大容量为512MB;

    什么是Redis持久化?Redis有哪几种持久化方式?优缺点是什么?

    持久化就是把内存的数据写到磁盘中去,防止服务宕机了内存数据丢失。
    (Redis 数据都放在内存中,断电即失,所以持久化是必须的。将内存中的数据保存在磁盘,下一次启动的时候就可以恢复数据到内存中。)

    Redis 提供了两种持久化方式:RDB(默认) 和AOF

    • RDB(Snapshotting):快照持久化、全量持久化

    RDB持久化是指 在指定的时间间隔内将内存中的 数据集快照 写入磁盘,实际操作过程是主进程fork一个子进程,先将数据集写入临时文件(dump.rdb),写入成功后,再替换之前的文件,默认用二进制压缩存储。具体间隔多长时间持久化一次,要看配置文件具体配置。

    默认配置为:
    save 900 1     #在900秒(15分钟)之后,如果至少有1个key发生变化,Redis就会自动触发BGSAVE命令创建快照。
    save 300 10    #在300秒(5分钟)之后,如果至少有10个key发生变化,Redis就会自动触发BGSAVE命令创建快照。
    save 60 10000  #在60秒(1分钟)之后,如果至少有10000个key发生变化,Redis就会自动触发BGSAVE命令创建快照。
    
    当然了,你也可以通过调用 SAVE (同步保存)或者 BGSAVE(异步保存),手动让 Redis 进行数据集保存操作。
    一般来说,在生产环境很少执行 SAVE 操作,因为它会阻塞所有客户端,保存数据库的任务通常由 BGSAVE 命令异步地执行。
    然而,如果负责保存数据的后台子进程不幸出现问题时, SAVE 可以作为保存数据的最后手段来使用。
    
    • AOF(append only file):增量持久化

    AOF持久化 是以日志的形式记录服务器所处理的每一个写、删除操作,查询操作不会记录,以文本的方式追加记录到 appendonly.aof 文件,可以打开文件看到详细的操作记录。
    如果开启AOF后,默认持久化方式为每秒同步一次:
    appendfsync everysec 每秒钟同步一次,显示地将多个写命令同步到硬盘

    【注】如果两个都配了 则优先加载AOF。(同时开启两个持久化方案,则按照 AOF的持久化方案恢复数据。)


    • RDB优点

      • 数据紧凑,利于备份:RDB 是一个非常紧凑(compact)的文件,它保存了 Redis 在某个时间点上的数据集。这种文件非常适合用于进行备份:比如说,你可以在最近的 24 小时内,每小时备份一次 RDB 文件,并且在每个月的每一天,也备份一个 RDB 文件。这样的话,即使遇上问题,也可以随时将数据集还原到不同的版本。
      • 性能最大化:RDB对Redis的性能影响非常小,是因为在同步数据的时候他只是fork了一个子进程去做持久化的再由子进程完成这些持久化的工作,父进程无须执行任何磁盘 I/O 操作。
    • RDB缺点

      • 容易造成数据丢失:如果你想保证数据的高可用性,即最大限度的避免数据丢失,那么RDB将不是一个很好的选择。因为系统一旦在定时持久化之前出现宕机现象,此前没有来得及写入磁盘的数据都将丢失。
      • 数据量大时消耗资源:由于RDB是通过 fork 子进程来协助完成数据持久化工作的,因此,如果当数据集较大时,客户端可能会暂停几毫秒甚至几秒;如果 你公司在做秒杀的时候他刚好在这个时候 fork 了一个子进程去生成一个大快照,这就很容易出现问题。

    • AOF优点

      • 保证数据的完整性 每一次修改都同步,文件的完整性会更好
      • 每一秒都同步,可能会丢失一秒的数据
    • AOF缺点

      • 对于相同数量的数据集来说,AOF文件通常要大于RDB文件AOF在恢复大数据集时比RDB恢复速度要慢
      • 根据同步策略的不同,AOF在运行效率上往往会慢于RDB。总之,每秒同步策略的效率是比较高的,同步禁用策略的效率和RDB一样高效。

    二者选择的标准,就是看系统是愿意 牺牲一些性能,换取更高的缓存一致性(aof),还是愿意写操作频繁的时候,不启用备份来换取更高的性能,待手动运行save的时候,再做备份(rdb)。rdb这个就更有些 最终一致性(eventually consistent)的意思了。

    进阶

    Redis是单线程的为什么速度还这么快

    Redis 读的速度是110000次/s,写的速度是80000次/s 。

    1.redis是基于内存的,内存的读写速度非常快;
    2.redis是单线程的,省去了很多上下文切换线程的时间;
    3.redis使用多路复用技术,可以处理并发的连接;

    简单解释下第二条:上下文切换就是cpu在多线程之间进行轮流执行(抢占cpu资源),而redis单线程的,因此避免了繁琐的多线程上下文切换

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

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

    Redis如何实现延时队列?

    Redis分布式锁

    缓存穿透(缓存和数据库都没有对应的数据)及如何解决?

    缓存穿透是指:用户想要查询一个数据,发现redis缓存数据库没有,也就是缓存没有命中,于是向持久层数据库查询。发现也没有,于是本次查询失败。当用户很多的时候,缓存都没有命中,于是都去请求了持久层数据库。这会给持久层数据库造成很大的压力,这时候就相当于出现了缓存穿透。

    • 方案一:缓存空对象

    缓存空对象会有一个必须考虑的问题:
    空值做了缓存,意味着缓存层中存了更多的键,需要更多的内存空间(如果是恶意攻击,缓存中的键值就会很多,问题更严重),比较有效的方法是针对这类数据设置一个较短的过期时间,让其自动过期。

    • 方案二:布隆过滤器拦截

    缓存击穿(所有查询全都聚集在缓存的某个点上)及如何解决?

    缓存击,是指:一个key非常热点,在不停的扛着大并发,大并发集中对这一个点进行访问,当这个key在失效的瞬间,持续的大并发就穿破缓存,直接请求数据库,就像在一个屏障上凿开了一个洞。

    缓存雪崩及如何解决?

    缓存雪崩就是指:缓存由于某些原因(比如 宕机、cache服务挂掉 或 有大量的key在同一时间过期),导致大量请求涌入到数据库,从而导致数据库崩溃,整个系统崩溃,发生灾难。

    缓存雪崩、穿透和击穿,是缓存最大的问题,要么不出现,一旦出现就是致命性的问题!

    哨兵模式

    主从之间的数据怎么同步的?

    你启动一台slave 的时候,他会发送一个psync命令给master ,如果是这个slave第一次连接到master,他会触发一个全量复制。master就会启动一个线程,生成RDB快照,还会把新的写请求都缓存在内存中,RDB文件生成后,master会将这个RDB发送给slave的,slave拿到之后做的第一件事情就是写进本地的磁盘,然后加载进内存,然后master会把内存里面缓存的那些新命名都发给slave。


    参考文章:

    相关文章

      网友评论

          本文标题:Redis面试专题

          本文链接:https://www.haomeiwen.com/subject/zvinrltx.html