欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

为什么单线程的Redis这么快?

程序员文章站 2022-04-28 11:43:25
一. Redis简介 Redis是一个开源的内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。 它支持多种类型的数据结构,如 字符串(strings), 散列(hashes), 列表(lists), 集合(sets), 有序集合(sorted sets)等。 二. Redis为什么这么快 ......

一. redis简介

redis是一个开源的内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。 它支持多种类型的数据结构,如 字符串(strings), 散列(hashes), 列表(lists), 集合(sets), 有序集合(sorted sets)等。

二. redis为什么这么快

  1. 完全基于内存,绝大部分请求是纯粹的内存操作。 
  2. 数据结构简单,对数据操作也简单,redis中的数据结构是专门进行设计的。 
  3. 采用单线程,避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗 cpu,不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗。  
  4. 使用多路i/o复用模型,非阻塞io。 
  5. 使用底层模型不同,它们之间底层实现方式以及与客户端之间通信的应用协议不一样,redis直接自己构建了vm 机制 ,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求。

三. 多路i/o复用模型

多路i/o复用模型是利用 select、poll、epoll 可以同时监察多个流的 i/o 事件的能力,在空闲的时候,会把当前线程阻塞掉,当有一个或多个流有 i/o 事件时,就从阻塞态中唤醒,于是程序就会轮询一遍所有的流(epoll 是只轮询那些真正发出了事件的流),并且只依次顺序的处理就绪的流,这种做法就避免了大量的无用操作。  
  这里“多路”指的是多个网络连接,“复用”指的是复用同一个线程。采用多路 i/o 复用技术可以让单个线程高效的处理多个连接请求(尽量减少网络 io 的时间消耗),且 redis 在内存中操作数据的速度非常快,也就是说内存内的操作不会成为影响redis性能的瓶颈,主要由以上几点造就了 redis 具有很高的吞吐量。

下面举一个例子,模拟一个tcp服务器处理30个客户socket。假设你是一个老师,让30个学生解答一道题目,然后检查学生做的是否正确,你有下面几个选择:

  1. 第一种选择:按顺序逐个检查,先检查a,然后是b,之后是c、d。。。这中间如果有一个学生卡主,全班都会被耽误。这种模式就好比,你用循环挨个处理socket,根本不具有并发能力。
  2. 第二种选择:你创建30个分身,每个分身检查一个学生的答案是否正确。 这种类似于为每一个用户创建一个进程或者线程处理连接。
  3. 第三种选择,你站在讲台上等,谁解答完谁举手。这时c、d举手,表示他们解答问题完毕,你下去依次检查c、d的答案,然后继续回到讲台上等。此时e、a又举手,然后去处理e和a。。。 这种就是io复用模型,linux下的select、poll和epoll就是干这个的。将用户socket对应的fd注册进epoll,然后epoll帮你监听哪些socket上有消息到达,这样就避免了大量的无用操作。此时的socket应该采用非阻塞模式。这样,整个过程只在调用select、poll、epoll这些调用的时候才会阻塞,收发客户消息是不会阻塞的,整个进程或者线程就被充分利用起来,这就是事件驱动,所谓的reactor模式。

四. 单进程单线程好处

  1. 代码更清晰,处理逻辑更简单
  2. 不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗
  3. 不存在多进程或者多线程导致的切换而消耗cpu

多路i/o复用模型例子参考:https://www.zhihu.com/question/28594409/answer/52835876


下面的是我的公众号二维码图片,欢迎关注,欢迎留言,一起学习,一起进步。

为什么单线程的Redis这么快?