浅谈高并发的一些解决思路

news2024/11/17 11:48:19

前言

《中国互联网发展状况统计报告》指出,截至2020年6月,我国网民规模已经达到9.40亿,较2020年3月年增长3625万,除了如此庞大的用户基数,如今人们接入互联网的方式也越来越多样,小到智能手表,手机,大到笔记本,汽车,这也意味着实际使用互联网服务的entry point正以亿级的增长速率膨胀。也就是基于如此规模急剧扩大的环境下,服务厂商开始面临着两大压力,一个是更大的并发访问压力,一个是海量数据存储的压力。

高并发问题是各大平台必须解决的问题之一,它关系着平台可以承担多大的用户量以及能否提供可靠的服务。传统的单机模式已经无法满足需要,单纯的增加服务器数量也无法彻底解决问题,必须从整体系统架构和设计上全面考虑。

因此,本文汇总了一些常用的高并发解决思路及巧妙的工程实践,与大家分享一哈,具体细节先不展开,随用随查。

技术汇总

池化技术

池化技术就是把一些资源预先分配好,然后组织到对象池中,之后的业务使用资源从对象池中获取,使用完后放回到对象池中。这样做带来几个明显的好处:

  1. 资源重复使用, 减少了资源分配和释放过程中的系统消耗。比如,在IO密集型的服务器上,并发处理过程中的子线程或子进程的创建和销毁过程,带来的系统开销将是难以接受的。所以在业务实现上,通常把一些资源预先分配好,如线程池,数据库连接池,Redis连接池,HTTP连接池等,来减少系统消耗,提升系统性能。
  2. 可以对资源的整体使用做限制。这个好理解,相关资源预分配且只在预分配是生成,后续不再动态添加,从而 限制了整个系统对资源的使用上限。类似一个令牌桶的功能。.
  3. 池化技术分配对象池,通常会集中分配,这样有效避免了碎片化的问题。

比较经典的就是内存池的设计是SGI STL内存分配器:

std::allocator:默认分配器

__pool_alloc :SGI内存池分配器

__mt_alloc : 多线程内存池分配器

array_allocator : 全局内存分配,只分配不释放,交给系统来释放

malloc_allocator :堆std::malloc和std::free进行的封装

缓存

缓存技术 一般是指,用一个更快的存储设备存储一些经常用到的数据,供用户快速访问。 用户不需要每次都与慢设备去做交互,因此可以提高访问效率。 分布式缓存 就是指在分布式环境或系统下,把一些热门数据存储到离用户近、离应用近的位置,并尽量存储到更快的设备,以减少远程数据传输的延迟,让用户和应用可以很快访问到想要的数据。

缓存技术比较热门的就是memcache和redis。

垂直/水平扩展

扩展就是典型的技术不够设备来凑,在云计算领域我们认为算力和内存是无穷的,原因就在于易于垂直/水平扩展。

垂直扩展:提升单机处理能力。

  1. 增强单机硬件性能,例如:增加CPU核数如32核,升级更好的网卡如万兆,升级更好的硬盘如SSD,扩充硬盘容量如2T,扩充系统内存如128G;
  2. 提升单机架构性能,例如:使用Cache来减少IO次数,使用异步来增加单服务吞吐量,使用无锁数据结构来减少响应时间;

水平扩展:只要增加服务器数量,就能线性扩充系统性能。

限流

“限流”是指对用户请求进行一定程度的拦截,实现请求延时或者请求丢弃处理,相关的解决方案如下:

  1. 使用缓存对数据处理层进行限制,存储一些热点数据,加快访问数据的同时也防止了大量请求到达后端数据库,如 Cookie 或 Session 等;
  2. 使用消息队列(Message Queue,MQ)中间件将一些非即时的流量缓冲到 MQ 中,后续来实现异步处理;
  3. 使用网络流量高并发处理算法进行流量整形,以服务器能够承受的速率发送到 Web 应用系统后端进行处理;
  4. 从业务层面上,限制用户单位时间内的频繁访问操作,可以限制一部分冗余请求。

