高并发先导片

高并发这个是我们在工作或者面试中都不能避免的话题,尤其在电商领域经常会有秒杀抢购等场景,或者当前热点,一个热搜冲下去,这些社交网站流量就瞬时飙升。那如何去设计高并发系统呢?该注意哪些因素?

拿大名鼎鼎的Redis为例,其为追求更好的性能,满足高并发,做了很多的设计,存储使用内存,异步刷新磁盘,还有从之前的单线程+IO多路复用,到后面的主线程+多路复用+后台异步线程,再到后来的多路复用+IO多线程处理IO+主线程处理命令+后台异步线程等模式,Redis cluster集群等等。都是在为更高性能高可用在不断地演进着。

那对于实际业务系统来说,尤其是对于电商来说,瞬时高并发量的处理能力也一定程度上表现了一个电商系统的技术水平。如果一到抢购活动或者其他大促时系统都会崩溃,QPS稍微高一点,系统都应付不了,那简直是灾难了。最早的小米抢购就很垃圾,一秒杀手机就经常崩,当然经过多次的迭代已经有了较大的进步。目前在我看来处理高并发最牛逼的应该属阿里淘宝,以及12306了,尤其是12306,一到春节,QPS高得吓人。

那我们谈论高并发应该谈论哪些点?一个是高性能,另一个就是高可用。高性能表示了系统可以有能力且高校地处理高并发请求,在硬件和软件上都可表现较好的系统性能;高可用侧重表示了系统不会因为高并发而崩溃,永远保持可访问。

高性能:

硬件:

单机配置:CPU,磁盘,内存、网络带宽

分布式:通过服务拆分,划分微服务,分而治之,服务边界清晰,相互独立,通过微服务治理以及API网关,为前端输出提供一套完整的分布式系统;当然要考虑分布式一致性,容错性等方面。

集群:单服务多实例,以集群的方式部署,通过负载均衡实现请求分摊;

软件:

数据库:分库分表(Mycat,Gaea),主从读写分离(Kingshard),数据归档,SQL性能调优;

缓存:通过设置多级别缓存,降低数据库请求,降低CPU资源消耗,堆内,堆外缓存,Redis缓存等;

并发编程:多进程,多线程,协程,IO多路复用等方式实现并发编程,池的使用,线程池,近程池等等;

异步:通过将请求处理异步化,提高接口相应,注意线程池的配置和隔离;

消息队列:消峰,解耦,比如RocketMQ,Kafka都是比较优秀的消息队列中间件;

CDN:通过CDN实现静态资源内容分发,降低应用请求;

反向代理:   Nginx是首选

高性能方面可做功课的地方的确还是很多的。

先说单服务器的提升。强东之前说京东第一台服务器是用前台妹子的(虽然有点扯蛋),最初像淘宝更多可能都是单体应用。那对于一个服务器来说,其处理性能是关键。一般一台服务器有100G内存,24核CPU已经很牛鼻了,此外最好固态硬盘,容量超过1T。操作系统一般都是Linux。

单体应用必然会存在瓶颈,因此需要进行水平扩展。而水平扩展的前提就是需要进行业务分层。比如一个完整系统从客户端开始一直到数据存储层要分成N个层。一个比较好的例子就是下面参考资料中提到的淘宝架构:

一个系统架构图包含了很多的知识点:DNS、LVS、Nginx、API网关、微服务、缓存、数据库分库分表、ES、HBase、HDFS等等。

DNS简单说就是通过一个域名配置多个机房的IP,通过DNS轮询来实现分流。

LVS是一种硬件实现的负载均衡,性能超吊。

Nginx这个就不用多说了,反向代理,优越的高并发支持,可轻松实现应用层的负载均衡。

微服务,这个也是目前比较流行的开发部署模式。目前都是按照功能模块拆分成多个微服务,服务间相互独立,通过RPC实现远程调用。

API网关,这个是为了微服务存在的,通过服务网关实现统一调用,鉴权,服务编排,缓存,缓存等等。

