面试官再问高并发,求你把这篇发给他!

2024-06-03 08:58

本文主要是介绍面试官再问高并发,求你把这篇发给他!,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

凯 猿人课堂 2020-07-03

高并发是几乎每个程序员都想拥有的一种经验。原因很简单:随着流量的增加,您将遇到各种技术问题,例如接口响应超时,CPU负载增加,GC频繁出现,死锁,大数据存储等。这些问题可以促使我们不断改进技术深度。

  在过去的面试中,如果候选人进行了高并发项目,我通常会让对方谈论他们对高并发的理解,但是没有多少人可以系统地回答这个问题,大概分为以下几类:

  1.没有基于数据的指标的概念:尚不清楚选择哪种指标来衡量高并发系统?并发和QPS无法区分,甚至关键数据(例如系统的用户总数和活动用户总数,高峰时间和高峰时间的QPS和TPS)也是未知的。

  2.已经设计了一些程序,但是对细节的理解还不够:无法描述该程序的技术要点和可能产生的副作用。例如,读取性能存在瓶颈,这会引入高速缓存,但是它会忽略诸如高速缓存命中率,热点密钥和数据一致性之类的问题。

  3.理解方面,将高并发设计与性能优化等同起来:谈论并发编程,多级缓存,异步和水平扩展,但忽略高可用性设计,服务治理以及运维保证。

  4.掌握了大计划,却忽略了最基本的东西:可以清楚地解释垂直分层,水平分区,缓存等大思想,但是没有意识去分析数据结构是否合理,算法是否有效 ,并且从未考虑过最基本的IO和计算两个维度来优化细节。

  在本文中,我想将我的经验与高并发项目相结合,以系统地总结高并发需要掌握的知识和实践思想。希望对您有所帮助。内容分为以下三个部分:

  如何理解高并发?

  高并发系统设计的目标是什么?

  高并发性的实际解决方案有哪些?

  01如何理解高并发?

  高并发意味着大流量,并且需要技术方法来抵抗流量的影响。这些方法就像操作流量一样,可以使流量被系统更平稳地处理,并为用户带来更好的体验。

  我们常见的高并发情况包括:淘宝网的Double 11,春运期间抢票以及微博的热门新闻。除了这些典型的事情外,每秒可处理数十万个请求的高峰系统,每天可处理数千万个订单的订单系统以及每天可处理数亿的信息流系统可归为“高” 并发。

  显然,上述高并发场景具有不同的并发,那么并发有多大?

  1.您不仅可以查看数字,还必须查看特定的业务场景。不能说10W QPS的峰值是高并发,而1W QPS的信息流不是高并发。信息流场景涉及复杂的推荐模型和各种手动策略。它的业务逻辑可能比峰值情景复杂10倍以上。因此,它们不在同一维度上并且没有比较意义。

  2.业务从0到1完成。并发和QPS只是参考指标。最重要的是:您是否在业务量逐渐变为原始量的10倍和100倍的过程中使用了高并发性?从体系结构设计,编码实现甚至产品解决方案等方面来发展系统的处理方法,以防止和解决由高并发引起的问题?而不是盲目地升级硬件并添加用于水平扩展的机器。

  此外,每个高并发方案的业务特征完全不同:存在一个读多写少的信息流方案,一个读多写多的事务方案。是否有通用的技术解决方案来解决不同情况下的高并发问题?

  我认为宏伟的构想可以作为参考,其他人的计划也可以作为参考,但是在实际着陆过程中,细节上有无数的坑。另外,由于软件和硬件环境,技术堆栈和产品逻辑不能完全一致,因此将导致相同的业务场景。即使使用相同的技术解决方案,他们也将面临不同的问题。这些坑必须一一探访。

  因此,在本文中,我将重点介绍我所实践的基本知识,一般思想和有效经验,以期希望您对高并发性有更深入的了解。

