高并发的杂谈

1、什么是高并发
高并发是互联网分布式系统架构设计中必须考虑的因素之一,就是通过设计保证系统可以并行处理很多请求。

2、高并发衡量指标
响应时间:系统对请求做出响应的时间,即一个http请求返回所用的时间
吞吐量:单位时间内处理的请求数量。
QPS:每秒可以处理的请求数。
并发用户数:同时承载正常使用系统功能的用户数量,即多少人同时使用,系统还能正常运行的用户数量。

3、架构杂谈
(1)流控:后台服务可以支撑的最大并发量,虽然可以提升单机的性能或者是可以通过添加节点的方法横向扩展,但考虑到成本通常后台服务都会存在一个预估的能力上限。后台服务的最大支撑能力低于了实际用户的请求量,那么对后台系统造成的影响,严重的话整个后台服务都会出现不可用,根据业务场景定制合理的流控策略。
(2)负载均衡:网关层除了流控功能外,还有一个重要的负载均衡的作用。将大量用户的请求通过负载均衡策略合理地分发给后端节点。每个节点分配不同的权重。现在对网络负载均衡的使用是随着网站规模的提升根据不同的阶段来使用不同的技术:第一阶段:利用Nginx或HAProxy进行单点的负载均衡,这一阶段服务器规模刚脱离开单服务器、单数据库的模式,需要一定的负载均衡,但是仍然规模较小没有专业的维护团队来进行维护,也没有需要进行大规模的网站部署。这样利用Nginx或HAproxy就是第一选择,此时这些东西上手快, 配置容易,在七层之上利用HTTP协议就可以。这时是第一选择。第二阶段:随着网络服务进一步扩大,这时单点的Nginx已经不能满足,这时使用LVS或者商用Array就是首要选择,Nginx此时就作为LVS或者Array的节点来使用,具体LVS或Array的是选择是根据公司规模和预算来选择,Array的应用交付功能非常强大,本人在某项目中使用过,性价比也远高于F5,商用首选,但是一般来说这阶段相关人才跟不上业务的提升,所以购买商业负载均衡已经成为了必经之路。第三阶段:这时网络服务已经成为主流产品,此时随着公司知名度也进一步扩展,相关人才的能力以及数量也随之提升,这时无论从开发适合自身产品的定制,以及降低成本来讲开源的LVS,已经成为首选,这时LVS会成为主流。最终形成比较理想的基本架构为:Array/LVS —Nginx/Haproxy — Squid/Varnish — AppServer。
(3)接入层:通过网关层执行一些基础的流控策略,然后再由网关层将请求转发给后端的接入层。接入层主要实现一些业务层面的基本校验功能,比如登录态校验。可过滤大部分非法请求,为合法的用户请求留出有限的后台资源。通常接入层都是无状态的,可横向扩展。
(4)逻辑层:根据“前轻后重”的原则,接入层一般只执行一些轻量的业务逻辑,真正核心的业务逻辑放在逻辑层来实现。逻辑层是真正核心处理的模块,它的处理能力决定了整个服务的质量,设计原则:缩短关键业务流程、降低单个接口处理时耗、同步变异步、隔离。
(5)存储层:解决的是数据快速访问,大数据量如何存储,以及数据一致性安全问题。对应的解决方案分别是缓存,分库分表,数据如何同步备份。

4、常见的问题
(1)对数据化的指标没有概念。
(2)设计了一些方案,但是细节掌握不透彻。
(3)理解片面,把高并发设计等同于性能优化。
(4)掌握大方案,却忽视最基本的东西。

高并发意味着大流量,需要运用技术手段抵抗流量的冲击,带给用户更好的体验。常见的高并发场景有:微信除夕红包、淘宝的双11、春运时的抢票、微博大V的热点新闻等。
业务都是从0开始做起来的,并发量和QPS只是参考指标,最重要的是:在业务量逐渐变成原来的10倍、100倍的过程中,是否用到了高并发的处理方法去演进系统,从架构设计、编码实现预防和解决高并发引起的问题,而不是一味的升级硬件、加机器做水平扩展。各个高并发场景的业务特点完全不同:有读多写少的信息流场景、有读多写多的交易场景,那是否有通用的技术方案解决不同场景的高并发问题呢?

