| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 大数据 -> 阿里P8面试官:如何设计一个扛住千万级并发的架构(超级详细) -> 正文阅读 |
|
[大数据]阿里P8面试官:如何设计一个扛住千万级并发的架构(超级详细) |
如何降低RT的值继续看上面这个图,一个请求只有等到tomcat容器中的应用执行完成才能返回,而请求在执行过程中会做什么事情呢?
这些操作每一个步骤都会消耗时间,当前客户端的请求只有等到这些操作都完成之后才能返回,所以降低RT的方法,就是优化业务逻辑的处理。 数据库瓶颈的优化当18000个请求进入到服务端并且被接收后,开始执行业务逻辑处理,那么必然会查询数据库。 每个请求至少都有一次查询数据库的操作,多的需要查询3~5次以上,我们假设按照3次来计算,那么每秒会对数据库形成54000个请求,假设一台数据库服务器每秒支撑10000个请求(影响数据库的请求数量有很多因素,比如数据库表的数据量、数据库服务器本身的系统性能、查询语句的复杂度),那么需要6台数据库服务器才能支撑每秒10000个请求。 除此之外,数据库层面还有涉及到其他的优化方案。
磁盘数据访问优化对于磁盘的操作,无非就是读和写。 比如对于做交易系统的场景来说,一般会设计到对账文件的解析和写入。而对于磁盘的操作,优化方式无非就是
合理利用内存充分利用内存缓存,把一些经常访问的数据和对象保存在内存中,这样可以避免重复加载或者避免数据库访问带来的性能损耗。 调用远程服务远程服务调用,影响到IO性能的因素有。
异步化架构微服务中的逻辑复杂处理时间长的情况,在高并发量下,导致服务线程消耗尽,不能再创建线程处理请求。对这种情况的优化,除了在程序上不断调优(数据库调优,算法调优,缓存等等),可以考虑在架构上做些调整,先返回结果给客户端,让用户可以继续使用客户端的其他操作,再把服务端的复杂逻辑处理模块做异步化处理。这种异步化处理的方式适合于客户端对处理结果不敏感不要求实时的情况,比如群发邮件、群发消息等。 异步化设计的解决方案: 多线程、MQ。 应用服务的拆分除了上述的手段之外,业务系统往微服务化拆分也非常有必要,原因是:
其实,最终要的是,单个应用在性能上的瓶颈很难突破,也就是说如果我们要支持18000QPS,单个服务节点肯定无法支撑,所以服务拆分的好处,就是可以利用多个计算机阶段组成一个大规模的分布式计算网络,通过网络通信的方式完成一整套业务逻辑。 如何拆分服务如何拆分服务,这个问题看起来简单,很多同学会说,直接按照业务拆分啊。 但是实际在实施的时候,会发现拆分存在一些边界性问题,比如有些数据模型可以存在A模块,也可以存在B模块,这个时候怎么划分呢?另外,服务拆分的粒度应该怎么划分? 一般来说,服务的拆分是按照业务来实现的,然后基于DDD来指导微服务的边界划分。领域驱动就是一套方法论,通过领域驱动设计方法论来定义领域模型,从而确定业务边界和应用边界,保证业务模型和代码模型的一致性。不管是DDD还是微服务,都要遵循软件设计的基本原则:高内聚低耦合。服务内部高内聚,服务之间低耦合,实际上一个领域服务对应了一个功能集合,这些功能一定是有一些共性的。比如,订单服务,那么创建订单、修改订单、查询订单列表,领域的边界越清晰,功能也就越内聚,服务之间的耦合性也就越低。 服务拆分还需要根据当前技术团队和公司所处的状态来进行。 如果是初创团队,不需要过分的追求微服务,否则会导致业务逻辑过于分散,技术架构太过负载,再加上团队的基础设施还不够完善,导致整个交付的时间拉长,对公司的发展来说会造成较大的影响。所以在做服务拆分的时候还需要考虑几个因素。
如果是针对一个老的系统进行改造,那可能涉及到的风险和问题更多,所以要开始着手改动之前,需要考虑几个步骤:拆分前准备阶段,设计拆分改造方案,实施拆分计划
另外,每个阶段需要聚焦到一两个具体的目标,否则目标太多反而很难把一件事儿做通透。例如某个系统的微服务拆分,制定了如下的几个目标:
当然,不要期望一次性完成所有目标,每一个阶段可以选择一个两个优先级高的目标进行执行。 微服务化架构带来的问题微服务架构首先是一个分布式的架构,其次我们要暴露和提供业务服务能力,然后我们需要考虑围绕这些业务能力的各种非功能性的能力。这些分散在各处的服务本身需要被管理起来,并且对服务的调用方透明,这样就有了服务的注册发现的功能需求。 同样地,每个服务可能部署了多台机器多个实例,所以,我们需要有路由和寻址的能力,做负载均衡,提升系统的扩展能力。有了这么多对外提供的不同服务接口,我们一样需要有一种机制对他们进行统一的接入控制,并把一些非业务的策略做到这个接入层,比如权限相关的,这就是服务网关。同时我们发现随着业务的发展和一些特定的运营活动,比如秒杀大促,流量会出现十倍以上的激增,这时候我们就需要考虑系统容量,服务间的强弱依赖关系,做服务降级、熔断,系统过载保护等措施。 以上这些由于微服务带来的复杂性,导致了应用配置、业务配置,都被散落到各处,所以分布式配置中心的需求也出现了。最后,系统分散部署以后,所有的调用都跨了进程,我们还需要有能在线上做链路跟踪,性能监控的一套技术,来协助我们时刻了解系统内部的状态和指标,让我们能够随时对系统进行分析和干预。 整体架构图基于上述从微观到宏观的整体分析,我们基本上能够设计出一个整体的架构图。
了解什么是高并发总结一下什么是高并发。 高并发并没有一个具体的定义,高并发主要是形容突发流量较高的场景。 如果面试的过程中,或者在实际工作中,你们领导或者面试官问你一个如何设计承接千万级流量的系统时,你应该要按照我说的方法去进行逐一分析。
高并发中的宏观指标一个满足高并发系统,不是一味追求高性能,至少需要满足三个宏观层面的目标:
微观指标性能指标 通过性能指标可以度量目前存在的性能问题,同时作为性能优化的评估依据。一般来说,会采用一段时间内的接口响应时间作为指标。 1、平均响应时间:最常用,但是缺陷很明显,对于慢请求不敏感。比如 1 万次请求,其中 9900 次是 1ms,100 次是 100ms,则平均响应时间为 1.99ms,虽然平均耗时仅增加了 0.99ms,但是 1%请求的响应时间已经增加了 100 倍。 2、TP90、TP99 等分位值:将响应时间按照从小到大排序,TP90 表示排在第 90 分位的响应时间, 分位值越大,对慢请求越敏感。 可用性指标 高可用性是指系统具有较高的无故障运行能力,可用性 = 平均故障时间 / 系统总运行时间,一般使用几个 9 来描述系统的可用性。 对于高并发系统来说,最基本的要求是:保证 3 个 9 或者 4 个 9。原因很简单,如果你只能做到 2 个 9,意味着有 1%的故障时间,像一些大公司每年动辄千亿以上的 GMV 或者收入,1%就是 10 亿级别的业务影响。 可扩展性指标 面对突发流量,不可能临时改造架构,最快的方式就是增加机器来线性提高系统的处理能力。 对于业务集群或者基础组件来说,扩展性 = 性能提升比例 / 机器增加比例,理想的扩展能力是:资源增加几倍,性能提升几倍。通常来说,扩展能力要维持在 70%以上。 但是从高并发系统的整体架构角度来看,扩展的目标不仅仅是把服务设计成无状态就行了,因为当流量增加 10 倍,业务服务可以快速扩容 10 倍,但是数据库可能就成为了新的瓶颈。 像 MySQL 这种有状态的存储服务通常是扩展的技术难点,如果架构上没提前做好规划(垂直和水平拆分),就会涉及到大量数据的迁移。 因此,高扩展性需要考虑:服务集群、数据库、缓存和消息队列等中间件、负载均衡、带宽、依赖的第三方等,当并发达到某一个量级后,上述每个因素都可能成为扩展的瓶颈点。 实践方案通用设计方法 纵向扩展(scale-up) 它的目标是提升单机的处理能力,方案又包括: 1、提升单机的硬件性能:通过增加内存、CPU 核数、存储容量、或者将磁盘升级成 SSD 等堆硬件的方式来提升。 2、提升单机的软件性能:使用缓存减少 IO 次数,使用并发或者异步的方式增加吞吐量。 横向扩展(scale-out) 因为单机性能总会存在极限,所以最终还需要引入横向扩展,通过集群部署以进一步提高并发处理能力,又包括以下 2 个方向: 1、做好分层架构:这是横向扩展的提前,因为高并发系统往往业务复杂,通过分层处理可以简化复杂问题,更容易做到横向扩展。 2、各层进行水平扩展:无状态水平扩容,有状态做分片路由。业务集群通常能设计成无状态的,而数据库和缓存往往是有状态的,因此需要设计分区键做好存储分片,当然也可以通过主从同步、读写分离的方案提升读性能。 高性能实践方案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、锁选择,读多写少的场景用乐观锁,或者考虑通过分段锁的方式减少锁冲突。 高可用实践方案1、对等节点的故障转移,Nginx 和服务治理框架均支持一个节点失败后访问另一个节点。 2、非对等节点的故障转移,通过心跳检测并实施主备切换(比如 redis 的哨兵模式或者集群模式、MySQL 的主从切换等)。 3、接口层面的超时设置、重试策略和幂等设计。 4、降级处理:保证核心服务,牺牲非核心服务,必要时进行熔断;或者核心链路出问题时,有备选链路。 5、限流处理:对超过系统处理能力的请求直接拒绝或者返回错误码。 6、MQ 场景的消息可靠性保证,包括 producer 端的重试机制、broker 侧的持久化、consumer 端的 ack 机制等。 7、灰度发布,能支持按机器维度进行小流量部署,观察系统日志和业务指标,等运行平稳后再推全量。 8、监控报警:全方位的监控体系,包括最基础的 CPU、内存、磁盘、网络的监控,以及 Web 服务器、JVM、数据库、各类中间件的监控和业务指标的监控。 9、灾备演练:类似当前的“混沌工程”,对系统进行一些破坏性手段,观察局部故障是否会引起可用性问题。 高可用的方案主要从冗余、取舍、系统运维 3 个方向考虑,同时需要有配套的值班机制和故障处理流程,当出现线上问题时,可及时跟进处理。 高扩展的实践方案1、合理的分层架构:比如上面谈到的互联网最常见的分层架构,另外还能进一步按照数据访问层、业务逻辑层对微服务做更细粒度的分层(但是需要评估性能,会存在网络多一跳的情况)。 2、存储层的拆分:按照业务维度做垂直拆分、按照数据特征维度进一步做水平拆分(分库分表)。 3、业务层的拆分:最常见的是按照业务维度拆(比如电商场景的商品服务、订单服务等),也可以按照核心接口和非核心接口拆,还可以按照请求去拆(比如 To C 和 To B,APP 和 H5)。 举报 评论?3 |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/24 2:41:03- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |