面:缓存中间件——Memcached和Redis的区别是什么?

答:Memcached的优点是简单易用,代码层次类似与Hash。支持简单数据类型,但不支持数据持久化存储,也不支持主从同步,也不支持分片。Redis的数据类型丰富,支持数据磁盘持久化存储,支持主从,支持分片。

面:为什么Redis能这么快?(100000+QPS)

  • 完全基于内存,不受限于磁盘I/O,绝大部分请求是纯粹的内存操作,执行效率高
  • 数据结构简单,对数据操作也简单(不使用表,存储结构就是键值对)
  • 采用单线程(主线程,多个线程对同一个键做写操作的时候,不会出现并发问题,避免了上下文的切换和锁竞争),单线程也能处理高并发请求,想多核也可以启动多实例
  • 使用多路I/O复用模型,非阻塞IO

面:说说你用过的Redis的数据类型?

  • String:最基本的数据类型,二进制安全
  • Hash:String元素组成的字典,适合用于存储对象
  • List:列表,按照String元素插入顺序排序
  • Set:String元素组成的无序集合,通过哈希表实现,不允许重复
  • Sorted Set(ZSet):通过分数来为集合中的成员进行从小到大的排序
  • 用于计数的HyperLogLog,用于支持存储地理位置信息的Geo

Redis底层数据类型基础:

  1. 简单动态字符串
  2. 链表
  3. 字典
  4. 跳跃表
  5. 整数集合
  6. 压缩列表
  7. 对象

面:如何从海量Key里查询出某一固定前缀的Key?

答:若使用KEYS pattern:查找出所有符合给定模式patter的key,会对使线上的业务造成卡顿(主要是一次性返回所有的满足条件的key),此时可以使用SCAN指令(SCAN cursor [MATCH pattern] [COUNT count])无阻塞的返回一定数量的key(它是基于游标的迭代器,需要基于上一次的游标延续之前的迭代过程;以0作为游标开始一次新的迭代,直到命令返回游标0完成一次遍历;不保证每次执行都返回某个给定数量的元素,支持模糊查询。)

面:如何通过Redis实现简单的分布式锁?

分布式锁需要解决的问题:互斥性(任意时刻只能有一个客户端获取锁),安全性(锁只能由持有该锁的客户端释放),死锁(持有锁的客户端宕机后,无法释放锁,导致其他客户端无法获取到该锁导致的死锁),容错(当某些客户端宕机后,其他客户端也要能获取锁和释放锁)

答:缺陷方案:首先可以通过Redis命令SETNX key value(原子性的,如果可以不存在,则创建并赋值,时间复杂度O(1),设置成功返回1,失败返回0),若能设置成功则说明此时没有别的线程进入了临界区。若失败,则表明该资源已经被其他线程所占用了,所以需要一直等待,直到SETNX返回1即其他线程设置的key过期了(EXPIRE key seconds)。但是上述方案有个缺点:即SETNX 和 EXPIRE的复合操作不是原子性的,若某个线程执行完SETNX突然挂掉了,那么由于没有执行EXPIRE操作,那么独占资源就一直不能被其他线程所占用。

优秀方案:上述方案之所以有缺陷,是因为原子性没有得到满足,所以可以通过以下命令SET key value [EX secods] [PX milliseconds] [NX|XX](这条命令就是同时满足SETNX和EXPIRE,SET操作成功时返回OK,否则返回nil)此条命令是原子操作。

面:如果有大量的Key同时过期,那么需要注意什么?

集中过期,由于清除大量的key会耗时,会出现短暂的卡顿现象。解决方案是在设置key的过期时间时,给每个key加上随机值,使得过期时间分散些。

面:如何使用Redis做异步队列?

答:使用List作为队列,RPUSH生产消息,LPOP消费消息。但是LPOP不会等待队列有值才消费它会一直尝试消费,可以同过引入Sleep机制调用LPOP重试。也可通过命令BLPOP key [key...] timeout(阻塞直到队列有消息或者超时)。缺点是:只能供一个消费者消费。如果要让多个消费者消费,就可以使用Redis里的pub/sub(主题订阅者模式),但是消息的发布是无状态的,无法保证可达(要解决这个问题,就需要使用专业的队列Kafka)。

