redis:深剖redis的单线程架构

电玩女神 2022-09-15 06:02 311阅读 0赞

redis使用了单线程架构和IO多路复用模型来实现高性能的内存数据库服务

单线程模型

现在开启了三个redis-cli客户端同时执行命令

  • 客户端1设置了一个字符串键值对

    set hello world

  • 客户端2对counter自增

    incr counter

  • 客户端3对counter自增

    incr counter

redis客户端和服务端的模型可以简化成下图,每次客户端调用都经历了发送命令、执行命令、返回结果三个过程
在这里插入图片描述我们说的单线程就是在第二步执行命令,一条命令从从客户端达到服务端不会立刻被执行,而是会进入一个队列中等待,每次只会有一条指令被选中执行。上面三个客户端命令的执行顺序是不确定的,如下图。
在这里插入图片描述

但是可以确定不会同时有两条命令被同时执行,如下图。所以两条incr命令无论怎么怎么执行都不会有并发问题

在这里插入图片描述

为什么单线程还能怎么块

为什么单线程还能怎么块

  • 第一:纯内存访问,redis将所有数据放在内存中,内存的响应时长大约为100纳秒,这是Redis达到每秒万级别访问的最重要的基础。
  • 第二:非阻塞IO,redis使用epoll作为IO多路复用技术的实现,在加上redis自身的事件处理模型将epoll中的连接、读写、关闭都转换为事件,不在网络IO浪费时间
    在这里插入图片描述

这里再扩展一下I/O多路复用:

引用知乎上一个高赞的回答来解释什么是I/O多路复用。假设你是一个老师,让30个学生解答一道题目,然后检查学生做得是否正确,你有下面几个选择:

  • 第一种选择:按顺序逐个检查,先检查A,然后是B,之后是C、D。。。这中间如果有一个学生卡主,全班都会被耽误。这种模式就好比,你用循环挨个处理socket,根本不具有并发能力。
  • 第二种选择:你创建30个分身,每个分身检查一个学生的答案是否正确。 这种类似于为每一个用户创建一个进程或者线程处理连接。
  • 第三种选择,你站在讲台上等,谁解答完谁举手。这时C、D举手,表示他们解答问题完毕,你下去依次检查C、D的答案,然后继续回到讲台上等。此时E、A又举手,然后去处理E和A

第一种就是阻塞IO模型,第三种就是I/O复用模型,Linux下的select、poll和epoll就是干这个的。将用户socket对应的fd注册进epoll,然后epoll帮你监听哪些socket上有消息到达,这样就避免了大量的无用操作。此时的socket应该采用非阻塞模式

这样,整个过程只在调用select、poll、epoll这些调用时才会阻塞,收发客户消息是不会阻塞的,整个进程或者线程就被充分利用起来,这就是事件启动,所谓的reactor模式

  • 第三:单线程可以简化数据结构和算法的实现;单线程避免了线程切换和竞态产生的消耗

对于服务器开发来说,锁和线程切换通常是性能杀手

单线程带来的问题

对于每个命令的执行时间是由要求的。如果某个命令执行过长,会造成其他命令的阻塞,对于redis这样的高性能服务来说是致命的,所以redis是面向快速执行场景的服务器

支持多线程的Redis6.0

Redis6.0引入了多线程的特性,这个多线程是在哪里呢?—— 是对处理网络请求过程采用了多线程

redis6.0采用多个IO线程来处理网络请求,网络请求的解析可以由线程完成,然后把解析后的请求交给主线程进行实际的内存读写。提升网络请求处理的并行度,进而提升整体性能

在这里插入图片描述

发表评论

表情:
评论列表 (有 0 条评论,311人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Redis单线理解

    简介 从接触Redis到现在,一直被它的单线程问题困扰,这对于一个苛求原理的我来说是种折磨,今天吃饭途中看了几篇博客,茅塞顿开。 个人理解         red