高并发系统通用设计方法是什么?
高并发代表着大流量,举个例子,从古至今对黄河的治理,大禹治水是拓宽河道,清除淤泥,让水流更通畅,流向大海。都江堰是通过引流的方式将岷江之水分流到多个支流,分担水流压力。三峡门和葛洲坝采用的是建造水库的方式将水储存起来然后把水库中的水缓缓排出去,提高下游抗洪能力。
高并发系统的设计三种思路
上面的例子也提到了三个例子,其实代表了高并发系统设计的三种思路。
- Scale-out(横向扩展):分而治之的思想,在算法中也常见,这是一种常见的高并发系统设计思路,采用分布式部署方案,将流量分开,让每个服务器都承担一定流量。
- 缓存:使用缓存来提高系统的性能,好比“拓宽河道”的方式抵抗高并发流量的冲击。
- 异步:在某些场景下,未处理完成之前,我们可以让请求先返回,在数据准备好之后再通知请求方,这样可以在单位时间内处理更多的请求。
横向扩展,纵向扩展 Scale-up vs Scale-out
Scale-up (纵向扩展) Scale-out(横向扩展)。举个例子,摩尔定律,摩尔定律是指每18个月 CPU 的性能要翻一倍。这种不断追逐摩尔定律,不断提升 CPU 的方案,就叫做 Scale-up(纵向扩展),把类似CPU 多核心的方案叫做 Scale-out(横向扩展)。
- Scale-up: 通过构面更好的硬件来提升系统的并发处理能力,比如从硬件 4核 4G 每秒处理 200 次请求, 那么如果要处理 400 次请求呢,例如可以把硬件升级到 8核 8G
- Scale-out ,则是另外一个思路,可以通过多个低性能的集群组成一个分布式集群来共同抵御高并发流量的冲击。 比如可以使用两台 4 核 4G 的机器来处理每秒 400 次请求。
scale-up 与 sclae-out 如何选择
系统设计最初的时候,会考虑使用 Scale-up 的方式,因为此方法简单,升级相关硬件就可以,但是当系统并发突破了单台机器的基线时,这个时候,就需要考虑scale-out 的方式。
scale-out 虽然突破了单机的限制,但是会出现分布式系统的问题,就是分布式系统中的 CAP 理论,如何保证多个节点的数据一致性?如何保证系统的可用性?如何无感知的增加或者删除节点?
使用缓存提升性能
大禹治水的时候疏通淤泥,防止阻塞,提高性能。
缓存主要是在高并发系统情况下,能够支撑多用户同时访问。主要是缓存的高性能,基于数据库存储,一般的持久化都是使用磁盘作为存储介质。通过机械,磁头,转轴等方式访问磁道和扇区。这个速度肯定不会特别快。
一般来说磁盘寻磁道的时间大概是 10ms 左右。相对磁盘的花费时间,CPU 执行指令,和内存寻址的时间都是 ns级别。从千兆网卡是读取的时间是 us 微秒级别。整个计算机体系中,磁盘是最慢的,这也是为啥很多计算机升级成固态硬盘。我们常说的缓存,一般是以内存作为存储介质的。可以提升性能。
异步
异步也是高并发系统的一种设计思路,反义词是同步。
- 同步,当进行同步操作时,需要进行等待调用返回,才继续往下进行。
- 异步: 不需要等待当前调用返回,通常通过事件或者回调机制来实现任务建调用次序。
同步会阻塞等待被调用方的逻辑执行完成,才会继续往下执行,这样存在个问题,当被调用方法响应时间长时,会造成调用方长久阻塞,在高并发的情况下会出现整个系统性能下降,甚至发生雪崩。
异步调用在高并发系统中经常被调用,大家熟悉的 12306 就是,订票时,可以看到系统显示在排队,其实这个就表示在异步处理我们的订票请求。其次 12306 系统中的余票查询,下单,更改余票状态,这些操作都是耗时操作,一般是采用异步的方式,将请求丢到消息队列中,同时快速响应用户,告诉用户正在排队处理,然后释放资源出来处理更多的请求,订票请求完成后,再通知用户是订票成功还是失败。
系统设计演进过程思路
罗马不是一天建成的!高并发系统的演进应该是循序渐进,以解决系统中存在的问题为目的和驱动力的。
- 系统设计满足业务需求和流量现状,选择最熟悉的技术体系
- 业务需求增加和流量增加,修正架构中存在的问题,如单点问题,横向扩展问题,性能无法满足需求等,选择社区中成熟的,团队熟悉的合适的组件去解决问题。
- 当对整个架构进行修补无法满足需求时,才需要重构和重写的方式进行大的架构调整。
以淘宝为例,当时在业务从0到1的阶段是通过购买的方式快速搭建了系统。而后,随着流昰的增长,淘宝做了一系列的技术改造来提升高并发处理能力,比如数据库存储引擎从 MyISAM 迁移到 InnoDB,数据库做分库分表,增加缓存,启动中间件研发等。