Redis 简介

缓存中间件——Memcache 与 Redis 的区别

Memcache:代码层次类似Hash

  • 支持简单数据库
  • 不支持持久化
  • 不支持主从
  • 不支持分片

Redis

  • 数据类型丰富
  • 支持持久化
  • 支持主从
  • 支持分片

如果只是简单需要一个key-value缓存,则mencache即可,有高级要求则建议Redis

为什么Redis这么快

Redis可以达到100000+QPS(Query per second,每秒查询次数)

  • 完全基于内存,绝大部分请求是纯粹的内存操作,执行效率高

  • 数据结构简单,对数据操作也简单

  • 采用单线程,单线程也能处理高并发请求,想多核也可启动多实例

    • 单线程指网络请求模块使用了一个线程(所以不需考虑并发安全性),即一个线程处理所有网络请求,其他模块仍用了多个线程。
    • 单线程避免了频繁的上下文切换和锁竞争,也不会出现并发问题。
    • 整个Redis肯定是多线程的,比如持久化写入时就开一个子线程去写入。
  • 使用多路I/O复用模型,非阻塞I/O

客户端与服务端建立连接交由socket,可以同时建立多个连接(这里应该是多线程/多进程),建立的连接redis是知道的,然后redis会基于这些建立的连接去探测哪个连接已经接收完了客户端的请求数据(注意:不是探测哪个连接建立好了,而是探测哪个接收完了请求数据),而且这里的探测动作就是单线程的开始,一旦探测到则基于接收到的数据开始数据处理阶段,然后返回数据,再继续探测下一个已经接收完请求数据的网络连接。注意,从探测到数据处理再到数据返回,全程单线程。这应该就是所谓的redis单线程。

多路I/O复用模型

FD:File Discriptor 文件描述符

  • 一个打开的文件通过唯一的描述符进行引用,该描述符是打开文件的元数据到文件本身的映射
  • 在Linux中用一个整数表示

传统I/O阻塞模型

当使用Read或者Write对某个文件描述符FD进行读写时,如果当前FD不可读或不可写,服务就不会对操作进行响应 ,导致整个服务不可用。

截屏2021-01-11 下午8.13.55

多路复用模型

select系统调用

截屏2021-01-11 下午8.16.30

selector系统调用,用于监听文件是否可读可写,会返回所有可读可写文件描述符个数

如此可以把读写监听交给系统调用,程序去做其他事情。

Redis采用的I/O多路复用函数

epoll、kqueue、evport、select

现代的UNIX操作系统提供了select/poll/kqueue/epoll 这样的系统调用,这些系统调用的功能是:你告知我一批套接字(socket),当这些套接字的可读或可写事件发生时,我通知你这些事件信息。

  • 因地制宜
    • redis会优先选择事件复杂度为O(1)的多路复用函数作为底层实现
    • 如优先使用Linux中的epoll,mac os中的kqueue
    • 以时间复杂度为O(n)的select保底
  • 基于reactor设计模式监听I/O事件