02高并发系统设计的目标是什么?

  首先了解高并发系统设计的目标,然后讨论设计方案和实践经验以使其有意义和针对性。

  2.1宏观目标

  高并发并不仅仅意味着追求高性能,这是许多人的单方面理解。从宏观角度来看,高并发系统设计有三个目标:高性能,高可用性和高可伸缩性。

  1.高性能:性能反映了系统的并行处理能力。在有限的硬件投资下,提高性能意味着节省成本。同时,性能也反映了用户体验,响应时间分别为100毫秒和1秒,用户体验完全不同。

  2.高可用性:指示系统可以正常服务的时间。全年无停机,无故障;另一个则每三到五次就发生一次事故和停机,用户必须选择前者。另外,如果系统只能提供90%的可用性,那么它将极大地拖累业务。

  3.高扩展性:表示系统的扩展能力,是否可以在高峰流量期间在短时间内完成容量扩展,并且可以更顺利地进行高峰流量,例如双11事件,离婚和其他热点 事件。

图片

 

这3个目标是需要通盘考虑的,因为它们互相关联、甚至也会相互影响。

比如说:考虑系统的扩展能力,你会将服务设计成无状态的,这种集群设计保证了高扩展性,其实也间接提升了系统的性能和可用性。

再比如说:为了保证可用性,通常会对服务接口进行超时设置,以防大量线程阻塞在慢请求上造成系统雪崩,那超时时间设置成多少合理呢?一般,我们会参考依赖服务的性能表现进行设置。

2.2微观目标

  从微观角度看,衡量高性能,高可用性和高扩展性的具体指标是什么?您为什么选择这些指标?

  ❇绩效指标

  性能指标可用于衡量当前的性能问题,同时可作为评估性能优化的基础。通常,一段时间内的接口响应时间将用作指标。

  1.平均响应时间:最常用的响应时间,但缺陷很明显,对缓慢的请求不敏感。例如,有10,000个请求,其中9900次为1ms,100次为100ms,平均响应时间为1.99ms。尽管平均时间仅增加了0.99ms,但1%请求的响应时间却增加了100倍。

  2. TP90,TP99和其他分位数:将响应时间从小到大排序。  TP90代表第90个分位数的响应时间。分位数值越大,对请求减慢的敏感性越高。

图片

 

3、吞吐量:和响应时间呈反比,比如响应时间是1ms,则吞吐量为每秒1000次。

通常,设定性能目标时会兼顾吞吐量和响应时间,比如这样表述:在每秒1万次请求下,AVG控制在50ms以下,TP99控制在100ms以下。对于高并发系统,AVG和TP分位值必须同时要考虑。

另外,从用户体验角度来看,200毫秒被认为是第一个分界点,用户感觉不到延迟,1秒是第二个分界点,用户能感受到延迟,但是可以接受。

因此,对于一个健康的高并发系统,TP99应该控制在200毫秒以内,TP999或者TP9999应该控制在1秒以内。

❇ 可用性指标

高可用性是指系统具有较高的无故障运行能力,可用性 = 平均故障时间 / 系统总运行时间,一般使用几个9来描述系统的可用性。

 

图片

