单进程单线程的Redis如何能够高并发

tcp socket实现单进程单线程 高并发服务端(c++源码) tcp socket实现单进程单线程 高并发服务端源码 c++源码 立即下载

1、基本原理

采用多路 I/O 复用技术可以让单个线程高效的处理多个连接请求(尽量减少网络IO的时间消耗)
(1)为什么不采用多进程或多线程处理?

  1. 多线程处理可能涉及到锁

  2. 多线程处理会涉及到线程切换而消耗CPU

无法发挥多核CPU性能,不过可以通过在单机开多个Redis实例来完善

2、Redis不存在线程安全问题?

Redis采用了线程封闭的方式,把任务封闭在一个线程,自然避免了线程安全问题,不过对于需要依赖多个redis操作的复合操作来说,依然需要锁,而且有可能是分布式锁

3、什么是多路I/O复用(Epoll)

(1) 网络IO都是通过Socket实现,Server在某一个端口持续监听,客户端通过Socket(IP+Port)与服务器建立连接(ServerSocket.accept),成功建立连接之后,就可以使用Socket中封装的InputStream和OutputStream进行IO交互了。针对每个客户端,Server都会创建一个新线程专门用于处理
(2) 默认情况下,网络IO是阻塞模式,即服务器线程在数据到来之前处于【阻塞】状态,等到数据到达,会自动唤醒服务器线程,着手进行处理。阻塞模式下,一个线程只能处理一个流的IO事件
(3) 为了提升服务器线程处理效率,有以下三种思路

多路I/O复用模型是利用 select、poll、epoll 可以同时监察多个流的 I/O 事件的能力,在空闲的时候,会把当前线程阻塞掉,当有一个或多个流有 I/O 事件时,就从阻塞态中唤醒,于是程序就会轮询一遍所有的流(epoll 是只轮询那些真正发出了事件的流),并且只依次顺序的处理就绪的流,这种做法就避免了大量的无用操作。

这里“多路”指的是多个网络连接,“复用”指的是复用同一个线程。采用多路 I/O 复用技术可以让单个线程高效的处理多个连接请求(尽量减少网络 IO 的时间消耗),且 Redis 在内存中操作数据的速度非常快,也就是说内存内的操作不会成为影响Redis性能的瓶颈

4、其它开源软件采用的模型

  1. Nginx:多进程单线程模型 
  2. Memcached:单进程多线程模型

Redis为什么是单线程的?

因为CPU不是Redis的瓶颈。Redis的瓶颈最有可能是机器内存或者网络带宽。(以上主要来自官方FAQ)既然单线程容易实现,而且CPU不会成为瓶颈,那就顺理成章地采用单线程的方案了。关于redis的性能,官方网站也有,普通笔记本轻松处理每秒几十万的请求,参见:How fast is Redis?

 

如果万一CPU成为你的Redis瓶颈了,或者,你就是不想让服务器其他核闲置,那怎么办?

那也很简单,你多起几个Redis进程就好了。Redis是keyvalue数据库,又不是关系数据库,数据之间没有约束。只要客户端分清哪些key放在哪个Redis进程上就可以了。redis-cluster可以帮你做的更好。

 

单线程可以处理高并发请求吗?

当然可以了,Redis都实现了。

有一点概念需要澄清,并发并不是并行。

(相关概念:并发性I/O流,意味着能够让一个计算单元来处理来自多个客户端的流请求。并行性,意味着服务器能够同时执行几个事情,具有多个计算单元)

Redis总体快速的原因:
采用队列模式将并发访问变为串行访问(?)

单线程指的是网络请求模块使用了一个线程(所以不需考虑并发安全性),其他模块仍用了多个线程。

 

Redis总体快速的原因:

1)绝大部分请求是纯粹的内存操作(非常快速)

2)采用单线程,避免了不必要的上下文切换和竞争条件

3)非阻塞IO(epoll方式的多路IO复用技术)

内部实现采用epoll,采用了epoll+自己实现的简单的事件框架。epoll中的读、写、关闭、连接都转化成了事件,然后利用epoll的多路复用特性,绝不在io上浪费一点时间

这3个条件不是相互独立的,特别是第一条,如果请求都是耗时的,采用单线程吞吐量及性能可想而知了。应该说redis为特殊的场景选择了合适的技术方案。

