Redis作为一个基于key-value的NoSQL数据库,最显著的特点存取速度非常快,官方说可以达到10W OPS,但是Redis为何这么快?

1、开发语言

Redis使用C语言进行编写的,而Unix系统也是C语言实现,所以C语言是非常贴近操作系统的语言

2、基于内存读写

基于内存读写是Redis速度快的主要原因,不进行数据同步的情况下,不从磁盘读取数据,没有IO。内存响应时间大约100ns

3、单线程

  1).单线程避免了线程上下文切换以及同步加锁、解锁带来的消耗。

  2).单线程简化算法的实现

  3).单线程也带来一个问题,阻塞,对于一个长命令来说,会阻塞很多命令的执行响应

这里的单线程,不包含fork()产生的子进程。除了Redis之外,Node.js、Nginx都是单线程,都属于高性能的组件框架

4、多路I/O复用模型

  由于Redis是单线程的,所有的操作都是串行执行,但是由于读写操作等待用户输入或输出都是阻塞的,所以 I/O 操作在一般情况下往往不能直

接返回,这会导致某一文件的 I/O 阻塞导致整个进程无法对其它客户提供服务,而 I/O 多路复用就是为了解决这个问题而出现的。

  Redis的I/O模型基于epoll实现,也提供select和kqueue的实现,默认epoll

epoll相对于其他多路复用技术,具有的优点:

  1. epoll没有最大并发连接的限制,上限是最大可以打开文件的数目,这个数字一般远大于 2048

  2. 效率提升,epoll最大的优点就在于它只管你“活跃”的连接,而跟连接总数无关,因此在实际的网络环境中, epoll的效率就会远远高于

select和poll

  3. 内存拷贝,epoll在这点上使用了“共享内存 ”,这个内存拷贝也省略了。

epoll与select/poll的区别:

I/O多路复用:通过一种机制,可以监视多个描述符(File Descriptor,简称fd),一旦某个描述符就绪,能够通知程序进行相应的操作。

1、select:

  本质是采用32个整数的32位,即32*32 = 1024来标识,fd值为1-1024。当fd的值超过1024限制时,就必须修改FD_SETSIZE的大小。这个时候就

可以标识32*max值范围的fd。

2、poll:

  poll与select不同,通过一个pollfd数组向内核传递需要关注的事件,故没有描述符个数的限制,pollfd中的events字段和revents分别用于

标示关注的事件和发生的事件,故pollfd数组只需要被初始化一次。

3、epoll:

  是poll的一种优化,返回后不需要对所有的fd进行遍历,在内核中维持了fd的列表。select和poll是将这个内核列表维持在用户态,然后传递

到内核中。与poll/select不同,epoll不再是一个单独的系统调用,而是由epoll_create/epoll_ctl/epoll_wait三个系统调用组成,后面将会看到

这样做的好处。epoll在2.6以后的内核才支持。

select/poll的几大缺点:

  1、每次调用select/poll,都需要把fd集合从用户态拷贝到内核态,这个开销在fd很多时会很大

  2、同时每次调用select/poll都需要在内核遍历传递进来的所有fd,这个开销在fd很多时也很大

  3、针对select支持的文件描述符数量太小了,默认是1024

  4.select返回的是含有整个句柄的数组,应用程序需要遍历整个数组才能发现哪些句柄发生了事件;

  5.select的触发方式是水平触发,应用程序如果没有完成对一个已经就绪的文件描述符进行IO操作,那么之后每次select调用还是会将这些文

件描述符通知进程。相比select模型,poll使用链表保存文件描述符,因此没有了监视文件数量的限制,但其他三个缺点依然存在。

epoll IO多路复用模型实现机制:

  由于epoll的实现机制与select/poll机制完全不同,上面所说的 select的缺点在epoll上不复存在。

  epoll没有这个限制,它所支持的FD上限是最大可以打开文件的数目,这个数字一般远大于2048,举个例子,在1GB内存的机器上大约是10万左右

  设想一下如下场景:有100万个客户端同时与一个服务器进程保持着TCP连接。而每一时刻,通常只有几百上千个TCP连接是活跃的(事实上大部

分场景都是这种情况)。

如何实现这样的高并发?

  在select/poll时代,服务器进程每次都把这100万个连接告诉操作系统(从用户态复制句柄数据结构到内核态),让操作系统内核去查询这些套

接字上是否有事件发生,轮询完后,再将句柄数据复制到用户态,让服务器应用程序轮询处理已发生的网络事件,这一过程资源消耗较大,因此,

select/poll一般只能处理几千的并发连接。

  如果没有I/O事件产生,我们的程序就会阻塞在select处。但是依然有个问题,我们从select那里仅仅知道了,有I/O事件发生了,但却并不知

道是那几个流(可能有一个,多个,甚至全部),我们只能无差别轮询所有流,找出能读出数据,或者写入数据的流,对他们进行操作。但是使用

select,我们有O(n)的无差别轮询复杂度,同时处理的流越多,每一次无差别轮询时间就越长

epoll的设计和实现与select完全不同。epoll通过在Linux内核中申请一个简易的文件系统(文件系统一般用什么数据结构实现?B+树)。把原先的

select/poll调用分成了3个部分:

  1)调用epoll_create()建立一个epoll对象(在epoll文件系统中为这个句柄对象分配资源)

  2)调用epoll_ctl向epoll对象中添加这100万个连接的套接字

  3)调用epoll_wait收集发生的事件的连接

  如此一来,要实现上面说是的场景,只需要在进程启动时建立一个epoll对象,然后在需要的时候向这个epoll对象中添加或者删除连接。同时,

