IO 模型 线程模型 高性能网络

image.png

## Redis高性能
- Redis是单线程的含义
  - 单线程执行命令 — 单线程的含义所在
  - 别的线程会处理数据同步,持久化等任务
  - 6.0之后引入了多线程
  - 归根结底是多线程
- epoll
  - 作用:增删改查文件描述符
  - 结构
    - 红黑树维护了全部监控文件描述符
    - 双向链表维护住了满足条件的文件描述符(就绪列表)
  - 关键API
    - epoll_create — 初始化epoll结构
    - epoll_ctl
      - 增删改文件描述符
      - 告知epoll实例,自己关心什么事件
    - epoll_wait
      - 查找获得满足条件的文件描述符
      - 可能的情况
        - 有满足条件的文件描述符,直接返回
        - 没有
	        - 超时是-1,阻塞等待,直到拿到文件描述符
          - 超时是0,立刻返回
          - 超时是正数
            - 在超时时间内,拿到了文件描述符
            - 超时
	    - 中断
	      - 驱动利用中断来告知epoll数据来了
	      - 利用时钟中断来得知超时
- 面试要点
  - poll和select:轮询文件描述符;超时机制
  - Reactor
    - 分发给 + 处理器
    - 组件
      - Reactor(dispatcher):分发事件
      - Acceptor:接收请求
      - Handler:处理事件
    - 单线程Redis — 使用epoll来获得事件;单线程扮演了全部角色
  - 为什么Memcache使用多线程?
    - 多线程
      - 优势:充分利用多核CPU性能
      - 劣势:上下文切换;模型复杂,难以理解
    - 单线程
      - 优势:没有上线文切换;Redis性能瓶颈不在CPU
      - 劣势:无法利用多核CPU性能
  - 为什么Redis要引入多线程?
    - 充分利用多核性能,让主线程集中执行命令
    - 组件
      - 主线程:可读客户端列表;可写客户端列表;IO线程
    - Reactor模型
      - 主线程负责接收时间并且分发
      - IO线程从可读/可写列表里拿到客户端连接,执行读写
      - IO线程读到的命令,交给主线程执行
      - 主线程执行完毕的响应,交给IO线程写回