Redis面试问点啥

总是写严肃的东西,也写点轻松愉快的,谈谈Redis,总结下自己面试以及网上的一些Redis面试经验。

笔者博客:https://charpty.com

一进门便是游戏开始了

我总感觉面试和狼人杀游戏差不多,一拿到牌游戏就开了,一样的,当面试官踏进门游戏便开始了。
咱们假设只是问Redis相关的哈。

不知道许多面试官有没有中招,第一题总是Redis有几种数据类型,D:–

Redis有几种数据类型呢

第一个问题往往是最重要的,因为它决定了后面要问你什么样的问题,就和你冲排位似的,前几把是定级赛,定级时给你个青铜段位,想要爬上去可就难了

是我的话,肯定要答全啊(装X脸)。都知道的有StringListSetSorted SetHash

不过这么回答的话,看样子只能拿30分了,接下来就是问问你会不会几个命令之类的了。
在我看来分为两类结构,一个是Redis自带的数据结构.

  1. 二进制安全的String:有点扯,但是面试官肯定在想你指的啥了.
  2. 双向链表、跳表、压缩表简称列表:这时面试官觉得有点意思了.
  3. 有序集合:这下好了这家伙使用上面的结构实现的
  4. 哈希表:和JDK1.7的实现类似
  5. 集合:利用哈希表实现

答了这5个,面试官的心窝子暖了,总算来了个稍微懂点的兄弟了,可是吧还不够,还不够完美,这5个是Redis基础的数据结构,还有更加高级的。

  1. 位图bitmap或者bit arrays:把本地的位图功能搬到了分布式环境中
  2. HyperLogLog:超级计数器,用来做大量元素计数统计的
  3. Geo地理位置:这可是PostgreSQL、mongo等db的拿手好戏,redis也做了支持
  4. 发布订阅:和楼上这位一样,是不是属于数据结构各有看法,更有说Pipeline也是

没了吧,真没了,Redis内部的数据结构真的就是这些了,这时候面试官流着口水看着你,当然他不是要吃掉你,他是希望你继续说下去。

Redis官网右边倒数第二个选项卡ModulesRedis本身各命令时也就是通过模块注入的方式实现的,所以它可以灵活的支持其他人编写模块嵌入到Redis中。

既然是自己编写模块,那这数据结构就说不清楚了,随你自己造,当然不需要你全部列出来,说几个出名的就行,Redis也把写的好的模块放到了官网上(写的好的都是他们自己人。。。)。

  1. neural-redis:这个厉害了,Redis作者自己实现的神经网络,当作是Redis的一种数据类型
  2. ReJSON:A JSON data type for Redis你懂就行
  3. rebloom:布隆过滤器
  4. Redis Graph:这老哥就不是整个数据结构那么简单了,他整了一个数据库,一大堆数据结构

因为Redis扩展的模块实在很多,就不一一列举,自己玩过写过module会有体会。

好了回答到这里,第一个问题就算是回答清楚了,厉害的面试官应该挺开心的,对你说:你小子值得再问100个问题!。。。。差点想打他,忍住嘛毕竟咱是来找工作的

说一说Redis的单线程模型

得,有了上面的回答,一般的set、get问题也懒得问了,Redis最著名的莫如这个单线程模型,不问才是见了鬼了。

Redis的单线程模型怎么来的呢,其实是这样的,作者antirez学艺不精,Linuxpthread编程模型对他来说太困难了,算了,咱就搞个单线程的算了,别和说什么多核并发、同步运行、异步非阻塞,老夫敲代码就是一把梭。

当然这不是真的,Redis单线程模型就是为了快,为了简单,是的没错,简单了就会很快,就好比为什么用越多的框架性能就越低,因为复杂了,为了扩展性、使用便利不得不作出很多性能牺牲。

单线程模型最大的好处就是防止了线程上下文切换带来的消耗,Redis使用的非阻塞IO、数据结构都量身定制,在实际环境中Redis最高可以支持百万级的QPS(这牛皮吹大了),Redis作为一个内存数据库,主要在于对内存的操作,CPU绝不会成为瓶颈。

你要实在是可惜你的CPU浪费了,你可以在一台机器上装Redis啊,。。。。我竟无言以对

前面回答完了,面试官只能是点点头,没有露出诡异的微笑,那还有什么要说的呢。。其实还很多,任何架构总是配合具体的业务来设计的,既然选择了单线程一定要有各种配合,首先思考几个问题。

1、这么多客户端连接Redis服务器,随时每个连接都有请求,一个线程面对这么多连接怎么应付的过来呢
2、在Redis中备份数据非常耗时的操作怎么做的呢
3、大键删除、过期数据扫描、Rehash、大量连接检查保活是怎么做的呢
4、单线程下多个客户端的事物型请求怎么处理

对啊,你倒是单线程了,你倒是简单了,编程也简单,速度也快了,看代码也爽了。那这些问题怎么解决呢,单线程模型咱说了,牛皮也吹了,关键在于在于在单线程模型下巧妙的解决了这些问题,这才是Redis单线程模型的真正精髓,不然解决不了问题早就改了。

多线程提供了除了利用多核以外很多的好处:防止阻塞、更好的编程模型,要在单线程模型下结合业务也拥有这些特性则需要巧妙的设计(我想Redis有些设计真的不是用巧妙形容的,简直是粗暴),场景非常多,挑上述几个典型的说说。