比较有代表性的限流算法是Google的开源项目RateLimiter,它是基于可配置的速率来分发令牌,数据包在获取令牌之后才能够被转发到网络中,从而实现对接口速率的限制。

负载均衡

负载均衡主要通过分担负载,通过选用合适的负载均衡策略,将请求分发到不同的服务节点上,解决网络拥堵问题,从而提高网络利用率,充分的利用服务器的各种资源让集群中的节点负载情况处于平衡状态来,提高系统的灵 活性和扩展能力,以达到提高系统整体的并发量的目的,从而使得外部用户体验更佳。常用的负载均衡的调度算法如下:

  • 轮询(Round Robin)
  • 加权轮询(Weighted Round Robin)
  • 最少连接(Least Connections)
  • 加权最少连接(Weighted Least Connections)
  • 随机(Random)
  • 加权随机(Weighted Random)
  • 源地址散列(Source Hashing)
  • 源地址端口散列(Source&Port Hashing)

削峰填谷

高并发处理可以抽象为消费者与生产者模型,当高峰期产出现的时候,消费者很容易出现瞬时流量非常大,但一般情况流量相对较少,这样平时的性能就浪费了。这个时候就可以引入消息队列RabbitMQ,它有三个好处:

  1. 解耦。生产者无需关注有多少消费者,它只需要和消息队列MQ交互,生成的数据传给MQ即可;
  2. 异步。生产者将数据交给MQ直接可以返回,消费者什么时候消费,无需专注
  3. 削峰填谷。MQ有限制消费的机制,比如之前生产者生成速率为3000,但MQ做了一个限制只有1000,那么高峰期的数据就会挤压在MQ里,高峰被“削”掉了,但是因为消息积压,在高峰期过后的一段时间内,消费消息的速度还是会维持在1000,直到消费完挤压的消息,这就做“填谷”。

无锁化

环形队列一般符合生产者-消费者模型,用于报文收发的缓存区或者是线程收发消息的队列,DPDK提供了一种无锁的环形队列,大家知道加锁操作十分耗费性能,下图是横向多种锁机制的比较,其中第一个是无锁:

DPDK的无锁环形队列的优缺点:

具体原理可见:dpdk无锁队列

GC优化

当Java程序性能达不到既定目标,且其他优化手段都已经穷尽时,通常需要调整垃圾回收器来进一步提高性能,称为GC优化。但GC算法复杂,影响GC性能的参数众多,且参数调整又依赖于应用各自的特点,这些因素很大程度上增加了GC优化的难度。

GC优化一般步骤可以概括为:确定目标、优化参数、验收结果。

  1. 明确目标。明确应用程序的系统需求是性能优化的基础,系统的需求是指应用程序运行时某方面的要求,譬如: - 高可用,可用性达到几个9。 - 低延迟,请求必须多少毫秒内完成响应。 - 高吞吐,每秒完成多少次事务。明确系统需求之所以重要,是因为上述性能指标间可能冲突。比如通常情况下,缩小延迟的代价是降低吞吐量或者消耗更多的内存或者两者同时发生。举例:假设单位时间T内发生一次持续25ms的GC,接口平均响应时间为50ms,且请求均匀到达,根据下图所示:那么有(50ms+25ms)/T比例的请求会受GC影响,其中GC前的50ms内到达的请求都会增加25ms,GC期间的25ms内到达的请求,会增加0-25ms不等,如果时间T内发生N次GC,受GC影响请求占比=(接口响应时间+GC时间)×N/T 。可见无论降低单次GC时间还是降低GC次数N都可以有效减少GC对响应时间的影响。

2. 优化参数。通过收集GC信息,结合系统需求,确定优化方案,例如选用合适的GC回收器、重新设置内存比例、调整JVM参数等。进行调整后,将不同的优化方案分别应用到多台机器上,然后比较这些机器上GC的性能差异,有针对性的做出选择,再通过不断的试验和观察,找到最合适的参数。

3. 验收优化结果。将修改应用到所有服务器,判断优化结果是否符合预期,总结相关经验。

读写分离