缓存,缓存涉及到的东西比较多,几乎每层都可以有缓存,比如Nginx,HTTP,后端服务,Mysql等等。比较多的是本地缓存,此外还有分布式缓存,比如Redis,Memcached等。Redis因为其高性能以及丰富的数据结构,已经是后来者居上。

搜索引擎 ES对于任何一个电商开发都不陌生,无论是商品搜索还是订单搜索,都用到了ES,其内部使用了Lucence,主要的就是倒排索引,查询性能要更好。

数据库分库分表、读写分离是目前流行的数据库提升性能手段。

HDFS分布式文件系统,这个主要是解决单点存储文件因为故障率以及存储空间等问题的。它会将文件分块,并分别存储到不同的服务器上,每个块文件都会有备份。现在我们公司开发的talos,就是一种基于Kafka开发,且使用HDFS存储topic数据的消息队列。

HBase一种K-V存储的Nosql数据库。一般解决的应然是数据库性能问题,比如我们公司会将历史优惠券数据归档,存储到Hbase中。

还有就是代码本身,代码的高性能也一定程度上决定了并发量。通过良好的代码也可提供,比如是否可以充分利用CPU cache,是否使用了多并发,是否充分利用了多核CPU等等。

高可用

降级,熔断,异步,消息队列,集群、分布式、数据冗余。

高可用的主要目的是防止在高并发的情况下,系统仍然是可用的。针对此问题,就有着多种做法:

1、集群,集群的作用除了分摊承载压力,同样是一种备份,当集群中一部分机器挂掉,可将请求达到其他在线的机器上,从而保证整个服务仍然可用;

2、消息队列,异步,这两个应该是一起的,通过消息队列,将一些任务异步执行,可以削弱流量高峰,比如秒杀活动中,可以将下单请求放在消息队列中,削减整个系统的瞬时处理请求,保证系统的可用性;

3、降级,大促期间通常会将系统中不重要的服务停掉,避免占用系统资源。如电商系统的评论、我的收藏等。

4、限流 ,控制短时间内并发流量,这在电商秒杀场景中是必不可少的,通过限流可以拦截无用的流量,避免处理过量请求导致系统崩掉,当然如果遇到ddos攻击的话另当别论。比如秒杀中100件商品,可能10万以上,或者几十万以上的流量都是无用的,就可限制走系统业务逻辑;限流算法有计数器法,令牌桶,漏斗等等

5、熔断  熔断是保证当后端业务有异常时,可以及时摘除,避免影响整个链路。比如RTT较长,就可摘除上游服务。sentinel是一个不错的选择,或者Hytrix框架等。

6、机房异地多活:这个是很重要的,我曾经在联通当过一段的网络工程师,遇到过很多奇葩事件导致机房内设备出现问题。比如光纤断了,设备端口down了,光模块坏了,机房断电等等,如果服务器都在同一个机房还是有风险的,最好是不同的机房或者异地。像小米就会有c3,c4集群,两个集群会对接不同的运营商的不同的机房。

对于任何一次秒杀活动或者大促之前,开始前都要进行 流量预估、全链路压测,灾备演练, 服务降级等等准备工作。

结束语:高并发看着是一个高大上的东西,但是不能因为是高大上就动不动为高并发做各种设计。系统的设计最忌讳的是过度设计,如果最高并发量也只有几十,那就没有各种分布式,各种微服务,各种负载均衡了。淘宝的系统也是逐步的演进的,不是一蹴而就的。小米有品最开始的后端服务只有两个,数据库只有读写分离,后来因为业务不断发展,才开始做微服务,分库分表等系统升级。

参考资料:

不懂什么是高并发?看完这篇文章你可以去吊打面试官了

当我们在谈论高并发的时候究竟在谈什么?

淘宝服务端高并发分布式架构演进之路

高可用+高并发+负载均衡架构设计

大型网站系统架构

--------EOF---------
本文微信分享/扫码阅读