epoll_wait的效率也非常高,因为调用epoll_wait时,并没有一股脑的向操作系统复制这100万个连接的句柄数据,内核也不需要去遍历全部的连接。

epoll内容原文地址:https://blog.csdn.net/wxy941011/article/details/80274233

Redis系列(六)--为什么这么快?的更多相关文章

  1. Redis系列(六):设置/移除键的过期时间

    本篇博客是Redis系列的第6篇,主要讲解以下内容: 数据库数量 切换目标数据库 设置键的过期时间 移除键的过期时间 本系列的前5篇可以点击以下链接查看: Redis系列(一):Redis简介及环境安 ...

  2. Redis系列(六)-SortedSets设计技巧

    阅读目录: 介绍 Score占位 更多位信息 总结 介绍 Redis Sorted Sets是类似Redis Sets数据结构,不允许重复项的String集合.不同的是Sorted Sets中的每个成 ...

  3. Redis系列六:redis相关功能

    一. 慢查询原因分析 与mysql一样:当执行时间超过阀值,会将发生时间耗时的命令记录 redis命令生命周期:发送 排队 执行 返回慢查询只统计第3个执行步骤的时间 预设阀值:两种方式,默认为10毫 ...

  4. Redis系列六 - 浅谈如何设计秒杀系统

    前言 设计一个系统之前,我们肯定要先确认系统业务场景是怎样的,下面就以某电商平台上的秒杀活动为场景,一起来探讨一个秒杀系统改如何去设计. 场景 我们现在要卖100件纸尿布,按照系统的用户量及以往经验来 ...

  5. Redis系列六 Redis事务

    Redis事务 1.介绍 在Redis事务中可以一次执行多个命令,本质是一组命令的集合.一个事务中的所有命令都会序列化,按顺序地串行化执行而不会被其它命令插入,不许加塞. 2.事务的作用 一个队列中, ...

  6. Redis系列之key操作命令与Redis中的事务详解(六)

    序言 本篇主要目的有二: 1.展示所有数据类型中key的所有操作命令,以供大家学习,查阅,更深入的挖掘redis潜力. 2.掌握redis中的事务,让你的数据完整性一致性拥有更优的保障. redis命 ...

  7. Redis系列(三):Redis的持久化机制(RDB、AOF)

    本篇博客是Redis系列的第3篇,主要讲解下Redis的2种持久化机制:RDB和AOF. 本系列的前2篇可以点击以下链接查看: Redis系列(一):Redis简介及环境安装. Redis系列(二): ...

  8. Redis系列(2)之数据类型

    Redis系列(2)之数据类型 <Redis系列(1)之安装>中介绍了Redis支持以下几种数据类型,那么本节主要介绍学习下这几种数据类型的基本操作 字符串类型,string 散列类型,h ...

  9. Python操作redis系列之 列表(list) (四)

    # -*- coding: utf- -*- import redis r =redis.Redis(host=,password="ZBHRwlb1608") 1. Lpush ...

随机推荐

  1. Watcher 实现机制之client注冊

    Zookeeper 提供的了分布式数据的公布/订阅功能,通过 Watch 机制来实现这样的分布式的通知功能. Zookeeper 同意client向server注冊一个Watch监听.当服务端的一些指 ...

  2. Grails边做边学入门篇[1]--------大家一起来动手建立project和Domain

    近期工作比較忙,没空写博客了.我发现每周五的下午都是我最放松的时候,可能是迟延症的缘故吧...总是寄希望于周末,慢慢的.我的周末就被工作占领了. 希望大家不要有这种坏毛病.今日事,今日毕.当然我们程序 ...

  3. Codeforces Round #322 (Div. 2) D. Three Logos 模拟

                                                      D. Three Logos Three companies decided to order a ...

  4. 【bzoj4592】[Shoi2015]脑洞治疗仪

    由于脑洞的序列不会改变,考虑用线段树维护区间内sum,左边0的个数,右边0的个数,区间内最大脑洞.对于查询l~r最大脑洞可以将l~r分成logn个区间,总复杂度O(nlogn). #include&l ...

  5. 【HNOI模拟By lyp】Day1

    1 xlk1.1 题目描述 给定一棵大小为 n 的无根树,求满足以下条件的四元组 (a, b, c, d) 的个数: 1. 1 ≤ a < b ≤ n 2. 1 ≤ c < d ≤ n 3 ...

  6. mac ox终端显示 bogon的问题

    mac终端显示如果正常应该是电脑名称(偏好设置-共享)的,但是细心的我们会发现,当电脑换了网络环境之后,可能就会出现终端上显示为主机名为:bogon,一查bogon这个单词是虚拟.虚伪的意思.     ...

  7. SQLALchemy之介绍,基本使用

    一.介绍 SQLALchemy也是一个python的ORM框架,django内部的ORM框架只适用于django,而SQLALchemy适用于所有python的web框架 SQLAlchemy是一个基 ...

  8. odb_sqlite_demo

    #include <iostream>       #include <odb/database.hxx>   #include <odb/transaction.hxx ...

  9. CodeForces 382C Arithmetic Progression (排序+分类讨论)

    题意:给出一个长度为n的序列,表示有n张卡片,上面的数字,现在还有一张卡片,上面没有数字,问说可以写几种数字在这张卡片上面, 使得n+1张卡片上的数字可以排列成一个等差数列,有无限多种时输出-1. 析 ...

  10. AutoCAD C# 利用反射导出所注册的命令

    主函数导出某一程序集AutoCAD 注册命令 /// <summary> ///提取所有的命令 /// </summary> /// <param name=" ...