高并发系统设计的目标
高并发系统设计的目标有三个:高性能、高可用,以及高可扩展。
1、高性能:性能体现了系统的并行处理能力,在有限的硬件投入下,提高性能意味着节省成本,提高性能用户体验。
2、高可用:系统可以正常服务的时间。
3、高扩展:系统的扩展能力,流量高峰时能否在短时间内完成扩容,更平稳地承接峰值流量。
这3个目标它们互相关联、也会相互影响。
比如说:考虑系统的扩展能力,会将服务设计成无状态的,这种集群设计保证了高扩展性,其实也间接提升了系统的性能和可用性。
再比如说:为了保证可用性,通常会对服务接口进行超时设置,以防大量线程阻塞在慢请求上造成系统雪崩,那超时时间设置成多少合理呢?一般,我们会参考依赖服务的性能表现进行设置。
可扩展性:面对突发流量,不可能临时改造架构,最快的方式就是增加机器来线性提高系统的处理能力。对于业务集群或者基础组件来说,扩展性 = 性能提升比例 / 机器增加比例,理想的扩展能力是:资源增加几倍,性能提升几倍。通常来说,扩展能力要维持在70%以上。但是从高并发系统的整体架构角度来看,扩展的目标不仅仅是把服务设计成无状态就行了,因为当流量增加10倍,业务服务可以快速扩容10倍,但是数据库可能就成为了新的瓶颈。像MySQL这种有状态的存储服务通常是扩展的技术难点,如果架构上没提前做好规划(垂直和水平拆分),就会涉及到大量数据的迁移。因此,高扩展性需要考虑:服务集群、数据库、缓存和消息队列等中间件、负载均衡、带宽、依赖的第三方等,当并发达到某一个量级后,上述每个因素都可能成为扩展的瓶颈点。

高并发的实践方案:通用的设计方法主要是从「纵向」和「横向」两个维度出发,俗称高并发处理的两板斧:纵向扩展和横向扩展。
纵向扩展(scale-up):它的目标是提升单机的处理能力,方案又包括:
1、提升单机的硬件性能:通过增加内存、CPU核数、存储容量、或者将磁盘升级成SSD等堆硬件的方式来提升。
2、提升单机的软件性能:使用缓存减少IO次数,使用并发或者异步的方式增加吞吐量。
横向扩展(scale-out):单机性能总会存在极限,所以最终还需要引入横向扩展,通过集群部署以进一步提高并发处理能力,又包括以下2个方向:
1、做好分层架构:这是横向扩展的提前,因为高并发系统往往业务复杂,通过分层处理可以简化复杂问题,更容易做到横向扩展。真实的高并发系统架构会做动静分离并引入CDN,反向代理层可以是LVS+Nginx,Web层可以是统一的API网关,业务服务层可进一步按垂直业务做微服务化,存储层可以是各种异构数据库。
2、各层进行水平扩展:无状态水平扩容,有状态做分片路由。业务集群通常能设计成无状态的,而数据库和缓存往往是有状态的,因此需要设计分区键做好存储分片,当然也可以通过主从同步、读写分离的方案提升读性能。

高性能的方案: 集群部署,通过负载均衡减轻单机压力。多级缓存,包括静态数据使用CDN、本地缓存、分布式缓存等,以及对缓存场景中的热点key、缓存穿透、缓存并发、数据一致性等问题的处理。分库分表和索引优化,以及借助搜索引擎解决复杂查询问题。异步化,将次要流程通过多线程、MQ、甚至延时任务进行异步处理。限流,需要先考虑业务是否允许限流(比如秒杀场景是允许的),包括前端限流、Nginx接入层的限流、服务端的限流。对流量进行削峰填谷,通过MQ承接流量。并发处理、预计算等。缓存预热,通过异步任务提前预热数据到本地缓存或者分布式缓存中。减少IO次数,比如数据库和缓存的批量读写、RPC的批量接口支持、或者通过冗余数据的方式去掉RPC调用。减少IO时的数据包大小,包括采用轻量级的通信协议、合适的数据结构、去掉接口中的多余字段、减少缓存key的大小、压缩缓存value等。程序逻辑优化,采用更高效的算法。各种池化技术的使用和池大小的设置。锁选择,读多写少的场景用乐观锁,或者考虑通过分段锁的方式减少锁冲突。

从计算和 IO 两个维度考虑所有可能的优化点,需要有配套的监控系统实时了解当前的性能表现,并支撑进行性能瓶颈分析,遵循二八原则,抓主要问题进行优化。

高可用的方案:对等节点的故障转移,Nginx和服务治理框架均支持一个节点失败后访问另一个节点。非对等节点的故障转移,通过心跳检测并实施主备切换(比如redis的哨兵模式或者集群模式、MySQL的主从切换等)。接口层面的超时设置、重试策略和幂等设计。熔断降级处理:保证核心服务,牺牲非核心服务,必要时进行熔断;或者核心链路出问题时,有备选链路。限流处理:对超过系统处理能力的请求直接拒绝或者返回错误码。MQ场景的消息可靠性保证。灰度发布,能支持按机器维度进行小流量部署,观察系统日志和业务指标,等运行平稳后再推全量。监控报警:全方位的监控体系,包括最基础的CPU、内存、磁盘、网络的监控,Web服务器、数据库、各类中间件的监控和业务指标的监控。

高扩展的方案:合理的分层架构,存储层的拆分,业务层的拆分。

高并发设计秉承架构设计的3个原则:简单、合适和演进。“过早的优化是万恶之源”,不能脱离业务的实际情况,更不要过度设计,合适的方案就是最完美的。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值