Redis服务设计(处理流程、事件模型、多路复用)

摘要:
该模型使用多个I/O复用、非阻塞IO和Redis单线程来处理大量并发客户端连接。服务器和客户端之间的通信将生成相应的文件事件,服务器将通过监听和处理这些事件来完成一系列网络通信操作。
简介

Redis作者: 意大利人 Salvatore Sanfilippo(网名 Antirez) 开发。Antirez 不仅帅的不像实力派,也非常有趣。Antirez 今年已经四十岁了,依旧在孜孜不倦地写代码,为 Redis 的开源事业持续贡献力量。

Redis是一个开放源代码(BSD许可)内存中的数据结构存储,用作数据库、缓存和消息代理。它支持字符串、哈希、列表、集合、带范围查询的排序集合、位图、超日志和流的地理空间索引等数据结构。Redis具有内置的复制、lua脚本、lru回收、事务和不同级别的磁盘上持久性,并通过Redis Sentinel和Redis集群的自动分区提供高可用性。

源码github:github.com/antirez/red…

压测

先通过一段测试来看下Redis的性能如何 Redis 自带了一个压力测试工具redis-benchmark,使用这个工具就可以进行管道测试。

首先我们对一个普通的 set 指令进行压测,QPS 大约 5w/s。

> redis-benchmark -t set -q
SET: 51975.05 requests per second
复制代码

我们加入管道选项-P参数,它表示单个管道内并行的请求数量,看下面P=2,QPS 达到了 9w/s。

> redis-benchmark -t set -P 2 -q
SET: 91240.88 requests per second
复制代码

再看看P=3,QPS 达到了 10w/s。

> redis-benchmark -t set -P 3 -q
SET: 102354.15 requests per second
复制代码

但如果再继续提升 P 参数,发现 QPS 已经上不去了。这是为什么呢?

因为这里 CPU 处理能力已经达到了瓶颈,Redis 的单线程 CPU 已经飙到了 100%,所以无法再继续提升了。

Redis为什么这么快?

正常情况下,Redis执行命令的速度非常快,官方给出的数字是读写性能可以达到10万/秒,当然这也取决于机器的性能,但这里先不讨论机器性能上的差异,只分析一下是什么造就了Redis除此之快的速度,可以大致归纳为以下五点:

Redis是用C语言实现的,一般来说C语言实现的程序“距离”操作系统更近,执行速度相对会更快。

完全基于内存,绝大部分请求是纯粹的内存操作,非常快速。数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1);正因为 Redis 是单线程,所以要小心使用 Redis 指令,对于那些时间复杂度为 O(n) 级别的指令,一定要谨慎使用,一不小心就可能会导致 Redis 卡顿。

数据结构简单,对数据操作也简单,Redis中的数据结构是专门进行设计的;采用单线程,避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗 CPU,不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗。

使用多路I/O复用模型,非阻塞IO,Redis 单线程处理大量的并发客户端连接的模型。使用底层模型不同,它们之间底层实现方式以及与客户端之间通信的应用协议不一样,Redis直接自己构建了VM 机制 ,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求;

作者对于Redis源代码可以说是精打细磨,曾经有人评价Redis是少有的集性能和优雅于一身的开源代码。

知道了Redis为什么这么快的原因,接下来看下redis的实现架构

Redis整体架构

通信架构

第一层:客户端,大家熟知的如原生redis-cli、java语言Jedis、python语言redis-py等

第二层:通信,传输层基于TCP的resp协议

第三层:服务端,多路复用、事件循环、持久化等

Redis服务设计(处理流程、事件模型、多路复用)第1张

流程架构

redis的整体核心在服务端的处理

流程图如下:

Redis服务设计(处理流程、事件模型、多路复用)第2张

epoll:多路复用模型的基础

事件:多路复用的设计方案,包含文件事件和时间事件。 命令处理:连接过程、处理过程、响应过程

上述三点,相辅相成共同构成了redis服务的核心处理流程。

整体流程如下: Client 发起socket连接

Server 接受socket连接

客户端写入

Server端接收写入

Server返回结果

Client收到返回结果

看到这里,对整体流程有个大概的印象了,你可能好奇两个点,一个是Redis事件是什么,第二个是I/O多路复用是什么,下面分别简单的说一下:

Redis事件

文件事件:

Redis通过套接字与客户端(或者其他服务器)进行连接,而文件事件就是服务器对套接字操作的抽象。服务器与客户端的通信会产生相应的文件事件,而服务器则通过监听并处理这些事件来完成一系列的网络通信操作。

Redis基于Reactor模式开发了自己的网络事件处理器:这个处理器则被称为文件时间处理器。

文件事件处理器使用I/O多路复用程序来同时监听多个套接字,并根据套接字目前执行的任务来为套接字关联不同的时间处理器。