对于高度并发的系统,最基本的要求是:保证3 9s或4 9s。原因很简单。如果您只能做两个9,则意味着停机时间为1%。就像一些每年花费超过1000亿的GMV或收入的大公司一样,1%的业务影响是10亿美元。

  ❇可扩展性指标

  面对突然的流量,不可能临时修改体系结构。最快的方法是添加计算机以线性地提高系统的处理能力。

  对于业务集群或基本组件,可伸缩性=性能改进率/机器增加率,理想的扩展能力是:资源增加几倍,性能提高几倍。一般来说,扩展能力应保持在70%以上。

  但是,从高度并发系统的整体体系结构的角度来看,扩展的目标不仅是将服务设计为无状态的,因为当流量增加10倍时,业务服务可以快速扩展10倍,而是 数据库可能成为新的瓶颈。

  像MySQL这样的有状态存储服务通常是扩展方面的技术难题。如果架构不是预先计划的(垂直和水平拆分),它将涉及大量数据的迁移。

  因此,需要考虑高可伸缩性:服务集群,数据库,缓存,消息队列和其他中间件,负载平衡,带宽,相关第三方等。当并发达到一定水平时,上述每个因素都可能成为可伸缩性。

  03高并发的实际解决方案有哪些?

  在理解了高并发设计的三个目标之后,系统地总结了高并发设计方案,该方案将由以下两个部分开发:首先概述一般设计方法,然后分别给出高性能,高可用性和高扩展性。计划。

  3.1一般设计方法

  通用设计方法主要基于“垂直”和“水平”两个维度,通常称为高并发处理的两个轴:垂直扩展和水平扩展。

  Scale放大

  其目标是提高单台机器的处理能力,该程序包括:

  1.改善独立计算机的硬件性能:通过添加内存,CPU核心,存储容量或将磁盘升级到SSD和其他堆硬件来增加独立计算机的硬件性能。

  2.提高单台计算机的软件性能:使用缓存减少IO的数量,并使用并发或异步方法提高吞吐量。

  ❇横向扩展

  由于单台计算机的性能始终受到限制,因此最终有必要引入水平扩展并通过集群部署进一步提高并发处理能力,包括以下两个方向:

  1.做一个好的分层体系结构:这是水平扩展的进步,因为高度并发的系统往往具有复杂的业务。通过分层处理,可以简化复杂的问题,并且可以更轻松地实现水平扩展。

图片

 

 

上面这种图是互联网最常见的分层架构,当然真实的高并发系统架构会在此基础上进一步完善。比如会做动静分离并引入CDN,反向代理层可以是LVS+Nginx,Web层可以是统一的API网关,业务服务层可进一步按垂直业务做微服务化,存储层可以是各种异构数据库。

 

2、各层进行水平扩展:无状态水平扩容,有状态做分片路由。业务集群通常能设计成无状态的,而数据库和缓存往往是有状态的,因此需要设计分区键做好存储分片,当然也可以通过主从同步、读写分离的方案提升读性能。

 

 

 

3.2 具体的实践方案

下面再结合我的个人经验,针对高性能、高可用、高扩展3个方面,总结下可落地的实践方案。

❇ 高性能的实践方案

1、集群部署,通过负载均衡减轻单机压力。

2、多级缓存,包括静态数据使用CDN、本地缓存、分布式缓存等,以及对缓存场景中的热点key、缓存穿透、缓存并发、数据一致性等问题的处理。

3、分库分表和索引优化,以及借助搜索引擎解决复杂查询问题。

4、考虑NoSQL数据库的使用,比如HBase、TiDB等,但是团队必须熟悉这些组件,且有较强的运维能力。

5、异步化,将次要流程通过多线程、MQ、甚至延时任务进行异步处理。

6、限流,需要先考虑业务是否允许限流(比如秒杀场景是允许的),包括前端限流、Nginx接入层的限流、服务端的限流。

7、对流量进行削峰填谷,通过MQ承接流量。

8、并发处理,通过多线程将串行逻辑并行化。

9、预计算,比如抢红包场景,可以提前计算好红包金额缓存起来,发红包时直接使用即可。

10、缓存预热,通过异步任务提前预热数据到本地缓存或者分布式缓存中。

11、减少IO次数,比如数据库和缓存的批量读写、RPC的批量接口支持、或者通过冗余数据的方式干掉RPC调用。

12、减少IO时的数据包大小,包括采用轻量级的通信协议、合适的数据结构、去掉接口中的多余字段、减少缓存key的大小、压缩缓存value等。

13、程序逻辑优化,比如将大概率阻断执行流程的判断逻辑前置、For循环的计算逻辑优化,或者采用更高效的算法。

14、各种池化技术的使用和池大小的设置,包括HTTP请求池、线程池(考虑CPU密集型还是IO密集型设置核心参数)、数据库和Redis连接池等。

15、JVM优化,包括新生代和老年代的大小、GC算法的选择等,尽可能减少GC频率和耗时。

16、锁选择,读多写少的场景用乐观锁,或者考虑通过分段锁的方式减少锁冲突。