读写分离是指将读写操作由不同的服务器执行,本质上是将数据库分为主库和从库,主数据库只用来处理对数据库的写入请求,即insert、update、delete等操作,从数据库只用作处理对数据的读请求,即select操作。一般情况下,数据库的写入操作是比较耗费时间的,如果系统在分布式场景下对数据库同时进行读写操作时,系统的并发压力增大,且若事务当前处理的是写请求,在处理过程中会对操作的数据加互斥锁,当其他请求想要操作该被加锁数据时,只能等待前一个线程处理完毕释放锁之后才能接着执行,如果等待时间太长,有可能会出现死锁问题,导致数据库服务不可用,因此实现读写分离可以避免因为数据库写操作对其他查询操作的影响,同时可以有效提高数据库并发性能,缓解数据库并发压力。

具体做法可以对单实例Redis进行分组扩展,将其扩展一组内只有一个mater数据库负责写,多个slave数据库负责读,如下图所示:

这个架构也可继续扩展为多机房场景:

冷热分离

冷热分离是目前ES非常火的一个架构,它充分的利用的集群机器的优劣来实现资源的调度分配。ES集群的索引写入及查询速度主要依赖于磁盘的IO速度,冷热数据分离的关键点为使用固态磁盘存储数据。若全部使用固态,成本过高,且存放冷数据较为浪费,因而使用普通机械磁盘与固态磁盘混搭,可做到资源充分利用,性能大幅提升的目标。因此我们可以将实时数据(5天内)存储到热节点中,历史数据(5天前)的存储到冷节点中,并且可以利用ES自身的特性,根据时间将热节点的数据迁移到冷节点中,这里因为我们是按天建立索引库,因此数据迁移会更加的方便。

分库分表

不管是IO瓶颈,还是CPU瓶颈,最终都会导致数据库的活跃连接数增加,进而逼近甚至达到数据库可承载活跃连接数的阈值。在业务Service来看就是,可用数据库连接少甚至无连接可用。针对IO瓶颈和CPU瓶颈可分为两种优化方式:

  1. IO瓶颈。第一种:磁盘读IO瓶颈,热点数据太多,数据库缓存放不下,每次查询时会产生大量的IO,降低查询速度 -> 分库和垂直分表。第二种:网络IO瓶颈,请求的数据太多,网络带宽不够 -> 分库。

2. CPU瓶颈。第一种:SQL问题,如SQL中包含join,group by,order by,非索引字段条件查询等,增加CPU运算的操作 -> SQL优化,建立合适的索引,在业务Service层进行业务计算。第二种:单表数据量太大,查询时扫描的行太多,SQL效率低,CPU率先出现瓶颈 -> 水平分表。

分库分表的5大方案,百度、腾讯、阿里等大厂都在用! - 腾讯云开发者社区-腾讯云 (tencent.com)

火焰图

火焰图(Flame Graph)是由 Linux 性能优化大师 Brendan Gregg 发明的用于分析性能瓶颈的可视化图表,火焰图以一个全局的视野来看待时间分布,它从顶部往底部列出所有可能导致性能瓶颈 Span。

绘制逻辑如下:
• 纵轴(Y轴)代表调用 Span 的层级深度,用于表示程序执行片段之间的调用关系:上面的 Span 是下面 Span 的父 Span(数据上也可以通过子 span 的 parent_id 等于父 Span 的 span_id 来关联来对应)。
• 横轴(X轴)代表单个 Trace 下 Span 的持续时间(duration),一个格子的宽度越大,越说明该 Span 的从开始到结束的持续时间较长,可能是造成性能瓶颈的原因。

程序员精进之路:性能调优利器--火焰图 - 知乎 (zhihu.com)

如何读懂火焰图? - 阮一峰的网络日志 (ruanyifeng.com)

巧用 “ 火焰图 ” 快速分析链路性能 - 掘金 (juejin.cn)

异步

