一.开发语言

二.纯内存访问

三.单线程

四.非阻塞多路I/O复用机制

前言

Redis是一种基于键值对(Key-Value)的NoSQL数据库 ,Redis的Value可以由String,hash,list,set,zset,Bitmaps,HyperLogLog等多种数据结构和算法组成。

Redis还提供了键过期,发布订阅,事务,Lua脚本,哨兵,Cluster等功能。 Redis执行命令的速度非常快,根据官方给的性能可以达到10w+qps。

那么本文主要介绍到底Redis快在哪里,主要有以下几点:

一、开发语言

现在我们都用高级语言来编程,比如Java、python等。也许你会觉得C语言很古老,但是它真的很有用,毕竟unix系统就是用C实现的,所以C语言是非常贴近操作系统的语言。 Redis就是用C语言开发的,所以执行会比较快。

另外多说一句,大学生们好好学C,会让你更好的理解计算机操作系统。别觉得学了高级语言就可以不用关注底层,欠的债总归要还的。此处推荐一本比较难啃的书《深入理解计算系统》。

二、纯内存访问

Redis将所有数据放在内存中,非数据同步正常工作中,是不需要从磁盘读取数据的,0次IO。 内存响应时间大约为100纳秒,这是Redis速度快的重要基础。 先看看CPU的速度:

拿我的电脑来说,主频是3.1G,也就是说每秒可以执行3.1*10^9个指令。所以说CPU看世界是非常非常慢的,内存比它慢百倍,磁盘比他慢百万倍,你说快不快?

借了一张《深入理解计算机系统》的图,展示了一个典型的存储器层次结构, 在L0层,CPU可以在一个时钟周期访问到,基于SRAM的高速缓存存续期,可以在几个CPU时钟周期访问到,然后是基于DRAM的主存,可以在几十到几百个时钟周期访问到他们。

三、单线程

第一, 单线程简化算法的实现 ,并发的数据结构实现不但困难且测试也麻烦。第二, 单线程避免了线程切换以及加锁释放锁带来的消耗 ,对于服务端开发来说,锁和线程切换通常是性能杀手。

当然了,单线程也会有它的缺点,也是Redis的噩梦:阻塞。 如果执行一个命令过长,那么会造成其他命令的阻塞,对于Redis是十分致命的 ,所以Redis是面向快速执行场景的数据库。

除了Redis之外,Node.js也是单线程,Nginx也是单线程,但他们都是服务器高性能的典范。

四、非阻塞多路I/O复用机制

在这之前先要说一下传统的阻塞I/O是如何工作的:当使用read或者write对某一文件描述符(File Descriptor FD)进行读写的时候,如果数据没有收到,那么该线程会被挂起,直到收到数据。 阻塞模型虽然易于理解,但是在需要处理多个客户端任务的时候,不会使用阻塞模型。

I/O多路复用实际上是指多个连接的管理可以在同一进程。 多路是指网络连接,复用只是同一个线程。在网络服务中,I/O多路复用起的作用是一次性把多个连接的事件通知业务代码处理,处理的方式由业务代码来决定。

在I/O多路复用模型中,最重要的函数调用就是I/O 多路复用函数,该方法能同时监控多个文件描述符(fd)的读写情况,当其中的某些fd可读/写时,该方法就会返回可读/写的fd个数。

Redis使用epoll作为I/O多路复用技术的实现,再加上Redis自身的事件处理模型将epoll的read、write、close等都转换成事件,不在网络I/O上浪费过多的时间。 实现对多个FD读写的监控,提高性能。

举个形象的例子吧。比如一个tcp服务器处理20个客户端socket。

A方案:顺序处理,如果第一个socket因为网卡读数据处理慢了,一阻塞后面都玩蛋去。

B方案:每个socket请求都创建一个分身子进程来处理,不说每个进程消耗大量系统资源,光是进程切换就够操作系统累的了。

C方案(I/O复用模型,epoll):将用户socket对应的fd注册进epoll(实际上服务器和操作系统之间传递的不是socket的fd而是fd_set的数据结构),然后epoll只告诉哪些需要读/写的socket,只需要处理那些活跃的、有变化的socket fd的就好了。这样,整个过程只在调用epoll的时候才会阻塞,收发客户消息是不会阻塞的。