网络问题则是利用Linux提供的多路复用IO,Unix种种好处,也是没有开发```Windows````版本原因之一
粗暴的来了,数据备份操作则是通过fork子进程来完成

大键删除、过期数据扫描、Rehash等操作,Redis则都是将其逻辑切分,每次只完成一部分,每次只占用一小段时间的CPU,分多次完成。这里涉及到一个很重要的东西,就是Redis对CPU时间片的分配,这个分配模型贯穿了众多耗时操作,也是eventLoop非常重要的一环。

事务啊,更粗暴,不支持,Redis事务并不是完整的ACID,当然可以顺便把几种实现一次类原子的执行命令的场景,multi、pipeline、lua script、面试官应该满意了。

当然最后还要得瑟一下,咳咳、Redis的单线程模型也要看怎么理解了哈,虽然存在并发、并行行为,但是它表现的像串行执行一般即可呀。 Redis4.0开始也逐渐增加了许多并发编程,总的目的都是提高各种各样场景下的运行性能(实际场景总是复杂的,实验室的QPS不能作数)。

Redis安全

很多同学对Redis各方面都很了解了,但是这个问题绝不仅仅关于Redis,即使很多工作多年的同学都容易忽略安全这个问题,安全无小事!

一般会问你们一般都做了哪些工作来保证Redis安全,这个问题比较难回答,涉及到了宏观的架构安全,但是可以先从小事入手。

  1. 高强度密码:Redis服务器绝不裸奔
  2. 危险命令重命名:对于刷库、config、save等命令进行重命名,防止误操作和恶意攻击
  3. 指定网卡bind:不要在所有网卡监听,也最好不要用默认端口,在不确定的网络环境中造成巨大隐患
  4. 防火墙与IP白名单:和数据库一样严格
  5. 定期数据备份:安全当然包括数据不丢失
  6. 非root启动:之前的Redis save获得root权限的场景还历历在目
  7. 定期审计:定期检查client list和慢日志,查看是否有monitor等
  8. 手动清理不合规数据:大键、大lua脚本、永留存数据,要有监控大盘
  9. 代码安全:要有统一的公共组件代码来访问Redis,避免程序员误操作

回答了这些,我想至少面试官会认为你有安全意识了,这个问题在他心中你已经通过了。但是想让他眼前一亮,你还得知道Redis的安全模型。

安全模型涉及的内容不少,简单的有Protected mode,这个在早前版本就有,一启动只能localhost访问,是不是很郁闷。

数据加密,Redis不支持数据传输加密,但是可以借助其他工具实现安全传输如spiped。

特殊算法碰撞,Redis的数据结构不多,比如Hash类型,如果把所有的元算都放到一个桶里,那岂不是整个Redis都卡了,关键Redis大量使用哈希表存储各种系统运行、时间、方法引用等信息。Redis为了防止这种情况使用了per-execution pseudo-random种子,使得元素存储带有一定的随机性,避免了相同数据落桶密集的问题。

Lua脚本评估,eval()这个东西在任何时候都是个麻烦,里面的参数就是代码,可以想见一不留神就危险了,虽然Redis没有对String做escape,但是通信协议有规定prefixed-length strings来保障安全,再说说RESP通信协议,面试官会刮目相看。

说到这里,面试官已经对你称赞不绝了,就差一步就可以录取你了。

Redis集群概述

好吧,最后一题,这时对面试官而言,问完这个问题怎么给你定级别才是问题。
一般会问,说一说Redis集群的通信方式、Redis如何做数据路由等等。

其实前面的问题都不是那么关键,这个才是真正展现你水平的时候,Redis集群是生产环境常用的场景。

这里面涉及的东西就太多了,分布式理论,一致性协议、数据分区与路由、集群通信协议、故障转移等等数不尽数,我想绝大多数人都只能尽力而为,但是知道几个大块和回答方向,谈起来也会从容许多。

分布式理论像CAP、BASE等一大堆东西是个大学问只能自己慢慢看和体会,一致性协议像Paxos、Raft、ZAB等等倒是可以自己跟着推导推导,手写尝试实现。这两点看着讲吧,别不懂装懂就行,面试官都不是吃素的,很容易拆穿你。

Redis的数据分区与路由以及集群通信机制则是必须要掌握的

Redis采用slot槽进行分区,各个数据通过一致性哈希分配到每个节点,当然他问你一致性哈希你也可以和他讲讲,一共映射有16384个槽,为什么呢2^14次方,因为考虑到最多节点数和集群节点map大小问题。
分区了当然也会限制很多的操作不能进行,可以讲一讲

Redis集群的路由也简单,计算槽 -> 槽节点查找,首先是通过hash函数计算位置,crc16() & 16383得到槽的位置,为什么还要再找槽呢,因为是集群就涉及到节点下线、数据迁移等问题,前一秒master1还在线,下一秒slave1就要接替站岗了,集群node map都还来不及更新。

Redis找槽主要逻辑就是先按map找,找到了发现不是,咱就随机换一个节点接着找呗,直到找到为止,这种方法虽然耗资源,但是简单!这和单线程模型如出一辙,都是作者偷懒的表现,哈哈。。。。

另外还要注意讲清楚ASK响应,如何实现智能客户端等等

接下来就是说说节点之间的通信了,通信协议采用的Gossip协议,单个节点与节点之间不断的交换消息,最终信息扩展到整个集群,整个通信是在另外单独的端口上进行的,有ping、meet、fail等多种消息。

既然是一对一,那么选择谁进行通信则是关键,否则老是和同一个节点说话,那么消息就很难传播到整个集群,Redis大量的工作就在此处了,通过记录与节点的通信时间,随机选择,槽信息更新频率等情况对通信节点进行选择。

最后这一个问题是展现本事的时候,不大可能是单纯的回答,中间多少穿插着就细节展开问题,这时就靠兵来将挡水来土淹了,当然回答这些问题不是关键,重要的是真的理解它的原理。


好了,面试要差不多,面试官问你大概期待的薪资待遇等等了,突然,你露出诡异的笑容,你知道自己过了,轻轻的说一句:我是来锻炼下水平的,再见!D#–

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值