上述方案无外乎从计算和 IO 两个维度考虑所有可能的优化点,需要有配套的监控系统实时了解当前的性能表现,并支撑你进行性能瓶颈分析,然后再遵循二八原则,抓主要矛盾进行优化。

❇高度实用的解决方案

  1.对等节点的故障转移,Nginx和服务管理框架都支持一个节点在发生故障后访问另一节点。

  2.非对等节点的故障转移,通过心跳检测并实现主从切换(例如Redis哨兵模式或集群模式,MySQL主从切换等)。

  3.接口级别的超时设置,重试策略和幂等设计。

  4.降级处理:确保核心服务,牺牲非核心服务,必要时进行融合;或者,如果核心链接有问题,则有一个备用链接。

  5.电流限制处理:对于超出系统处理能力的请求,直接拒绝或返回错误代码。

  6. MQ场景中的消息可靠性保证,包括生产方重试机制,代理方持久性,消费者方ack机制等。

  7.灰度发布,可根据机器尺寸支持小流量部署,观察系统日志和业务指标,并在稳定运行后全额推送。

  8.监视和警报:全面的监视系统,包括最基本的CPU,内存,磁盘,网络监视,以及Web服务器,JVM,数据库,各种中间件监视和业务指标监视。

  9.灾难准备工作:与当前的“混乱工程”类似,对系统采取了一些破坏性措施来观察本地故障是否会引起可用性问题。

 

 

  高可用性解决方案主要从冗余,权衡以及系统运行和维护三个方向考虑。同时,它需要支持的职责机制和故障处理过程。如果存在在线问题,可以及时进行跟踪。

  ❇高度可扩展的实用解决方案

  1.合理的分层体系结构:例如,上面提到的Internet上最常见的分层体系结构,以及根据数据访问层和业务逻辑层对微服务进行的更细粒度的分层(但性能需要评估。网络再跳一跳)。

  2.存储层拆分:根据业务维度进行垂直拆分,并根据数据功能维度(子数据库和子表)进行水平拆分。

  3.业务层拆分:最常见的是根据业务维度(例如电子商务场景中的商品服务,订单服务等)进行拆分,或者根据核心接口和非核心接口进行拆分, 或根据请求来源(例如To C和To B,APP和H5)。

  最后的话

  高并发确实是一个复杂而系统的问题。由于空间有限,例如分布式跟踪,全链路压力测量和灵活的事务处理,都是要考虑的技术要点。此外,如果业务方案不同,则高并发性的着陆计划也将有所不同,但是总体设计思想和可供参考的计划基本上是相似的。

 

  高并发设计还必须遵守建筑设计的三个原则:简单性,适用性和演进性。  “过早的优化是万恶之源”,离不开企业的实际情况,更不能过度设计,适当的解决方案才是最完美的。

  希望本文能使您对高并发性有更全面的了解。如果您也有经验和深入的思想可以学习,请在评论区域中留下评论以进行讨论。

图片

 

这篇关于面试官再问高并发,求你把这篇发给他!的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1026532

相关文章

高并发环境中保持幂等性

在高并发环境中保持幂等性是一项重要的挑战。幂等性指的是无论操作执行多少次,其效果都是相同的。确保操作的幂等性可以避免重复执行带来的副作用。以下是一些保持幂等性的常用方法: 唯一标识符: 请求唯一标识:在每次请求中引入唯一标识符(如 UUID 或者生成的唯一 ID),在处理请求时,系统可以检查这个标识符是否已经处理过,如果是,则忽略重复请求。幂等键(Idempotency Key):客户端在每次

Java并发编程之——BlockingQueue(队列)

一、什么是BlockingQueue BlockingQueue即阻塞队列,从阻塞这个词可以看出,在某些情况下对阻塞队列的访问可能会造成阻塞。被阻塞的情况主要有如下两种: 1. 当队列满了的时候进行入队列操作2. 当队列空了的时候进行出队列操作123 因此,当一个线程试图对一个已经满了的队列进行入队列操作时,它将会被阻塞,除非有另一个线程做了出队列操作;同样,当一个线程试图对一个空