在高并发场景下,另一种提高CPU利用率的方法是异步化。我们可以编写异步的,非阻塞的代码。在执行IO操作的时候,让线程继续拥有CPU的时间片同时切换到另一个任务上,当异步任务执行完成时,再返回当前的线程继续执行。异步系统通常每个CPU核心使用一个线程处理所有的请求和响应,因为并不是每个请求都需要创建一个线程,所以连接成本很便宜。 它的成本只是文件描述符和监听器(例如epoll)。由于数据保留在同一CPU上,从而可以更好地利用CPU级别的缓存,并且只有较少的上下文切换,因此可以提高效率。

架构设计 | 异步处理流程,多种实现模式详解 - 知了一笑 - 博客园 (cnblogs.com)

异步架构和响应式(Reactive)编程 - 掘金 (juejin.cn)

分片

分片这里面是指计算量分片。

计算量分片可以运用到某一种计算量非常大的场景,比如说计算直播中礼物数量的排行榜,这里面我们就可以通过多机分片计算各个地区数据,然后再交由统一的汇总系统去合并计算出排行榜,这个思想很像归并排序。

动静分离

动静分离是指服务器对动态和静态请求分开处理,将动态请求(php,servlet等)发送给tomcat服务器处理,而对静态请求(jpg,html,js,css等),则直接访问定义的静态资源目录,不用发送给服务器,这样可以提高网站相应速度,减轻服务器负载。因为Tomcat程序本身是用来处理jsp代码的,但tomcat本身处理静态效率不高,还会带来资源开销。

静态请求和动态请求_qq_42728930的博客-CSDN博客_动态请求和静态请求区别

什么是动静分离?_dijichen0911的博客-CSDN博客

网站“动静分离”分析及实战 - 知乎 (zhihu.com)

分布式消息队列详解:10min搞懂同步和异步架构_处理 (sohu.com)

预计算

预计算是一种用于信息检索和分析的常用技术, 其基本含义是提前计算和存储中间结果,再使用这些预先计算的结果加快进一步的查询。

预计算广泛应用于数据库技术中。比如,关系数据库中的索引其实就是一种预计算。为了快速地检索数据,数据库会主动维护一个数据索引的结构,用来描述表格中一列或者多列数据的缩影。一旦索引的预计算完成,数据库不用每次都重新查找表格的每一行,就能快速地定位数据。假设 N 是表格的行数,有了索引的预计算,数据检索的时间可以从 O(N)减少至 O(log(N)) 甚至到 O(1)。索引作为一种预计算,带来便利的同时也存在一些弊端。当表格中插入新的行数时,就需要重新进行的计算和储存。 当索引越多,查询响应越快时,那其实也意味着要进行更多的预计算,这当然也会显著减缓数据更新的速度。 下列图表展示了索引数量增加后,表格插入行的性能也相应降低 。

Apache Kylin 的预计算是怎么回事?_Shockang的博客-CSDN博客_kylin预计算

为什么预计算技术代表大数据行业的未来,一文读懂_数据库_apachekylin_InfoQ精选文章

Reference

赵俊哲. 网络流量高并发优化处理研究[D]. 江苏:南京邮电大学,2020.

【池化技术】池化技术基础和原理_小熊coder的博客-CSDN博客_池化技术

内存池介绍与经典内存池的实现 - 腾讯云开发者社区-腾讯云 (tencent.com)

负载均衡_魏言华的博客-CSDN博客_负载均衡

1.1MQ的基本概念,优劣势介绍及 RabbitMQ简介_苹水相峰的博客-CSDN博客

超详细的RabbitMQ入门,看这篇就够了!-阿里云开发者社区 (aliyun.com)

C++性能榨汁机之无锁编程 - 知乎 (zhihu.com)

dpdk无锁队列_七夜落幕丶的博客-CSDN博客

从实际案例聊聊Java应用的GC优化 - 美团技术团队 (meituan.com)

如何优化Java GC - 简书 (jianshu.com)

读写分离的几种方式_Morning sunshine的博客-CSDN博客_读写分离

ElasticSearch实战系列十: ElasticSearch冷热分离架构 - 虚无境 - 博客园 (cnblogs.com)