当被监听的套接字准备好执行连接应答accept、读取read、写入write、关闭close等操作时,与操作相对应的文件事件就会产生,这时文件事件处理器就会调用套接字之前关联好的事件处理器来处理这些事件。

时间事件:

Redis服务器中一些操作(比如serverCron的函数)则需要在给定的时间点执行,时间事件就是服务器对这类定时操作的抽象。默认一秒执行10次,即100ms执行一次。配置在redis.conf中的hz

serverCron函数的主要工作:

更新服务器的各类统计信息,比如内存占用、数据库占用情况等。

清理数据库中的过期键值对。

关闭和清理链接失效的客户端。

尝试进行AOF或RDB持久化操作。

如果服务器是主服务器,对从服务器进行定时同步。

集群模式,对集群进行定期同步和连接测试。

I/O 多路复用技术

详解:

blog.chinaunix.net/uid-2451754…

实现机制:

blog.csdn.net/shenya1314/…

多种线程模型:同步阻塞、同步非阻塞、多路复用、异步的对比,这里不展开介绍,感兴趣的同学可以自行查看相关资料。

下面介绍一下多路复用中的epoll,Redis事件管理器核心实现基本依赖于它。

epoll是在Linux 2.6内核中引进的,是一种强大的I/O多路复用技术,上面我们已经说到在进行网络操作的时候是通过文件描述符来进行读写的,那么平常我们就是一个进程操作一个文件描述符。然而epoll可以通过一个文件描述符管理多个文件描述符,并且不阻塞I/O。这使得我们单进程可以操作多个文件描述符,这就是redis在高并发性能还如此强大的原因之一。

下面简单介绍epoll 主要的三个方法:

int epoll_create(int size) //创建一个epoll句柄用于监听文件描述符FD,size用于告诉内核这个监听的数目一共有多大。该epoll句柄创建后在操作系统层面只会占用一个fd值,但是它可以监听size+1 个文件描述符

int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event) //epoll事件注册函数,在创建文件事件的时候进行调用注册

int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout)//等待事件的产生

Redis 的事件管理器主要是基于epoll机制,先采用 epoll_ctl方法 注册事件,然后再使用epoll_wait方法取出已经注册的事件。

以上就是本篇文章的全部内容,感谢您的阅读,如果您在其中发现任何不正确或者不严谨的描述,欢迎指正。

免责声明:文章转载自《Redis服务设计(处理流程、事件模型、多路复用)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Dynamics AX 2012 R3 Demo 安装与配置Django实战(二)之模板语言下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

redis常见命令

一、介绍 1、Redis是什么 REmote DIctionary Server(Redis) 是一个由Salvatore Sanfilippo写的key-value存储系统。Redis提供了一些丰富的数据结构,包括 lists, sets, ordered sets 以及 hashes ,当然还有和Memcached一样的 strings结构.Redis当...

高性能NoSQL

极客时间:《从 0 开始学架构》:高性能NoSQL 1、引言 关系型数据库凭借着SQL功能和ACID的属性,活跃于各种各样的系统中,但它并不是完美的,其存在以下缺点: 关系数据库存储的是行记录,无法存储数据结构 关系数据库的 schema 扩展很不方便关系数据库的表结构 schema 是强约束,操作不存在的列会报错,业务变化时扩充列也比较麻烦,需要执行...

Python使用Redis

Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。Redis支持存储的value类型包括字符串(String), 哈希(Hash), 列表(list), 集合(set) 和 有序集合(sorted set)。 Redis官方文档:https://redis.io Red...

docker应用、搭建、container、image、搭建私有云docker registry、容器通信、端口映射、多机多容器通信、数据持久化、docker部署wordpress、docker compose使用、负载均衡、docker Swarm、docker云部署

docker一、 容器技术和docker简介 1. 部署演变 l 在一台物理机部署Application l 虚拟化技术 2. 容器的必要性 l 开发人员开发一个Application需要各种环境,各种依赖 l 运维人员部署Application时也需要搭建各种环境 3. 容器解决的问题 l 解决了开发和运维之间的矛盾 4. 容器是什么 l 对软...

redis慢查询的简单认识和事务、订阅的认识

  有学习的小伙伴可以一起讨论有问题可以问我,微信 15321502296慢查询 阀值:规定的一个值 阈值:规定的一个范围 就是系统在执行命令前后计算每条命令的执行时间,当超过预设的阀值时,就见这条命令记录下来 slowlog-log-slower-than  微秒 1秒=1000毫秒=1000000微秒 0 记录所有命令 <0不进行记录 slowl...

windows下docker的安装及常用命令学习

docker search 镜像名     本文主要介绍Docker在Windows下的安装。关于Docker的介绍和文档在其官网中可以找到:http://www.docker.com 。安装环境:Windows7。   Docker引擎使用了一个定制的Linux内核,所以要在Windows下运行Docker我们需要用到一个轻量级的虚拟机(vm),我们使用...