java线程深度解析(五)——并发模型(生产者-消费者)

http://blog.csdn.net/Daybreak1209/article/details/51378055 三、生产者-消费者模式     在经典的多线程模式中,生产者-消费者为多线程间协作提供了良好的解决方案。基本原理是两类线程,即若干个生产者和若干个消费者,生产者负责提交用户请求任务(到内存缓冲区),消费者线程负责处理任务(从内存缓冲区中取任务进行处理),两类线程之

java线程深度解析(四)——并发模型(Master-Worker)

http://blog.csdn.net/daybreak1209/article/details/51372929 二、Master-worker ——分而治之      Master-worker常用的并行模式之一,核心思想是由两个进程协作工作,master负责接收和分配任务,worker负责处理任务,并把处理结果返回给Master进程,由Master进行汇总,返回给客

深入解析秒杀业务中的核心问题 —— 从并发控制到事务管理

深入解析秒杀业务中的核心问题 —— 从并发控制到事务管理 秒杀系统是应对高并发、高压力下的典型业务场景,涉及到并发控制、库存管理、事务管理等多个关键技术点。本文将深入剖析秒杀商品业务中常见的几个核心问题,包括 AOP 事务管理、同步锁机制、乐观锁、CAS 操作,以及用户限购策略。通过这些技术的结合,确保秒杀系统在高并发场景下的稳定性和一致性。 1. AOP 代理对象与事务管理 在秒杀商品

PostgreSQL中的多版本并发控制(MVCC)深入解析

引言 PostgreSQL作为一款强大的开源关系数据库管理系统,以其高性能、高可靠性和丰富的功能特性而广受欢迎。在并发控制方面,PostgreSQL采用了多版本并发控制(MVCC)机制,该机制为数据库提供了高效的数据访问和更新能力,同时保证了数据的一致性和隔离性。本文将深入解析PostgreSQL中的MVCC功能,探讨其工作原理、使用场景,并通过具体SQL示例来展示其在实际应用中的表现。 一、

使用协程实现高并发的I/O处理

文章目录 1. 协程简介1.1 什么是协程?1.2 协程的特点1.3 Python 中的协程 2. 协程的基本概念2.1 事件循环2.2 协程函数2.3 Future 对象 3. 使用协程实现高并发的 I/O 处理3.1 网络请求3.2 文件读写 4. 实际应用场景4.1 网络爬虫4.2 文件处理 5. 性能分析5.1 上下文切换开销5.2 I/O 等待时间 6. 最佳实践6.1 使用 as

Go并发模型:流水线模型

Go作为一个实用主义的编程语言,非常注重性能,在语言特性上天然支持并发,Go并发模型有多种模式,通过流水线模型系列文章,你会更好的使用Go的并发特性,提高的程序性能。 这篇文章主要介绍流水线模型的流水线概念,后面文章介绍流水线模型的FAN-IN和FAN-OUT,最后介绍下如何合理的关闭流水线的协程。 Golang的并发核心思路 Golang并发核心思路是关注数据流动。数据流动的过程交给cha

【吊打面试官系列-Redis面试题】说说 Redis 哈希槽的概念?

大家好,我是锋哥。今天分享关于 【说说 Redis 哈希槽的概念?】面试题,希望对大家有帮助; 说说 Redis 哈希槽的概念? Redis 集群没有使用一致性 hash,而是引入了哈希槽的概念,Redis 集群有 16384 个哈希槽,每个 key 通过 CRC16 校验后对 16384 取模来决定放置哪个槽, 集群的每个节点负责一部分 hash 槽。

Java 入门指南:Java 并发编程 —— 并发容器 ConcurrentLinkedDeque

文章目录 ConcurrentLinkedDeque特点构造方法常用方法使用示例注意事项 ConcurrentLinkedDeque ConcurrentLinkedDeque 是 Java 并发工具包(java.util.concurrent 包)中的一个线程安全的双端队列(Deque)实现,实现了 Deque 接口。它使用了链表结构,并且针对高并发环境进行了优化,非常适合