面:Redis如何做持久化?

  • RDB(快照)持久化:保存某个时间点的全量数据快照

    • SAVE命令:阻塞Redis的服务器进程,直到RDB文件被创建完毕
    • BGSAVE命令:Fork出一个子进程来创建RDB文件,不阻塞服务器进程
    • 缺点是:由于是内存数据的全量同步,那么当数据量大时会由于I/O而严重影响性能;可能会因为Redis挂掉而丢失从当前至最近一次快照期间的数据
  • AOF(Append-Only-File)持久化:保存写状态。记录除了查询以外的所有变更数据库状态的指令,以append的形式追加保存到AOF文件中(增量)

面:如何解决AOF文件大小不断增大的问题?

答:可以采取日志重写的方式,原理如下:

  1. 调用fork(),创建一个子进程
  2. 子进程把新的AOF写到一个临时文件里,不依赖原来的AOF文件
  3. 主进程持续将新的变动同时写到内存和原来的AOF里(防止重写失败,保证数据的完整性)
  4. 主进程获取子进程重写AOF的完成信号往新AOF同步增量变动
  5. 使用新的AOF文件替换掉旧的AOF文件

面:当RDB和AOF文件共存的情况下,如何恢复Redis的数据?

面:谈谈RDB和AOF的优缺点?

  • RDB优点:全量数据快照,文件小,恢复快
  • RDB缺点:无法保存最近一次快照之后的数据
  • AOF优点:可读性高,适合保存增量数据,数据不易丢失
  • AOF缺点:文件体积大,恢复时间长

RDB-AOF混合持久化方式:BGSAVE做镜像全量持久化,AOF做增量持久化。

面:如何从海量数据里快速找到所需要的数据?

答:使用分片:按照某种规则去划分数据,使数据分散存储在多个节点上。并且Redis为了能够提高key的命中率,采用的是一致性hash算法(一致性hash算法:对2^32取模将hash值空间组织成虚拟的圆环,将数据key使用相同的hash函数计算出hash值,引入虚拟节点解决数据倾斜)。

参考资料

慕课网 剑指Java面试-Offer直通车

面试之Redis的更多相关文章

  1. 面试集——redis

    背景:该贴主要用来记面试过程中redis相关的问题,方便后期回顾. 为什么说Redis是单线程的以及Redis为什么这么快! https://blog.csdn.net/xlgen157387/art ...

  2. 【面试】我是如何在面试别人Redis相关知识时“软怼”他的

    事出有因 Redis是一个分布式NoSQL数据库,因其数据都存储在内存中,所以访问速度极快,因此几乎所有公司都拿它做缓存使用,所以Redis常被称为分布式缓存. 一次我的一个同事让我帮他看Redis相 ...

  3. 妈妈再也不担心我面试被Redis问得脸都绿了

    长文前排提醒,收藏向前排提醒,素质三连 (转发 + 在看 + 留言) 前排提醒! 前言 Redis 作为一个开源的,高级的键值存储和一个适用的解决方案,已经越来越在构建 「高性能」.「可扩展」 的 W ...

  4. 【Java面试】Redis存在线程安全问题吗?为什么?

    一个工作了5年的粉丝私信我. 他说自己准备了半年时间,想如蚂蚁金服,结果第一面就挂了,非常难过. 问题是: "Redis存在线程安全问题吗?" 关于这个问题,看看普通人和高手的回答 ...

  5. Java面试07|Redis数据库

    1.Redis持久化的几种方式 (1)RDB(Redis DataBase)持久化 (2)AOF(Append Only File)持久化 2.Redis的缓存失效策略 主要涉及到expire对主键过 ...

  6. Redis面试篇 -- Redis主从复制原理

        Redis一般是用来支撑读高并发的,为了分担读压力,Redis支持主从复制.架构是主从架构,一主多从, 主负责写,并且将数据复制到其它的 slave 节点,从节点负责读. 所有的读请求全部走从 ...

  7. 【面试】Redis

    1.如果在setnx之后执行expire之前进程意外crash或者要重启维护了,那会怎么样? set指令有非常复杂的参数,这个应该是可以同时setnx和expire合成一条指令来用的! 2.使用过Re ...

  8. 面试突击 | Redis 如何从海量数据中查询出某一个 Key?附视频

    1 考察知识点 本题考察的知识点有以下几个: Keys 和 Scan 的区别 Keys 查询的缺点 Scan 如何使用? Scan 查询的特点 2 解答思路 Keys 查询存在的问题 Scan 的使用 ...

  9. 面试准备——redis

    https://blog.csdn.net/yangzhong0808/article/details/81196472 http://www.imooc.com/article/36399 http ...

