Redis的高性能之谜

2023-09-21 09:06:19
9d797a46b38161ea88f8ded8fa0e7c14.png

介绍

Redis通常用作缓存。当一致性要求不高时,它也可以用作存储。此外,Redis还提供消息订阅、事务、索引等功能。我们还可以使用集群功能构建分布式存储服务,并实现非强一致性的分布式锁服务。

在上述各种情况下,Redis都具有一个共同的优势,即处理速度快(高性能)。

Redis有多快?

要了解Redis有多快,您需要有一个评估工具。

幸运的是,Redis提供了这样一个工具,并提供了一些常用硬件平台的性能数据。

1.Redis基准测试可用于评估Redis的性能。命令行提供了在正常/管道模式下以及在不同压力下评估特定命令性能的功能。2.Redis具有出色的性能。作为键值系统,最大负载级别为10W / s,设置和获取时间消耗级别分别为10ms和5ms。使用流水线可以提高Redis操作的性能。

redis-benchmark -t set,lpush -n 100000 -q
SET: 97087.38 每秒请求 //处理97000次设置请求每秒
LPUSH: 101112.23 每秒请求 //处理100000次lpush请求每秒

脚本执行时间

redis-benchmark -n 100000 -q script load "redis.call('set','foo','bar')"
SCRIPT load redis.call('set','foo','bar'): 101317.12 每秒请求, p50=0.255毫秒

默认情况下,Redis基准测试使用100,000个请求、50个客户端和3字节的负载进行测试。

Redis为何如此之快?

Redis是单线程应用程序,这意味着Redis使用单个线程来处理客户端的请求。

Redis具有高性能的原因如下:

•内存存储:Redis使用内存(内存中)存储,没有磁盘I/O开销。•单线程实现:Redis使用单个线程处理请求,避免了多线程之间的线程切换和锁资源争用的成本。•非阻塞I/O:Redis使用多路复用I/O技术,在poll、epoll和kqueue中选择最佳的I/O实现。•优化的数据结构:Redis具有许多经过优化的数据结构实现,可以直接应用。应用层可以直接使用本机数据结构以提高性能。

单线程

Redis的核心网络模型由单线程实现,这在一开始时曾引起了许多人的困惑。Redis官方对此的回答是:

CPU很少成为Redis的瓶颈,因为通常Redis要么是内存绑定的,要么是网络绑定的。例如,使用管道在运行在平均Linux系统上的Redis上,每秒可以传输甚至100万个请求,因此,如果您的应用程序主要使用O(N)或O(log(N))命令,它几乎不会使用太多CPU。

单线程的好处是什么?

1.无需线程创建或线程销毁引起的消耗2.避免线程切换引起的CPU消耗3.避免线程之间的竞争问题,如添加锁、释放锁、死锁等

此外,单线程机制极大地降低了Redis内部实现的复杂性。哈希的延迟重哈希、Lpush等“线程不安全”命令可以在无锁的情况下执行。

I/O模型

一般来说,I/O操作分为两个步骤:

1.等待数据从网络到达,然后将其加载到内核空间缓冲区2.将数据从内核空间缓冲区复制到用户空间缓冲区

根据这两个步骤是否阻塞线程,可以将其分为阻塞/非阻塞、同步/异步。

阻塞I/O模型

I/O最常见的模型是阻塞I/O模型,我们迄今为止在文本中使用的所有示例都使用了阻塞I/O模型。默认情况下,所有套接字都是阻塞的。

02d0407cb26b0751dad51134ce961ad4.png
 

在此示例中,我们使用UDP而不是TCP,因为对于UDP,数据“准备”以供读取的概念很简单:要么接收到整个数据报,要么没有。

而对于TCP,情况会更加复杂,因为还涉及到额外的变量,如套接字的低水位标记等。

非阻塞I/O模型

当我们将套接字设置为非阻塞时,我们告诉内核“当我请求的I/O操作不能在不使进程进入休眠的情况下完成时,请不要使进程进入休眠,而是返回一个错误”。

041e9a7f0a18b1aba92df7dd0e3f679c.png
 

前三次调用recvfrom时,没有数据返回,因此内核立即返回EWOULDBLOCK错误。第四次调用recvfrom时,数据报准备好了,它

被复制到我们的应用程序缓冲区中,recvfrom成功返回。然后我们处理数据。

当应用程序循环调用非阻塞描述符上的recvfrom时,这称为轮询。应用程序不断轮询内核,以查看某个操作是否准备好。这通常会浪费CPU时间,但通常在专用于一项功能的系统上遇到这种模型。

多路复用I/O模型

使用I/O多路复用时,我们调用select或poll并在这两个系统调用中的一个中阻塞,而不是在实际I/O系统调用中阻塞。

5edad328c3504e620e246da6beceab56.png
 

我们在调用select中阻塞,等待数据报套接字可读。当select返回套接字可读时,我们然后调用recvfrom将数据报复制到我们的应用程序缓冲区中。

与阻塞I/O相比,使用select似乎没有任何优势,实际上,由于使用select需要两个系统调用而不是一个,因此实际上存在轻微的劣势。

但使用select的优势在于,我们可以等待多个描述符准备就绪。

现在让我们看看Redis如何处理客户端连接?

通常,Redis使用反应器设计模式,封装了多个实现(select、epoll、kqueue等)以多路复用IO来处理来自客户端的请求。