数据架构:概念与冷热分离 - 知乎 (zhihu.com)

分库分表的5大方案,百度、腾讯、阿里等大厂都在用! - 腾讯云开发者社区-腾讯云 (tencent.com)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1499475.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MySQL存储函数

存储函数是有返回值存储过程,存储函数的参数只能还是IN类型的 1、语法 create function 存储函数名称 ([参数列表])Returns type [characterrastic...]Begin--SQL语句Return ..;End;characterrastic说明:Deterministic:相同的输…

纯css实现太极八卦图

感觉最近好像闯鬼了&#xff0c;赶紧写个八卦图避避邪&#xff0c;开玩笑了&#xff0c;不废话&#xff0c;上菜&#xff0c;看效果上代码。 效果 代码&#xff0c;你们都是大佬&#xff0c;这里就不解释代码了 &#xff08;hover会转动喔&#xff09;。 <!DOCTYPE html&g…

Linux:kubernetes(k8s)探针LivenessProbe的使用(9)

他做的事情就是当我检测的一个东西他不在规定的时间内存在的话&#xff0c;我就让他重启&#xff0c;这个检测的目标可以是文件或者端口等 我这个是在上一章的基础之上继续操作&#xff0c;我会保留startupProbe探针让后看一下他俩的执行优先的一个效果 Linux&#xff1a;kuber…

图机器学习(3)-连接层面的特征工程

0 问题定义 通过已经连接去猜未知连接&#xff1a; 有两个思路&#xff1a;

金融行业专题|基金超融合架构转型与场景探索合集(2023版)

更新内容 更新 SmartX 超融合在基金行业的覆盖范围、部署规模与应用场景。更新信创云资源池、关键业务系统性能优化等场景实践。更多超融合金融核心生产业务场景实践&#xff0c;欢迎下载阅读电子书《金融核心生产业务场景探索文章合集》。 随着数字化经济的蓬勃发展&#xf…

WPF 消息提示 类似toast方式

WPF里面的消息提示一般都是MessageBox.Show()&#xff0c;这种样式不是很好看&#xff0c;所以就想办法重新搞了一个类似弹出消息的功能。原理很简单&#xff0c;就是弹出一个新窗体&#xff0c;然后等几秒窗体自动关闭。 先上效果图&#xff1a; 新建一个MsgHelper.cs类&…

板绘学习路线、技巧和日常练习-----线条基础(点线面)---持续补充

板绘学习路线、技巧和日常练习-----主目录-----持续更新(进不去说明我没写完)&#xff1a;https://blog.csdn.net/grd_java/article/details/136199248 虽然PS画线条可以用快捷键画&#xff0c;但是太AI了。我们需要线条包含更多的人性。所以通过我们心-脑-手&#xff0c;这样…

腾讯云2024年云服务器优惠价格表,不买后悔!

腾讯云服务器多少钱一年&#xff1f;61元一年起&#xff0c;2核2G3M配置&#xff0c;腾讯云2核4G5M轻量应用服务器165元一年、756元3年&#xff0c;4核16G12M服务器32元1个月、312元一年&#xff0c;8核32G22M服务器115元1个月、345元3个月&#xff0c;腾讯云服务器网txyfwq.co…

滤波器:工作原理和分类及应用领域?|深圳比创达电子EMC

滤波器在电子领域中扮演着重要的角色&#xff0c;用于处理信号、抑制噪声以及滤除干扰。本文将详细介绍滤波器的工作原理、分类以及在各个应用领域中的具体应用。 一、滤波器的定义和作用 滤波器是一种电子设备&#xff0c;用于选择性地通过或阻塞特定频率范围内的信号。其主…

【小黑送书—第十一期】>>如何阅读“计算机界三大神书”之一 ——SICP(文末送书)

《计算机程序的构造和解释》&#xff08;Structure and Interpretation of Computer Programs&#xff0c;简记为SICP&#xff09;是MIT的基础课教材&#xff0c;出版后引起计算机教育界的广泛关注&#xff0c;对推动全世界大学计算机科学技术教育的发展和成熟产生了很大影响。…