随机推荐

  1. sass 安装与各种命令

    css 是一种编程语言,可以用来开发网页样式,但是却不能编程,没有变量,没有条件语句,于是就有了“css预处理器”, 它的原理就是:利用编程语言进行网页样式设计,然后再编译成正常的css文件: sas ...

  2. iOS编码的一些规范

    1.实例变量instance variable,最好带上前缀下划线,例如 @interface  Person:NSObject { NSString *_name; int *_age; } @en ...

  3. 05_传智播客iOS视频教程_第一个OC程序

    Cocoa Application开发的是带界面的程序. OC是完全兼容C语言的,但是C语言里面是不能写OC的东西的. OC和C的第一个区别,就是源文件的后缀名的区别.OC程序的源文件的后缀名是.m, ...

  4. bzoj 2423: [HAOI2010]最长公共子序列【dp+计数】

    设f[i][j]为a序列前i个字符和b序列前j个字符的最长公共子序列,转移很好说就是f[i][j]=max(f[i-1][j],f[i][j-1],f[i-1][j-1]+(a[i]==b[j])) ...

  5. bzoj 3437: 小P的牧场【斜率优化】

    emmm妹想到要倒着推 先假设只在n建一个控制站,这样的费用是\( \sum_{i=1}^{n} b[i]*(n-i) \)的 然后设f[i]为在i到n键控制站,并且i一定建一个,能最多节省下的费用, ...

  6. 数据结构 - 顺序栈的实行(C语言)

    数据结构-顺序栈的实现 1 顺序栈的定义 既然栈是线性表的特例,那么栈的顺序存储其实也是线性表顺序存储的简化,我们简称为顺序栈.线性表是用数组来实现的,对于栈这种只能一头插入删除的线性表来说,用数组哪 ...

  7. [POI2012]Vouchers

    Description 考虑正整数集合,现在有n组人依次来取数,假设第i组来了x人,他们每个取的数一定是x的倍数,并且是还剩下的最小的x个. 正整数中有m个数被标成了幸运数,问有哪些人取到了幸运数. ...

  8. 手把手教你玩微信小程序跳一跳

    最近微信小程序火的半边天都红了,虽然不会写,但是至少也可以仿照网上大神开发外挂吧!下面手把手教妹纸们(汉纸们请自觉的眼观耳听)怎么愉快的在微信小游戏中获得高分. 废话不多说,咱们这就发车了!呸!咱们这 ...

  9. Word排版技巧

    点击打开链接 # 整体布局 ## 页面布局 如果是新建一个Word文件,这里「页面布局」一般不用设置了: 文字方向:从左到右: 页边距:普通(日常使用建议用适中或窄,节约用纸,提交的论文报告什么才用普 ...

  10. 动态链接库(DLL) 分类: c/c++ 2015-01-04 23:30 423人阅读 评论(0) 收藏

    动态链接库:我们经常把常用的代码制作成一个可执行模块供其他可执行文件调用,这样的模块称为链接库,分为动态链接库和静态链接库. 对于静态链接库,LIB包含具体实现代码且会被包含进EXE中,导致文件过大, ...