======

 

1. Redis服务端是个单线程的架构,不同的Client虽然看似可以同时保持连接,但发出去的命令是序列化执行的,这在通常的数据库理论下是最高级别的隔离(serialize)
2. 用MULTI/EXEC 来把多个命令组装成一次发送,达到原子性
3. 用WATCH提供的乐观锁功能,在你EXEC的那一刻,如果被WATCH的键发生过改动,则MULTI到EXEC之间的指令全部不执行,不需要rollback
4. 其他回答中提到的DISCARD指令只是用来撤销EXEC之前被暂存的指令,并不是回滚

 

多线程对同一个Key操作时,Redis服务是根据先到先作的原则,其他排队(可设置为直接丢弃),因为是单线程。

修改默认的超时时间,默认2秒。但是大部份的操作都在30ms以内。

========

1. 使用Redis有哪些好处?优点

(1) 速度快,因为数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1)

(2) 支持丰富数据类型,支持string,list,set,sorted set,hash

(3) 支持事务,操作都是原子性,所谓的原子性就是对数据的更改要么全部执行,要么全部不执行

(4) 丰富的特性:可用于缓存,消息,按key设置过期时间,过期后将会自动删除

2. Redis相比memcached有哪些优势?

(1) memcached所有的值均是简单的字符串,redis作为其替代者,支持更为丰富的数据类型

(2) redis的速度比memcached快很多

(3) redis可以持久化其数据

(4)Redis支持数据的备份,即master-slave模式的数据备份。

5)、使用底层模型不同

它们之间底层实现方式 以及与客户端之间通信的应用协议不一样。

Redis直接自己构建了VM 机制 ,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求。

(6)value大小:redis最大可以达到1GB,而memcache只有1MB

3. redis常见性能问题和解决方案:

(1) Master最好不要做任何持久化工作,如RDB内存快照和AOF日志文件

(Master写内存快照,save命令调度rdbSave函数,会阻塞主线程的工作,当快照比较大时对性能影响是非常大的,会间断性暂停服务,所以Master最好不要写内存快照;AOF文件过大会影响Master重启的恢复速度)

(2) 如果数据比较重要,某个Slave开启AOF备份数据,策略设置为每秒同步一次

(3) 为了主从复制的速度和连接的稳定性,Master和Slave最好在同一个局域网内

(4) 尽量避免在压力很大的主库上增加从库

(5) 主从复制不要用图状结构,用单向链表结构更为稳定,即:Master <- Slave1 <- Slave2 <- Slave3...

这样的结构方便解决单点故障问题,实现Slave对Master的替换。如果Master挂了,可以立刻启用Slave1做Master,其他不变
 

redis的一些其他特点:

(1)Redis是单进程单线程的

redis利用队列技术将并发访问变为串行访问,消除了传统数据库串行控制的开销

(2)读写分离模型

通过增加Slave DB的数量,读的性能可以线性增长。为了避免Master DB的单点故障,集群一般都会采用两台Master DB做双机热备,所以整个集群的读和写的可用性都非常高。
读写分离架构的缺陷在于,不管是Master还是Slave,每个节点都必须保存完整的数据,如果在数据量很大的情况下,集群的扩展能力还是受限于单个节点的存储能力,而且对于Write-intensive类型的应用,读写分离架构并不适合。

(3)数据分片模型

为了解决读写分离模型的缺陷,可以将数据分片模型应用进来。

可以将每个节点看成都是独立的master,然后通过业务实现数据分片。

结合上面两种模型,可以将每个master设计成由一个master和多个slave组成的模型。

(4)Redis的回收策略,如何保持热点数据

  1. volatile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰
  2. volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰
  3. volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰
  4. allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰
  5. allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰
  6. no-enviction(驱逐):禁止驱逐数据

 

注意这里的6种机制,volatile和allkeys规定了是对已设置过期时间的数据集淘汰数据还是从全部数据集淘汰数据,后面的lru、ttl以及random是三种不同的淘汰策略,再加上一种no-enviction永不回收的策略。

  使用策略规则:

  1、如果数据呈现幂律分布,也就是一部分数据访问频率高,一部分数据访问频率低,则使用allkeys-lru

  2、如果数据呈现平等分布,也就是所有的数据访问频率都相同,则使用allkeys-random
 

 

