辛德蕾拉|面试官:Redis缓存了解吗?面对这11道题是否有很多问号?( 二 )


文件事件处理器的结构包含 4 个部分:

  • 多个 socket
  • IO 多路复用程序
  • 文件事件分派器
  • 事件处理器(连接应答处理器、命令请求处理器、命令回复处理器)
多个 socket 可能会并发产生不同的操作 , 每个操作对应不同的文件事件 , 但是 IO 多路复用程序会监听多个 socket , 会将产生事件的 socket 放入队列中排队 , 事件分派器每次从队列中取出一个 socket , 根据 socket 的事件类型交给对应的事件处理器进行处理 。
来看看客户端与 redis 的一次通信过程:
辛德蕾拉|面试官:Redis缓存了解吗?面对这11道题是否有很多问号?要明白 , 通信是通过 socket 来完成的 , 不懂的同学可以先去看一看 socket 网络编程 。
客户端 socket01 向 redis 进程的 server socket 请求建立连接 , 此时 server socket 会产生一个AE_READABLE 事件 , IO 多路复用程序监听到 server socket 产生的事件后 , 将该 socket 压入队列中 。
文件事件分派器从队列中获取 socket , 交给连接应答处理器 。 连接应答处理器会创建一个能与客户端通信的 socket01 , 并将该 socket01 的 AE_READABLE 事件与命令请求处理器关联 。
假设此时客户端发送了一个 set key value 请求 , 此时 redis 中的 socket01 会产生AE_READABLE 事件 , IO 多路复用程序将 socket01 压入队列 , 此时事件分派器从队列中获取到 socket01 产生的AE_READABLE 事件 , 由于前面 socket01 的 AE_READABLE 事件已经与命令请求处理器关联 , 因此事件分派器将事件交给命令请求处理器来处理 。 命令请求处理器读取 socket01 的 key value 并在自己内存中完成 key value 的设置 。 操作完成后 , 它会将 socket01 的 AE_WRITABLE 事件与命令回复处理器关联 。
如果此时客户端准备好接收返回结果了 , 那么 redis 中的 socket01 会产生一个 AE_WRITABLE 事件 , 同样压入队列中 , 事件分派器找到相关联的命令回复处理器 , 由命令回复处理器对 socket01 输入本次操作的一个结果 , 比如 ok , 之后解除 socket01 的 AE_WRITABLE 事件与命令回复处理器的关联 。
这样便完成了一次通信 。
为啥 redis 单线程模型也能效率这么高?
  • 纯内存操作
  • 核心是基于非阻塞的 IO 多路复用机制
  • 单线程反而避免了多线程的频繁上下文切换问题
3、redis 都有哪些数据类型?分别在哪些场景下使用比较合适?面试官心理分析除非是面试官感觉看你简历 , 是工作 3 年以内的比较初级的同学 , 可能对技术没有很深入的研究 , 面试官才会问这类问题 。 否则 , 在宝贵的面试时间里 , 面试官实在不想多问 。
其实问这个问题 , 主要有两个原因:
  • 看看你到底有没有全面的了解 redis 有哪些功能 , 一般怎么来用 , 啥场景用什么 , 就怕你别就会最简单的 KV 操作;
  • 看看你在实际项目里都怎么玩儿过 redis 。
要是你回答的不好 , 没说出几种数据类型 , 也没说什么场景 , 你完了 , 面试官对你印象肯定不好 , 觉得你平时就是做个简单的 set 和 get 。
面试题剖析redis 主要有以下几种数据类型:
  • string
  • hash
  • list
  • set
  • Zset(sorted set)
string
这是最简单的类型 , 就是普通的set和get , 做简单的KV缓存 。
hash
这个是类似 map 的一种结构 , 这个一般就是可以将结构化的数据 , 比如一个对象(前提是这个对象没嵌套其他的对象)给缓存在 redis 里 , 然后每次读写缓存的时候 , 可以就操作 hash 里的某个字段 。
hset person name bingohset person age 20hset person id 1 hget person nameperson = { "name": "bingo", "age": 20, "id": 1}


推荐阅读