高并发问题是各大平台必须办理的问题之一,它关系着平台可以承担多大的用户量以及能否供应可靠的做事。传统的单机模式已经无法知足须要,纯挚的增加做事器数量也无法彻底办理问题,必须从整体系统架构和设计上全面考虑。
因此,本文汇总了一些常用的高并发办理思路及奥妙的工程实践,与大家分享一哈,详细细节先不展开,随用随查。
技能汇总池化技能
池化技能便是把一些资源预先分配好,然后组织到工具池中,之后的业务利用资源从工具池中获取,利用完后放回到工具池中。这样做带来几个明显的好处:
资源重复利用, 减少了资源分配和开释过程中的系统花费。比如,在IO密集型的做事器上,并发处理过程中的子线程或子进程的创建和销毁过程,带来的系统开销将是难以接管的。以是在业务实现上,常日把一些资源预先分配好,如线程池,数据库连接池,Redis连接池,HTTP连接池等,来减少系统花费,提升系统性能。可以对资源的整体利用做限定。这个好理解,干系资源预分配且只在预分配时天生,后续不再动态添加,从而 限定了全体系统对资源的利用上限。类似一个令牌桶的功能。.池化技能分配工具池,常日汇合等分配,这样有效避免了碎片化的问题。
比较经典的便是内存池的设计是SGI STL内存分配器:
std::allocator:默认分配器
__pool_alloc :SGI内存池分配器
__mt_alloc : 多线程内存池分配器
array_allocator : 全局内存分配,只分配不开释,交给系统来开释
malloc_allocator :堆std::malloc和std::free进行的封装
缓存缓存技能 一样平常是指,用一个更快的存储设备存储一些常常用到的数据,供用户快速访问。 用户不须要每次都与慢设备去做交互,因此可以提高访问效率。 分布式缓存 便是指在分布式环境或系统下,把一些热门数据存储到离用户近、离运用近的位置,并只管即便存储到更快的设备,以减少远程数据传输的延迟,让用户和运用可以很快访问到想要的数据。
缓存技能比较热门的便是memcache和redis。
垂直/水平扩展扩展便是范例的技能不足设备来凑,在云打算领域我们认为算力和内存是无穷的,缘故原由就在于易于垂直/水平扩展。
垂直扩展:提升单机处理能力。
增强单机硬件性能,例如:增加CPU核数如32核,升级更好的网卡如万兆,升级更好的硬盘如SSD,扩充硬盘容量如2T,扩充系统内存如128G;提升单机架构性能,例如:利用Cache来减少IO次数,利用异步来增加单做事吞吐量,利用无锁数据构造来减少相应韶光;水平扩展:只要增加做事器数量,就能线性扩充系统性能。
限流“限流”是指对用户要求进行一定程度的拦截,实现要求延时或者要求丢弃处理,干系的办理方案如下:
利用缓存对数据处理层进行限定,存储一些热点数据,加快访问数据的同时也防止了大量要求到达后端数据库,如 Cookie 或 Session 等;利用行列步队(Message Queue,MQ)中间件将一些非即时的流量缓冲到 MQ 中,后续来实现异步处理;利用网络流量高并发处理算法进行流量整形,以做事器能够承受的速率发送到 Web 运用系统后端进行处理;从业务层面上,限定用户单位韶光内的频繁访问操作,可以限定一部分冗余要求。比较有代表性的限流算法是Google的开源项目RateLimiter,它是基于可配置的速率来分发令牌,数据包在获取令牌之后才能够被转发到网络中,从而实现对接口速率的限定。
负载均衡
负载均衡紧张通过分担负载,通过选用得当的负载均衡策略,将要求分发到不同的做事节点上,办理网络拥堵问题,从而提高网络利用率,充分的利用做事器的各种资源让集群中的节点负载情形处于平衡状态来,提高系统的灵 活性和扩展能力,以达到提高系统整体的并发量的目的,从而使得外部用户体验更佳。常用的负载均衡的调度算法如下:
轮询(Round Robin)加权轮询(Weighted Round Robin)最少连接(Least Connections)加权最少连接(Weighted Least Connections)随机(Random)加权随机(Weighted Random)源地址散列(Source Hashing)源地址端口散列(Source&Port Hashing)削峰填谷高并发处理可以抽象为消费者与生产者模型,当高峰期产涌现的时候,消费者很随意马虎涌现瞬时流量非常大,但一样平常情形流量相对较少,这样平时的性能就摧残浪费蹂躏了。这个时候就可以引入行列步队RabbitMQ,它有三个好处:
解耦。生产者无需关注有多少消费者,它只须要和行列步队MQ交互,天生的数据传给MQ即可;异步。生产者将数据交给MQ直接可以返回,消费者什么时候消费,无需专注削峰填谷。MQ有限定消费的机制,比如之前生产者天生速率为3000,但MQ做了一个限定只有1000,那么高峰期的数据就会挤压在MQ里,高峰被“削”掉了,但是由于积压,在高峰期过后的一段韶光内,消费的速率还是会坚持在1000,直到消费完挤压的,这就做“填谷”。无锁化环形行列步队一样平常符合生产者-消费者模型,用于报文收发的缓存区或者是线程收发的行列步队,DPDK供应了一种无锁的环形行列步队,大家知道加锁操作十分耗费性能,下图是横向多种锁机制的比较,个中第一个是无锁:
DPDK的无锁环形行列步队的优缺陷:
详细事理可见:dpdk无锁行列步队
GC优化当Java程序性能达不到既定目标,且其他优化手段都已经穷尽时,常日须要调度垃圾回收器来进一步提高性能,称为GC优化。但GC算法繁芜,影响GC性能的参数浩瀚,且参数调度又依赖于运用各自的特点,这些成分很大程度上增加了GC优化的难度。
GC优化一样平常步骤可以概括为:确定目标、优化参数、验收结果。
明确目标。明确运用程序的系统需求是性能优化的根本,系统的需求是指运用程序运行时某方面的哀求,譬如: - 高可用,可用性达到几个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瓶颈可分为两种优化办法:
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)