YOLO26涨点改进 |TGRS 2026 | 全网独家改进、特征融合创新篇 | 引入CMIFE跨模态交互特征提取模块,充分挖掘互补信息,适合多模态图像融合,目标检测,实例分割,遥感图像分类高效涨点 本文提出CMIFE模块用于改进YOLO26网络模型,通过跨模态交互特征提取实现多尺度特征的精细化融合。该模块采用双注意力机制(自注意力强化模态内一致性,交叉注意力实现跨模态互补信息筛选),有效解决了传统YOLO融合中的信息冗余和负迁移问题。实验表明,CMIFE模块在保持模型实时性的同时,显著提升了小目标检测、遮挡场景等复杂环境下的检测精度。文章详细介绍了模块原理、网络结构、核心代码实现方法,并提供了三种改进版YOLO26的配置文件方案(yolo26_CMIFE-1/2/3.yaml)。 阅读详情

相关推荐

模电专题-MOS管的放大电路分析

在实际应用中,我们经常会使用到功率MOS,这时通常不会将它当成一个开关使用,而是当成一个放大器来使用,那这就需要让其工作在放大状态。参考下图中的mos管的特性曲线,右图中的输出特性曲线中有一根红色的分界线,这个线就是区分mos管工作状态的分界线,在红线的左边,mos管工作在可变电阻区,也就是线性区;在红线的右边mos管工作在恒流区,也就是饱和区。当然,还有一个截止区。本文分析主要运用模电课本中的理论计算验证。

Anitawen的博客 2万+

如何使用单线程处理高并发

单线程相当于一个队列,只能按照顺序执行,如果要实现高并发,可以借助下面的方式: (1)、IO多路复用技术 (2)、采用事件驱动模型,基于异步回调来处理事件来

一缕阳光的博客 2017

运用AD进行stm32最小系统PCB图的绘制

运用AD进行stm32最小系统PCB图的绘制一、PCB图的绘制(1)布局(2)布线(3)覆铜(4)电气规则检查二、给PCB添加logo三、生成garber文件总结 一、PCB图的绘制 (1)布局 1.画好原理图后,新建一个PCB项目 2.在Design中选择第二项,导入器件 3.先点击右下角第一项,再点第二项导入器件 导入成功 4.导入后效果 选择紫红色方框,按电脑上的delete键把它删掉 5.在Tools选择Outside Board,自动排布器件 排布后效果如图 6.画线,确定板子范围

lucario1的博客 2149

单线程的Redis如何能够高并发

单线程的Redis如何能够高并发0.预备知识1.官方答案其他补充答案 参考: 单进程单线程的Redis如何能够高并发 Redis为什么是单线程,高并发快的3大原因详解 为什么redis 是单线程的? 0.预备知识 CPU到底比内存跟硬盘快多少 大概意思是: 假设把CPU执行一个指令的时间定义为1s 则读取一级缓存将花费1.3s 分支预测将花费13s 读取二级缓存将花费18.2s 内存寻址260s,将近4分钟 一次CPU上下文切换大概需要65分钟 在1Gbps的网络上传输 2K 的数据需要14.4小时

selfsongs 1046

Llama模型结构拆解:为什么MLP模块要这样设计?从参数配置到计算流程全解析

本文深入解析了Llama模型MLP模块的设计精髓。通过拆解其三线性层结构、门控机制与SwiGLU激活函数,揭示了并行计算如何提升效率,并详细阐述了intermediate_size参数配置背后的经验权衡与计算考量,帮助读者透彻理解这一核心组件的设计逻辑与工程实现。

mac99的博客 528

Simscape Multiboby学习笔记1——跟着官网学Multibody

文章目录一. 引言二. Simscape Multibody自学之路三. 本教程的目录 一. 引言 最近在倒腾Matlab的动力学仿真,起因是看到有人推荐Matlab的multbody模块,一经了解之下简直惊为天人。作为一名Matlab的小粉,看到这么好用的模块简直不要太开心,之前用simulink搭飞行器的仿真模型,虽然能够仿真看到六自由度位移,毕竟不能可视化,还是很不够直观,而且simulink仿真(以及更费力的脚本文件仿真)需要精确建模,模型不精确计算也是天差地别。而Multibody在具备其他动力学

