服务端高并发分布式架构演进

单机架构

应用程序+数据库都在一台机器上,通常用于项目初期用户量较小阶段,或者快速通过市场检验业务的阶段,没有对性能、安全有很高的要求,维护成本也较低

image-20260715142547763

Web 服务器软件:Tomcat、Netty、Nginx、Apache 等
数据库软件:MySQL、Oracle、PostgreSQL、SQL Server 等

应用数据分离架构

应用程序和数据库分别部署在两台机器上,通常使用socket网络通信,性能相较于单机架构会好一点

应用服务集群架构

并发量增加到一定程度,数据分离架构这时也无法满足要求,我们就需要多个机器上部署应用程序来降低每一台的并发量,因此我们还要在前面加一层负载均衡层,这里就涉及到一些负载均衡算法了:

  • Round-Robin 轮询算法。即非常公平地将请求依次分给不同的应用服务器

  • Weight-Round-Robin 轮询算法。为不同的服务器(比如性能不同)赋予不同的权重(weight),能者多劳

  • ⼀致哈希散列算法。通过计算用户的特征值(比如 IP 地址)得到哈希值,根据哈希结果做分发,优点是确保来⾃相同用户的请求总是被分给指定的服务器。也就是我们平时遇到的专项客户经理服务

这时的数据库还是只有一个,部署在一台额外的机器上

负载均衡软件:Nginx、HAProxy、LVS、F5 等负载均衡软件:Nginx、HAProxy、LVS、F5 等

读写分离/主从分离架构

随着应用服务器的增多,最后的数据请求都打到了数据库服务器上。所以现在数据库成了瓶颈了,因为无法保证数据一致性,所以我们不能像扩展应用服务器那样扩展数据库服务器

解决办法为,读写分离:保留一个主要的数据库为写入数据库,其他的数据库为读取数据库(从属数据库),所有的写操作都打到了主数据库上,所有的读操作都打到从属数据库上(读数据库可能有多个这里应该也有负载均衡),大部分的系统中,读写请求都是不成比例的,例如 100 次读 1 次写。当然这个过程不是无代价的,主库到从库的数据同步其实是由时间成本的,但这个问题我们暂时不做进一步探讨

MyCat、TDDL、Amoeba、Cobar等类似数据库中间件等

冷热分离架构(引入缓存)

随着读取请求越来越多,发现一些数据被读取的频率远大于其他数据

根据28法则,20%的数据就可以满足80%的请求,所以我们把那20%的数据通过本地缓存存起来,在用户要访问数据的时候先去访问缓存,如果缓存命中,直接返回;缓存没有命中,再去访问数据库,这样就可以大大减轻从数据库的压力

其中涉及的技术包括:使⽤ memcached 作为本地缓存,使⽤ Redis 作为分布式缓存,还会涉及缓存一致性、缓存穿透/击穿、缓存雪崩、热点数据集中失效等问题

垂直分库

随着业务规模越来越大,大量的数据存在一个库中有些力不从心了。所以可以根据业务逻辑,将不同的数据存在不同的库里面

比如针对评论数据,可按照商品ID进行hash,路由到对应的表中存储;针对支付记录,可按照小时创建表,每个小时表继续拆分为小表,使用用户ID或记录编号来路由数据。只要实时操作的表数据量足够够小,请求能够足够均匀的分发到多台服务器上的小表,那数据库就能通过水平扩展的方式来提高性能。其中前面提到的 Mycat 也支持在大表拆分为小表情况下的访问控制。这种做法显著的增加了数据库运维的难度,对DBA( Database Administrator,数据库管理员)的要求较高。数据库设计到这种结构时,已经可以称为分布式数据库,但是这只是⼀个逻辑的数据库整体,数据库里不同的组成部分是由不同的组件单独来实现的,如分库分表的管理和请求分发,由Mycat实现,SQL的解析由单机的数据库实现,读写分离可能由网关和消息队列来实现,查询结果的汇总可能由数据库接口层来实现等等,这种架构其实是MPP(大规模并行处理)架构的⼀类实现

相关软件:Greenplum、TiDB、Postgresql XC、HAWQ等,商用的如南大通用的GBase、睿帆科技的雪球DB、华为的 LibrA 等

微服务(业务拆分)

随着人员增加,业务发展,我们将业务分给不同的开发团队去维护,每个团队独立实现自己的微服务,然后互相之间对数据的直接访问进行隔离,可以利用 Gateway、消息总线等技术,实现相互之间的调用关联。甚至可以把一些类似用户管理、安全管理、数据采集等业务提成公共服务。

image-20260715142714726


Attention

以上的架构没有孰优孰劣,一切的架构选择都是在业务基础上。对于简单业务,可能选择单机架构就足够用了,对于类似几亿并发量的系统,我们就需要更加合理的架构设计。因此我们总能找到一种最合适于当前业务的架构,为了避免锤子精神,我们需要对当前业务有深入了解之后再谨慎做出选择。当然,在一开始工作的时候可能涉及不到类似的架构选择的工作,但是我们需要知道为什么当前业务选择了这种架构,当前架构对于当前业务有什么优势?又有什么不足需要补足?

Redis

Redis是一种基于键值对的非关系型数据库,Redis中的值可以是由 string(字符串)、hash(哈希)、list(列表)、set(集合)、zset(有序集合)、Bitmaps(位图)、HyperLogLog、GEO(地理信息定位)等多种数据结构和算法组成,因此 Redis 可以满足很多的应用场景,而且因为 Redis 会将所有数据都存放在内存中,所以它的读写性能非常惊人。不仅如此,Redis 还可以将内存的数据利用快照和日志的形式保存到硬盘上,这样在发生类似断电或者机器故障的时候,内存中的数据不会“丢失”。除了上述功能以外,Redis 还提供了键过期、发布订阅、事务、流水线、Lua 脚本等附加功能。总之,如果在合适的场景使⽤号 Redis,它就会像一把瑞士军刀一样所向披靡

使用场景

常见数据类型

客户端

持久化

Redis事务

主从复制

哨兵

集群

典型应用

缓存(cache)

分布式锁

常见面试题