MySQL的事务隔离级别介绍

我将为您详细讲解 MySQL 的事务隔离级别&#xff0c;并给出相应的简单例子。事务隔离级别是数据库管理系统中用于控制事务内外的数据一致性和并发性的重要概念。在 MySQL 中&#xff0c;事务隔离级别用于解决并发操作可能产生的问题&#xff0c;如脏读、不可重复读和幻读。 1. …

自然语言处理: 第十三章P-tuing系列之P-tuning V1

项目地址: P-Tuning 论文地址: [2103.10385] GPT Understands, Too (arxiv.org) 理论基础 正如果上一节介绍LoRA(自然语言处理: 第十二章LoRA解读_lora自然英语处理-CSDN博客)一样,本次介绍的在21年由清华团推提出来的 P-Tuning V1系列也属于PEFT(参数高效微调系列)里的一种&…

人类与智能体

1、人类与智能体 人类与智能体之间的关系在当今科技发展中变得日益紧密。智能体&#xff0c;作为人工智能领域的一个核心概念&#xff0c;通常指的是一种能够感知环境、做出决策并采取行动以实现特定目标的实体&#xff0c;它可以是软件系统、机器人或其他类型的自动化装置。 …

Java代码审计安全篇-目录穿越漏洞

前言&#xff1a; 堕落了三个月&#xff0c;现在因为被找实习而困扰&#xff0c;着实自己能力不足&#xff0c;从今天开始 每天沉淀一点点 &#xff0c;准备秋招 加油 注意&#xff1a; 本文章参考qax的网络安全java代码审计&#xff0c;记录自己的学习过程&#xff0c;还希望各…

离散数学——(3)联结词及对应的真值指派,最小全功能联结词集,对偶式,范式,范式存在定理,小项

目录 1.联结词及对应的真值指派 2.最小全功能联结词集 3.对偶式 4.范式 1.析取范式 5.范式存在定理 6.小项 1.联结词及对应的真值指派 2.最小全功能联结词集 3.对偶式 4.范式 1.析取范式 5.范式存在定理 6.小项

大宗商品现货系统开发撮合交收制度说明

大宗商品现货系统的撮合交收制度是其交易机制的核心部分&#xff0c;确保了交易的顺利进行和市场的公平、公正。以下是该制度的主要说明&#xff1a; 撮合原则&#xff1a; 大宗商品现货系统通常采用价格优先、时间优先的撮合原则。价格优先意味着报价最高的买方和报价最低的…

气相白炭黑外资垄断格局被打破 国内本土企业数量增加

气相白炭黑外资垄断格局被打破 国内本土企业数量增加 气相白炭黑又名气相二氧化硅&#xff0c;是一种无毒、无味、无嗅&#xff0c;无污染的非金属氧化物&#xff0c;主要由硅的卤化物在氢氧火焰中高温水解生成的带有表面羟基和吸附水的无定形的纳米级颗粒。气相白炭黑主要用于…

【C语言基础】:深入理解指针(三)

文章目录 深入理解指针一、冒泡排序二、二级指针三、指针数组3.1 指针数组模拟二维数组 四、字符指针变量五、数组指针变量5.1 数组指针变量是什么&#xff1f;5.2 数组指针变量的初始化 六、二维数组传参的本质 深入理解指针 指针系列回顾&#xff1a; 【C语言基础】&#xf…

[uni-app ] createAnimation锚点旋转 及 二次失效问题处理

记录一下: 锚点定位到左下角, 旋转动画 必须沿Z轴,转动 但是,此时会出现 后续动画在微信小程序失效问题 解决: 清空 this.animationData

关于 OpenAI Sora的一些探索和思考

关于 OpenAI Sora的一些探索和思考 探索 OpenAI 的 Sora&#xff1a;一种突破性的文本到视频 AI&#xff0c;将在 2024 年彻底改变多模态 AI。探索其功能、创新和潜在影响。 OpenAI 最近宣布了其最新的突破性技术——Sora。到目前为止&#xff0c;这种文本到视频的生成式 AI …