3b624a9ccd7a2280efeebe94845d507d.png
 

反应器设计模式通常用于实现事件驱动。此外,Redis在不同平台上封装了不同的多路复用IO库。

Redis将优先选择时间复杂度为O(1)的I/O多路复用函数作为底层实现,包括Solaris 10中的evport、Linux中的epoll和Mac OS / FreeBSD中的kqueue。

这些函数都使用内核的内部结构,并可以为数十万个文件描述符提供服务。

但是,如果当前的编译环境没有上述函数,将选择select作为备选方案。因为在使用时会扫描所有受监视的描述符,所以其时间复杂度较差O(n),同时一次只能为1024个文件描述符提供服务,因此通常不作为首选方案使用。

更多推荐

网络安全(黑客)自学

前言:想自学网络安全(黑客技术)首先你得了解什么是网络安全!什么是黑客网络安全可以基于攻击和防御视角来分类,我们经常听到的“红队”、“渗透测试”等就是研究攻击技术,而“蓝队”、“安全运营”、“安全运维”则研究防御技术。无论网络、Web、移动、桌面、云等哪个领域,都有攻与防两面性,例如Web安全技术,既有Web渗透,也有

手写模拟Spring的底层原理2.1

先来引入两个问题第一个懒加载还是立即加载的问题,这个问题还是在于就是说,当我们xml配置了一个对象bean的时候,它在spring容器里面是什么时候开始会给我们创建这个对象那如果我们想对某个对象启动懒加载,可以添加@lazy这个注解这个注解一加上,它就只会在得到对象的时候给我们在容器中创建对象也就是在使用下面的方法的时

Reactor 第十二篇 WebFlux集成PostgreSQL

1引言在现代的应用开发中,数据库是存储和管理数据的关键组件。PostgreSQL是一种强大的开源关系型数据库,而WebFlux是Spring框架提供的响应式编程模型。本文将介绍如何使用Reactor和WebFlux集成PostgreSQL,实现响应式的数据库访问。1.环境准备首先,我们需要在项目的pom.xml文件中添

一个例子了解交叉编译

学习嵌入式Linux经常听到交叉编译这个名词,那到底什么是交叉编译,下面通过一个例子来介绍。首先新建一个C文件,其代码如下。#include"stdio.h"voidmain(){inta,b;intc;printf("请输入两个数:\n");scanf("%d%d",&a,&b);c=a+b;printf("a+b=

Ubuntu不能上网解决办法

判断能不能联网1、怎么判断ubuntu确实不能联网?(1)最简单的办法当然是打开一个浏览器,随便输入一个网址,如www.baidu.com,若不能打开该网址,说明可能联网有问题。(2)打开终端,输入ifconfig命令,可以显示当前系统的网络设备,若只出现以下一个设备,表示该系统确实不能联网。(3)同样打开终端,使用p

Python经典练习题(三)

文章目录🍀第一题🍀第二题🍀第三题🍀第一题输入一行字符,分别统计出其中英文字母、空格、数字和其它字符的个数。本题需要我们掌握的知识点在于,判断字符串,是数字还是字母还是啥的,当然在Python内置中几乎都可以找到我们需要的下表我将介绍一些常用的判断函数判断函数描述isalnum()判断是否为字母或数字(字母数字组

SQL Server 数据库变成单个用户怎么办

参考技术A1、首先我们打开SQLSERVER的管理控制台,找到一个要设置角色的用户。2、下面我们将为这个用户赋予创建数据库的角色,我们先用这个用户登录管理工具看一下是否具有创建用户的权限。3、进行数据库创建的时候,提示如下的错误,证明这个用户不具备这个角色的权限。4、下面我们登录sa用户,找到这个用户,右键单击选择属性

拼多多API接口解析,实现根据ID取商品详情

拼多多是一个流行的电商平台,它提供了API接口供开发者使用。要根据ID获取商品详情,您需要使用拼多多API接口并进行相应的请求。以下是使用拼多多API接口根据ID获取商品详情的示例代码(使用Python编写):importrequestsimportjson#拼多多API接口地址api_url="https://api

【漏洞复现】易思智能物流无人值守系统文件上传

本文由掌控安全学院-江月投稿【产品介绍】易思无人值守智能物流系统是一款集成了人工智能、机器人技术和物联网技术的创新产品。它能够自主完成货物存储、检索、分拣、装载以及配送等物流作业,帮助企业实现无人值守的智能物流运营,提高效率、降低成本,为现代物流行业带来新的发展机遇。【漏洞描述】易思无人值守智能物流系统/Sys_Rep

h5下载文件,无兼容问题~

最近写了个页面,打开页面出现文件列表,用户可以下载文件。失败方案使用a标签进行下载,参考代码如下:因为有批量下载的需求,这里将xhr请求单独封装到downloadFile.js中//downloadFile.jsconstdownloadFile=(url,onProgress,xhrAr)=>{console.log

Linux知识点 -- 网络基础(二)-- 应用层

Linux知识点–网络基础(二)--应用层文章目录Linux知识点--网络基础(二)--应用层一、使用协议来实现一个网络版的计算器1.自定义协议2.守护进程3.使用json来完成序列化二、HTTP协议1.概念2.HTTP协议请求和响应的报文格式3.使用HTTP协议进行网络通信4.HTTP协议的方法5.HTTP协议的状态

热文推荐