《四大点,搞懂Redis到底快在哪里?》的更多相关文章

  1. 简单物联网:外网访问内网路由器下树莓派Flask服务器

    最近做一个小东西,大概过程就是想在教室,宿舍控制实验室的一些设备. 已经在树莓上搭了一个轻量的flask服务器,在实验室的路由器下,任何设备都是可以访问的:但是有一些限制条件,比如我想在宿舍控制我种花 ...

  2. 利用ssh反向代理以及autossh实现从外网连接内网服务器

    前言 最近遇到这样一个问题,我在实验室架设了一台服务器,给师弟或者小伙伴练习Linux用,然后平时在实验室这边直接连接是没有问题的,都是内网嘛.但是回到宿舍问题出来了,使用校园网的童鞋还是能连接上,使 ...

  3. 外网访问内网Docker容器

    外网访问内网Docker容器 本地安装了Docker容器,只能在局域网内访问,怎样从外网也能访问本地Docker容器? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Docker容器 ...

  4. 外网访问内网SpringBoot

    外网访问内网SpringBoot 本地安装了SpringBoot,只能在局域网内访问,怎样从外网也能访问本地SpringBoot? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装Java 1 ...

  5. 外网访问内网Elasticsearch WEB

    外网访问内网Elasticsearch WEB 本地安装了Elasticsearch,只能在局域网内访问其WEB,怎样从外网也能访问本地Elasticsearch? 本文将介绍具体的实现步骤. 1. ...

  6. 怎样从外网访问内网Rails

    外网访问内网Rails 本地安装了Rails,只能在局域网内访问,怎样从外网也能访问本地Rails? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Rails 默认安装的Rails端口 ...

  7. 怎样从外网访问内网Memcached数据库

    外网访问内网Memcached数据库 本地安装了Memcached数据库,只能在局域网内访问,怎样从外网也能访问本地Memcached数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装 ...

  8. 怎样从外网访问内网CouchDB数据库

    外网访问内网CouchDB数据库 本地安装了CouchDB数据库,只能在局域网内访问,怎样从外网也能访问本地CouchDB数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Cou ...

  9. 怎样从外网访问内网DB2数据库

    外网访问内网DB2数据库 本地安装了DB2数据库,只能在局域网内访问,怎样从外网也能访问本地DB2数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动DB2数据库 默认安装的DB2 ...

  10. 怎样从外网访问内网OpenLDAP数据库

    外网访问内网OpenLDAP数据库 本地安装了OpenLDAP数据库,只能在局域网内访问,怎样从外网也能访问本地OpenLDAP数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动 ...

随机推荐

  1. android之Tween Animation

    android Tween Animation有四种,AlphaAnimation(透明度动画).ScaleAnimation(尺寸伸缩动画).TranslateAnimation(位移动画).Rot ...

  2. IO系列测试源码

    //IO系列测试源码(需要自取) using System; using System.CodeDom; using System.Collections.Generic; using System. ...

  3. blazor发布之后 刷新404的解决方法

    其实所有单页面应用都一样 只需要在nginx里面配置 location / { root html; index index.html index.htm; rewrite ^/.*/$ / last ...

  4. Vulkan移植GPUImage(五)从P到Z的滤镜

    现aoce_vulkan_extra把GPUImage里从P到Z的大部分滤镜用vulkan的ComputeShader实现了,也就是最后一部分的移植,整个过程相对前面来说比较简单,大部分我都是直接复制 ...

  5. Spring Cloud Gateway之全局过滤器在工作中的使用场景

    一.使用注意事项 1.全局过滤器作用于所有的路由,不需要单独配置. 2.通过@Order来指定执行的顺序,数字越小,优先级越高. 二.默认全局拦截器的整体架构 三.实战场景,例如,校验token.记录 ...

  6. Visual Studio/VS中任务列表的妙用

    一.任务列表开启方法 首先说下开启的方法:视图-任务列表,即可打开任务列表. 快捷键Ctrl+'\'+T,熟练了可以快速开启.注意,'\'键是回车键上面的'',不要按成了'/' 二.任务列表标签设置 ...

  7. JSX语法详解

    一.基础1.JSX是什么JSX是一种像下面这样的语法: const element = <h1>Hello, world!</h1>;1它是一种JavaScript语法扩展,在 ...

  8. Python 送你一棵圣诞树

    Python 送你一棵圣诞树 2019-01-02阅读 8800   今天是圣诞节,先祝大家圣诞快乐!??? 有人要说了,圣诞节是耶稣诞生的日子,我又不信基督教,有啥好庆祝的.这你就有所不知了,Pyt ...

  9. rpm命令的简介-(转自jb51.net )

    在Linux操作系统中,有一个系统软件包,它的功能类似于Windows里面的"添加/删除程序",但是功能又比"添加/删除程序"强很多,它就是Red Hat Pa ...

  10. 完全理解Python 迭代对象、迭代器、生成器

    在了解Python的数据结构时,容器(container).可迭代对象(iterable).迭代器(iterator).生成器(generator).列表/集合/字典推导式(list,set,dict ...