qq_30267617的博客 8241

redis单线程如何处理高并发的

这里写目录标题1.IO(阻塞IO)和NIO(非阻塞IO)的概念2.redis的线程模型3.redis的通信协议 1.IO(阻塞IO)和NIO(非阻塞IO)的概念 1.jdk1.4引入了NIO,但也有很多人在用阻塞IO,这两者有什么区别呢?假设线程1现在要从服务端读取1个10个字节的数据,但是只读到了5个字节,没有读完,那么线程1就会进入到阻塞状态。NIO就是线程1即使只读到了5个字节也会直接将这读到的5个字节返回,不会阻塞,等剩下5个字节加载进来后,再去读取。 2.redis的线程模型 1.redis虽然是

weixin_41359273的博客 2244

《用 AI 赋能医药科研创新》目录(持续更新)

本专栏旨在指导医学科研和药物研发人员运用AI技术提升研究效率。内容包括:利用AI分析文献、识别研究热点、自动生成研究草稿;在新药研发中,通过AI优化临床方案设计、受试者筛选等环节;介绍AI理论基础如大语言模型、提示词工程学及智能体技术发展历程。专栏采用5000-9000字的长文形式,系统讲解AI在医药研发各环节的应用方法,帮助研究者缩短周期、降低成本,推动医药研发进入智能化新阶段。

MD Code 499

单进程单线程的Redis如何支持高并发

1、基本原理 采用多路 I/O 复用技术可以让单个线程高效的处理多个连接请求(尽量减少网络IO的时间消耗) (1)为什么不采用多进程或多线程处理? 多线程处理可能涉及到锁 多线程处理会涉及到线程切换而消耗CPU (2)单线程处理的缺点? 无法发挥多核CPU性能,不过可以通过在单机开多个Redis实例来完善 2、Redis不存在线程安全问题? Redis采用了线程封闭的方式,把任...

疯一样的女子 1100

海洋CMS admin_notify.php 远程代码执行漏洞复现(CVE-2024-30565)

海洋CMS admin_notify.php 接口处存在远程代码执行漏洞,经过身份验证的远程攻击者可利用该漏洞执行任意代码,写入后门文件,进而控制整个web服务器。

0xSec 2713

基于MATLAB的多无人机多任务调度算法——CBBA带时间窗

本文将介绍基于MATLAB的CBBA算法,并对其进行改进,加入时间窗概念,以提高多无人机系统的调度效率和性能。时间窗用于限定任务的执行时间范围,以避免任务执行时间过长或过短导致的问题。具体而言,我们为每个任务设置一个允许的最早开始时间和最晚结束时间,并在任务分配的过程中考虑这些时间约束。在多无人机系统中,需要将若干个任务分配给不同的无人机完成,以实现高效的任务执行。以上是关于基于MATLAB的多无人机多任务调度算法CBBA带时间窗的简要介绍和源代码实现。多无人机系统的调度问题。

BUG?不存在的! 1898

单进程单线程的Redis如何能够高并发,redis是个单线程的程序,为什么会这么快呢?

弄清楚 Redis 为什么是单线程单进程,为什么单线程能保证这么快的速度

Java面试辅导-海龟老师 3907

PHP实现SM2算法(附完整源码)

PHP实现SM2算法(附完整源码)

希望我的博客,能帮上你解决学习中工作中所遇到的问题 4022

redis特点单进程单线程高性能服务器,Redis为什么是单线程?高并发响应快?

为什么 redis 单线程却能支撑高并发?纯内存操作核心是基于非阻塞的 IO 多路复用机制单线程反而避免了多线程的频繁上下文切换问题一、Redis的高并发和快速原因1.redis是基于内存的,内存的读写速度非常快(纯内存); 数据存在内存中,数据结构用HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1)。2.redis是单线程的,省去了很多上下文切换线程的时间(避免线程切换和...

weixin_33687939的博客 394

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

上一篇: Resetting first dirty offset of __consumer_offsets
下一篇: Java网络编程与NIO详解2:JAVA NIO 一步步构建IO多路复用的请求模型
wrr-cat
博客等级 码龄9年 128粉丝 302原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值