【Redis】《一文走完服务端高并发架构演进:从单机架构到 K8S 容器编排》

一.概述

在进⾏技术学习过程中,由于⼤部分读者没有经历过⼀些中⼤型系统的实际经验,导致⽆法从全

局理解⼀些概念,所以本⽂以⼀个 "电⼦商务" 应⽤为例,介绍从⼀百个到千万级并发情况下服务端的架构的演进过程,同时列举出每个演进阶段会遇到的相关技术,让⼤家对架构的演进有⼀个整体的认知,⽅便⼤家对后续知识做深⼊学习时有⼀定的整体视野。


二.常见概念

在正式引⼊架构演进之前,为避免读者对架构中的概念完全不了解导致低效沟通,优先对其中⼀

些⽐较重要的概念做前置介绍:


1.基本概念

(1)应⽤(Application)/ 系统(System)

为了完成一整套服务的一个程序或者一组相互配合的程序群。

一个应用就是一个 / 组服务器程序。

拿一个生活中的例子来做类比:为了完成一项任务,而搭建的由一个人或者一群相互配的人组成的团队。


(2)模块(Module)/ 组件(Component)

当应⽤较复杂时,为了分离职责,将其中具有清晰职责的、内聚性强的部分,抽象出概念,便于理解。

⽣活例⼦类⽐:军队中为了进⾏某据点的攻克,将⼈员分为突击⼩组、爆破⼩组、掩护⼩组、通信⼩组等。


(3)分布式(Distributed)

系统中的多个模块被部署于不同服务器之上,即可以将该系统称为分布式系统。如 Web 服务器与数据库分别⼯作在不同的服务器上,或者多台 Web 服务器被分别部署在不同服务器上。⽣活例⼦类⽐:为了更好的满⾜现实需要,⼀个在同⼀个办公场地的⼯作⼩组被分散到多个城市的不同⼯作场地中进⾏远程配合⼯作完成⽬标。跨主机之间的模块之间的通信基本要借助⽹络⽀撑完成。


(4)集群(Cluster)

被部署于多台服务器上的、为了实现特定⽬标的⼀个/组特定的组件,整个整体被称为集群。⽐如多个 MySQL ⼯作在不同服务器上,共同提供数据库服务⽬标,可以被称为⼀组数据库集群。

⽣活例⼦类⽐:为了解决军队攻克防守坚固的⼤城市的作战⽬标,指挥部将⼤批炮兵部队集中起来形成⼀个炮兵打击集群。


(5)分布式 vs 集群

通常不⽤太严格区分两者的细微概念,细究的话,分布式强调的是物理形态,即⼯作在不同服务器上并且通过⽹络通信配合完成任务;⽽集群更在意逻辑形态,即是否为了完成特定服务⽬标。


(6)主(Master)/ 从(Slave)

集群中,通常有⼀个程序需要承担更多的职责,被称为主;其他承担附属职责的被称为从。⽐如MySQL 集群中,只有其中⼀台服务器上数据库允许进⾏数据的写⼊(增/删/改),其他数据库的数据修改全部要从这台数据库同步⽽来,则把那台数据库称为主库,其他数据库称为从库。


(7)中间件(Middleware

什么是中间件?

中间件(Middleware)是一类提供不同应用程序用于相互通信的软件,即处于不同技术、工具和数据库之间的桥梁。它的核心价值是解耦 、复用 、异步处理 、削峰填谷等。

中间件的定位 :

中间件是与具体业务逻辑解耦的通用基础设施,它为业务提供通用的能力支撑(如通信、缓存、消息、协调),但本身不包含业务逻辑。

常见的中间件分类:

  • 消息队列:Kafka、RabbitMQ、RocketMQ

  • 缓存:Redis、Memcached

  • RPC 框架:Dubbo、gRPC

  • Web 服务器:Nginx、Tomcat

  • 配置中心:Nacos、Apollo

  • 网关:Spring Cloud Gateway

  • 分布式协调:ZooKeeper、etcd

注意 :数据库本身不算中间件(它是数据存储系统),但数据库中间件(如 ShardingSphere、MyCat)算------它们负责分库分表、读写分离,是应用和数据库之间的桥梁。

生活类比 :

一家饭店开始时,每天去市场买菜;随着业务量变大,成立一个采购部,由采购部专职于采买业务,成为厨房和菜市场之间的桥梁。这个采购部就像中间件------它解耦 了厨房和菜市场,提供了专业化的通用服务。如果再大一点,采购部可能还会拆分成"生鲜采购组"和"干货采购组",这就像中间件也会根据场景细分为消息中间件、缓存中间件、RPC 中间件等。


(8)容器(Docker)

什么是 Docker?

Docker 是一个开源的应用容器引擎 ,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像(Image) 中,然后发布到任何支持 Docker 的 Linux 或 Windows 机器上运行。

Docker 是虚拟化吗?

Docker 属于容器化(Containerization) 技术,更准确地说是"操作系统级别的虚拟化"。它和传统虚拟机(VM)有本质区别:

  • 虚拟机 :虚拟的是硬件,每个 VM 有独立的操作系统内核,重量级,启动慢(分钟级)。

  • Docker 容器 :虚拟的是操作系统层,所有容器共享宿主机的内核,轻量级,启动快(秒级甚至毫秒级)。

注意:Docker 镜像不是完全跨平台的。Linux 镜像只能在 Linux 内核上运行(Windows 上需要通过 WSL2 或 Hyper-V 模拟 Linux 内核),Windows 镜像只能在 Windows 上运行。

生活类比 :

可以理解为一个集装箱 。集装箱里面是每个用户的货物(应用),整体打包。集装箱不仅打包了货物,还打包了货架、说明书、操作工具 (依赖包、环境变量、配置文件),所以不管运到哪个港口(服务器),打开集装箱就能直接工作,不需要重新装修(配置环境)。这正是 Docker 解决"在我的机器上能跑,在你的机器上跑不起来"问题的核心价值。


(9)容器编排(K8S)

什么是 Kubernetes(K8s)?

Kubernetes,简称 K8s,是用 8 代替名字中间的 8 个字母 "ubernete" 而成的缩写(K + 8 个字母 + s)。它是一个开源的、用于管理云平台中多个主机上的容器化应用的容器编排系统,目标是让部署容器化的应用简单并且高效。

K8s 和 Docker 的关系 :

Kubernetes 本身不直接运行容器,它通过容器运行时(Container Runtime) 来运行。早期 K8s 默认使用 Docker,但从 K8s 1.24 开始,Docker 被移除,改用 containerd 或 CRI-O。所以现在的分工是:

  • Docker:负责"打包"镜像(把应用和依赖装进集装箱)。

  • Kubernetes:负责"编排"容器(决定集装箱装到哪艘船、哪个位置、什么时候出发)。

生活类比 :

可以理解为一个货船 + 港口调度系统:

  • Docker 是集装箱(打包应用和依赖)。

  • Kubernetes 是货船和调度中心(负责把集装箱合理地组织、搬运、调度)。

  • K8s 的核心能力包括:自动部署、自动扩缩容、自动修复、服务发现、负载均衡、滚动更新等。它让"搬货"这件事从"人工手动搬"变成"自动化调度"。


2.评价指标(Metric)

(1)可⽤性(Availability)

考察单位时间段内,系统可以正常提供服务的概率/期望。例如: 年化系统可⽤性 = 系统正常提供服务时⻓ / ⼀年总时⻓。这⾥暗含着⼀个指标,即如何评价系统提供⽆法是否正常,我们就不深⼊了。平时我们常说的 4 个 9 即系统可以提供 99.99% 的可⽤性,5 个 9 是 99.999% 的可⽤性,以此类推。我们平时只是⽤⾼可⽤(High Availability HA)这个⾮量化⽬标简要表达我们系统的追求。

可用性是一个系统的第一要务。


(2)响应时长(Response Time RT)

指⽤⼾完成输⼊到系统给出⽤⼾反应的时⻓(响应时长用来衡量服务器的性能)。例如点外卖业务的响应时⻓ = 拿到外卖的时刻 - 完成点单的时刻。通常我们需要衡量的是最⻓响应时⻓、平均响应时⻓和中位数响应时⻓。这个指标原则上是越⼩越好,但很多情况下由于实现的限制,需要根据实际情况具体判断


(3)吞吐(Throughput)VS 并发(Concurrent)

吞吐考察单位时间段内,系统可以成功处理的请求的数量。并发指系统同⼀时刻⽀持的请求最⾼量。例如⼀条辆⻋道⾼速公路,⼀分钟可以通过 20 辆⻋,则并发是 2,⼀分钟的吞吐量是 20。实践中,并发量往往⽆法直接获取,很多时候都是⽤极短的时间段(⽐如 1 秒)的吞吐量做代替。我们平时⽤⾼并发(Hight Concurrnet)这个⾮量化⽬标简要表达系统的追求。


三.架构演进

1.单机架构(应用服务程序 + 数据库服务器共用一台服务器)

1. 简介

  • 定义:应用服务和数据库服务共用一台服务器。

  • 本质:所有功能(Web 应用、数据库、缓存、文件存储)全部部署在同一台物理机或虚拟机上。

2. 出现原因

  • 背景:出现在互联网早期。

  • 条件:访问量比较小,单机足以满足需求。

  • 目的:快速上线,验证业务模式(MVP),降低初期成本。

3. 架构工作原理(以电子商城为例)

  • 应用层:划分了多个模块(用户、商品、订单),运行在同一个进程或容器中。

  • 数据层:数据库(MySQL)和缓存(Redis)也运行在同一台机器上。

  • 协作方式:用户请求发给应用,应用直接读写本机的数据库和缓存,所有操作都在同一台机器的 CPU 和内存中完成。

4. 技术案例:如下图

5. 架构优缺点

  • 优点:

    • 部署简单:打一个包,扔上去运行即可,无需考虑分布式事务、网络延迟、服务发现等复杂问题。

    • 成本低:只需要一台服务器,不需要负载均衡器、不需要多台机器。

  • 缺点:

    • 存在严重的性能瓶颈:单台服务器的 CPU、内存、磁盘 I/O、网络带宽都有物理上限,一旦流量爆发,整台机器直接崩溃。

    • 数据库和应用互相竞争资源:应用代码吃 CPU 和内存,数据库也吃 CPU、内存和磁盘 I/O。当应用跑满 CPU 时,数据库查询就会变慢;当数据库做大量磁盘写入时,应用响应就会卡顿。两者互相拖累,导致整体性能急剧下降。

初期,我们需要利⽤我们精⼲的技术团队,快速将业务系统投⼊市场进⾏检验,并且可以迅速响

应变化要求。但好在前期⽤⼾访问量很少,没有对我们的性能、安全等提出很⾼的要求,⽽且系统架构简单,⽆需专业的运维团队,所以选择单机架构是合适的。


相关软件

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

2.应用数据分离架构(应用服务程序和数据库服务器分别放到不同的主机上进行部署)

1. 简介

  • 定义:应用服务和数据库服务使用不同服务器。

  • 本质:将应用层(Web 服务)和数据层(数据库、缓存)部署在独立的物理机或虚拟机上,通过网络进行通信。

2. 出现原因

  • 背景:单机架构存在严重的资源竞争,导致站点变慢。

  • 条件:业务增长,并发量上升,单机无法同时满足应用和数据库的资源需求。

  • 目的:隔离应用和数据库,避免互相拖累,提升整体性能。

3. 架构工作原理(以电子商城为例)

  • 应用层 :划分了多个模块(用户、商品、订单),部署在应用服务器上。

  • 数据层 :数据库(MySQL)和缓存(Redis)部署在数据库服务器上。

  • 协作方式:应用服务器通过网络(如 TCP/IP)向数据库服务器发送 SQL 查询或缓存请求,数据库服务器处理后返回结果。两者各自拥有独立的 CPU、内存和磁盘资源,互不干扰。

**4. 技术案例:**如下图

5. 架构优缺点

  • 优点:

    • 成本相对可控:只需要两台服务器,比单机架构多一台,但远低于集群架构的成本。

    • 性能相比单机有提升:应用和数据库各自拥有独立资源,不再互相竞争 CPU、内存和磁盘 I/O,整体响应速度显著提升。

    • 数据库单独隔离,不会因为应用把数据库搞坏,有一定的容灾能力:应用崩溃或重启不会影响数据库运行;数据库故障也不会直接导致应用进程挂掉。

  • 缺点:

    • 硬件成本变高:需要至少两台服务器,增加了采购和维护成本。

    • 性能有瓶颈,无法应对海量并发:虽然比单机好,但每层仍然是单点。当并发量进一步增长时,应用服务器或数据库服务器仍会成为瓶颈,无法支撑海量请求。

一台主机的硬件资源是有上限的,包括但不限于以下几种:

  • CPU:计算能力的上限。

  • 内存:数据缓存和进程运行空间的上限。

  • 硬盘:存储容量和磁盘 I/O 带宽的上限。

  • 网络:带宽和网络连接数的上限。

  • 文件描述符:每个连接和打开文件都占用一个 fd,Linux 默认单进程上限通常为 1024。

  • 端口号:一台机器最多只有 65535 个端口。

服务器每收到一个请求,都是需要消耗上述的一些资源的。如果同一时刻处理的请求多了,此时就可能导致某个硬件资源不够用了。

无论是哪个方面的资源不够用,都可能导致服务器处理请求的时间变长,甚至于处理出错:

  • CPU 瓶颈:请求排队等待 CPU 时间片,响应时间线性增长。

  • 内存瓶颈:触发 Swap,磁盘 I/O 暴增,性能断崖式下跌;严重时 OOM Killer 会杀掉进程。

  • 磁盘瓶颈:读写队列堆积,数据库查询变慢,甚至超时。

  • 网络瓶颈:TCP 连接队列溢出,新连接被拒绝;或者带宽跑满,数据传输延迟飙升。

  • 文件描述符瓶颈 :新连接无法建立,报错 Too many open files。

  • 端口瓶颈:作为客户端发起连接时,本地端口耗尽,无法建立新连接。

如果真的遇到了这样的服务器不够用的场景,应该如何处理呢?

  1. 开源(简单粗暴,增加更多的硬件资源。一个主机上面能增加的硬件资源也是有限的,这取决于主板的扩展能力)
  2. 节流(软件上进行优化,需要通过性能测试来找出是哪个环节出现了瓶颈,再去对症下药)

随着系统的上线,我们不出意外地获得了成功。市场上出现了一批忠实于我们的用户,使得系统的访问量逐步上升,逐渐逼近了硬件资源的极限,同时团队也在此期间积累了对业务流程的一批经验。面对当前的性能压力,我们需要未雨绸缪去进行系统重构、架构挑战,以提升系统的承载能力。但由于预算仍然很紧张,我们选择了将应用和数据分离的做法,可以最小代价的提升系统的承载能力。

和之前架构的主要区别在于将数据库服务独⽴部署在同⼀个数据中⼼的其他服务器上,应⽤服务通过⽹络访问数据。


3.应用服务集群架构(负载均衡,应用服务器 --->集群)

1.简介

  • 定义:引入了负载均衡,应用以集群方式运作。

  • 本质:将单台应用服务器扩展为多台,通过负载均衡器(如 Nginx、LVS)将请求分发到不同的应用节点上。

2. 出现原因

  • 背景:单个应用不足以支持海量的并发请求,高并发的时候站点响应变慢。

  • 条件:业务继续增长,应用层成为瓶颈。

  • 目的:通过横向扩展应用节点,提升整体吞吐量和可用性。

3. 架构工作原理(以电子商城为例)

  • 应用层:应用不再是一个,而是变成了多个,部署在多台服务器上。

  • 负载均衡:通过负载均衡器(如 Nginx)将海量并发请求分发到不同的应用节点上。

  • 协作方式:每个应用节点处理一部分请求,共同支撑海量并发。数据库层暂时保持不变(仍是单点)。

4. 技术案例:如下图

5. 架构优缺点

  • 优点:

    • 应用服务高可用:应用满足高可用,不会一个服务出问题整个站点挂掉。负载均衡器可以自动剔除故障节点,将请求转发到健康节点。

    • 应用服务具备一定高性能:如果不访问数据库,应用相关处理通过扩展可以支持海量请求快速响应。多台应用节点并行处理,吞吐量成倍提升。

    • 应用服务有一定扩展能力:支持横向扩展。业务增长时,只需增加应用节点即可。

  • 缺点:

    • 数据库成为性能瓶颈:无法应对数据库的海量查询。应用层扩展了,但数据库仍是单点,所有请求最终都要落到同一个数据库上,数据库压力剧增。

    • 数据库是单点,没有高可用:一旦数据库宕机,整个系统不可用。

    • 运维工作增多:扩展后部署运维工作增多,需要开发对应的工具应对快速部署。多台服务器的配置管理、日志收集、监控告警等都需要自动化工具支撑。

    • 硬件成本较高:需要多台应用服务器 + 负载均衡器,硬件成本比单机架构和应用数据分离架构都高。

Redis的系统受到了用户的欢迎,并且出现了爆款,单台应用服务器已经无法满足需求了。Redis的单机应用服务器首先遇到了瓶颈,摆在Redis技术团队面前的有两种方案,Redis团队针对方案的优劣展示了热烈的讨论:

  • 垂直扩展 / 纵向扩展 Scale Up。通过购买性能更优、价格更高的应用服务器来应对更多的流量。这种方案的优势在于完全不需要对系统软件做任何的调整;但劣势也很明显:硬件性能和价格的增长关系是非线性的,意味着选择性能 2 倍的硬件可能需要花费超过 4 倍的价格,其次硬件性能提升是有明显上限的。
  • 水平扩展 / 横向扩展 Scale Out。通过调整软件架构,增加应用层硬件,将用户流量分担到不同的应用层服务器上,来提升系统的承载能力。这种方案的优势在于成本相对较低,并且提升的上限空间也很大。但劣势是带给系统更多的复杂性,需要技术团队有更丰富的经验。

经过Redis团队的学习、调研和讨论,最终选择了水平扩展的方案,来解决该问题,但这需要引入一个新的组件 ------ 负载均衡:为了解决用户流量向哪台应用服务器分发的问题,需要一个专门的系统组件做流量分发。实际中负载均衡不仅仅指的是工作在应用层的,甚⾄可能是其他的网络层之中。同时流量调度算法也有很多种,这里简单介绍几种较为常见的:

  1. Round-Robin 轮询算法。即非常公平地将请求依次分给不同的应用服务器。
  2. Weight-Round-Robin 轮询算法。为不同的服务器(比如性能不同)赋予不同的权重(weight),能者多劳。
  3. 一致哈希散列算法。通过计算用户的特征值(比如 IP 地址)得到哈希值,根据哈希结果做分发,优点是确保来自相同用户的请求总是被分给指定的服务器。也就是我们平时遇到的专项客户经理服务。
  • 应用服务器,里面可能会包含很多的业务逻辑,可能会吃 CPU 和内存。
  • 数据库服务器,需要更大的硬盘空间,更快的数据访问速度。可以配置更大硬盘的服务器,甚至可以选择 SSD 硬盘(固态硬盘,价格高、访问速度快)。

我们可以类比:

  • 负载均衡器,是领导,分配工作。
  • 应用服务器,是组员,执行任务。

通过负载均衡器,把请求比较均匀的分发给集群中的每个应用服务器。

当集群中的某个主机挂了,其他的主机仍然可以承担服务,这就提高了整个系统的可用性。


相关软件

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


4.读写分离 / 主从分离架构(数据库主从结构)

  • **1.简介:**将数据库读写操作分散到不同的节点上,数据库服务器搭建主从集群,一主一从、一主多从都可以,数据库主机负责写操作,从机只负责读操作。
  • **2.出现原因:**数据库成为瓶颈,而互联网应用一般读多写少,数据库承载压力大,主要是由这些读的请求造成的,那么我们可以把读操作和写操作分开。
  • **3.架构工作原理:**以电子商城为例,可以看到数据库服务器不再是一个,而是变成了多个,数据库主机负责写操作,从机负责读操作,数据库主机通过复制将数据同步到从机。
  • 4.技术案例
  • 5.架构优缺点
    • 优点
      • 数据库的读取性能提升
      • 读取被其他服务器分担,写的性能间接提升
      • 数据库有从库,数据库的可用性提高了
    • 缺点
      • 热点数据的频繁读取导致数据库负载很高
      • 当同步挂掉,或者同步延迟比较大时,写库和读库的数据不一致
      • 服务器成本需要进一步增加

上面提到,我们把⽤⼾的请求通过负载均衡分发到不同的应⽤服务器之后,可以并⾏处理了,

并且可以随着业务的增⻓,可以动态扩张服务器的数量来缓解压⼒。但是现在的架构⾥,⽆论扩展多少台服务器,这些请求最终都会从数据库读写数据,到⼀定程度之后,数据的压⼒称为系统承载能⼒的瓶颈点。我们可以像扩展应⽤服务器⼀样扩展数据库服务器么?答案是否定的,因为数据库服务有其特殊性:如果将数据分散到各台服务器之后,数据的⼀致性将⽆法得到保障。所谓数据的⼀致性,此处是指:针对同⼀个系统,⽆论何时何地,我们都应该看到⼀个始终维持统⼀的数据。想象⼀下,银⾏管理的账⼾⾦额,如果收到⼀笔转账之后,⼀份数据库的数据修改了,但另外的数据库没有修改,则⽤⼾得到的存款⾦额将是错误的。

我们采⽤的解决办法是这样的,保留⼀个主要的数据库作为写⼊数据库,其他的数据库作为从属

数据库。从库的所有数据全部来⾃主库的数据,经过同步后,从库可以维护着与主库⼀致的数据。然后为了分担数据库的压⼒,我们可以将写数据请求全部交给主库处理,但读请求分散到各个从库中。由于⼤部分的系统中,读写请求都是不成⽐例的,例如 100 次读 1 次写,所以只要将读请求由各个从库分担之后,数据库的压⼒就没有那么⼤了。当然这个过程不是⽆代价的,主库到从库的数据同步其实是由时间成本的,但这个问题我们暂时不做进⼀步探讨。

在真实业务场景中,数据库读请求频率远高于写请求。 架构采用一主多从模式:部署 1 台主数据库服务器,N 台从数据库服务器,并通过数据库负载均衡供应用服务器访问。

  • 主节点:负责处理写数据请求
  • 从节点:负责处理读数据请求 主节点会将变更的数据同步到所有从节点。

为了在应用层实现读写请求自动区分,可引入数据库中间件(MyCat、TDDL 等),把读写请求分发的工作交给中间件托管。

相关软件

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


5.引入缓存 ------ 冷热分离架构(进一步的提升了服务器针对请求的处理能力 ------ "二八原则")

1. 简介

  • 定义:引入缓存,实行冷热分离,将热点数据放到缓存中快速响应。

  • 本质:在应用和数据库之间增加一层缓存(通常是 Redis),把高频访问的"热数据"放在内存中,低频访问的"冷数据"留在数据库里。

2. 出现原因

  • 背景:海量的请求导致数据库负载过高,站点响应再度变慢。

  • 条件:读写分离后,数据库仍然扛不住高并发读请求。

  • 目的:通过内存缓存分担绝大部分读请求,降低数据库压力,提升响应速度。

3. 架构工作原理(以电子商城为例)

  • 缓存层:多了缓存服务器(如 Redis)。

  • 读流程:对于热点数据(如商品详情、首页推荐),全部放到缓存中。应用先查缓存,命中则直接返回;未命中再查数据库,并回写缓存。

  • 写流程:更新数据库后,删除或更新缓存(保证最终一致性)。

  • 冷热分离:不常用的数据再去查询数据库,常用数据常驻内存。

4. 技术案例:如下图

5. 架构优缺点

  • 优点:

    • 大幅降低对数据库的访问请求,性能提升非常明显:缓存命中率通常在 90% 以上,数据库只需处理少量未命中请求。
  • 缺点:

    • 带来了缓存一致性、缓存击穿、缓存失效、缓存雪崩等问题:需要额外处理缓存与数据库的数据同步,以及各种缓存异常场景。

    • 服务器成本需要进一步增加:需要部署和维护 Redis 集群,增加了硬件和运维成本。

    • 业务体量支持变大后,数据不断增加,数据库单库太大,单个表体量也太大,数据查询会很慢,导致数据库再度成为系统瓶颈:缓存解决了读性能问题,但没有解决数据量增长带来的存储和查询瓶颈。

随着访问量继续增加,发现业务中一些数据的读取频率远大于其他数据的读取频率。我们把这部分数据称为热点数据,与之相对应的是冷数据。针对热数据,为了提升其读取的响应时间,可以增加本地缓存,并在外部增加分布式缓存,缓存热门商品信息或热门商品的 html 页面等。通过缓存能把绝大多数请求在读写数据库前拦截掉,大大降低数据库压力。其中涉及的技术包括:使用 memcached 作为本地缓存,使用 Redis 作为分布式缓存,还会涉及缓存一致性、缓存穿透 / 击穿、缓存雪崩、热点数据集中失效等问题。

这里的数据库有个天然的问题 ------ 响应速度慢 。把数据分为**"热数据" 和 "冷数据"**,"热数据" 放到缓存中,缓存的访问速度比数据库要快得多。

Redis 在一个分布式系统中,通常扮演者缓存这样的角色。缓存服务器帮助数据库服务器 "负重前行"。引入缓存的问题:数据库和缓存的数据一致性问题。


相关软件

Memcached、Redis 等缓存软件


6.垂直分库(数据库能够进一步扩展存储空间)

1. 简介

  • 定义:数据库的数据被拆分,数据库数据分布式存储,分布式处理,分布式查询,也可以理解为分布式数据库架构。

  • 本质:将原本集中在一个数据库中的数据,按照一定规则拆分到多个数据库或多个表中,分散存储和查询压力。

2. 出现原因

  • 背景:单机的写库会逐渐达到性能瓶颈,需要拆分数据库。数据表的数据量太大,处理压力太大,需要进行分表。

  • 条件:缓存虽然解决了读性能,但写性能和单表数据量瓶颈仍然存在。

  • 目的:为降低运维难度,业界逐渐研发了分布式数据库,库表天然支持分布式,从根本上解决单机存储和性能瓶颈。

3. 架构工作原理(以电子商城为例)

  • 架构形态:数据库是由多个主从库或者存储集群构成。

  • 处理方式:支持分布式大规模并行处理,请求被路由到不同的数据库节点上,各自处理一部分数据。

  • 拆分维度:

    • 垂直拆分:按业务拆分(如用户库、商品库、订单库)。

    • 水平拆分:按数据行拆分(如订单表按用户 ID 取模拆成 100 张表)。

4. 技术案例:如下图

5. 架构优缺点

  • 优点:

    • 数据库吞吐量大幅提升,不再是瓶颈:数据分散到多个节点,写性能和存储容量都可以横向扩展。
  • 缺点:

    • 跨库 join、分布式事务等问题,这些需要对应的去进行解决,目前的 MPP 都有对应的解决方案:拆分后,原本简单的联表查询和事务变得复杂,需要中间件或数据库自身支持分布式事务(如 Seata、XA)。

    • 数据库和缓存结合目前能够抗住海量的请求,但是应用的代码整体耦合在一起,修改一行代码需要整体重新发布:这是单机应用架构的遗留问题------所有业务逻辑都在一个应用里,无法独立部署和扩展。

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


相关软件

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


7.业务拆分 ------ 微服务(从业务上进一步拆分应用服务器)

1. 简介

  • 定义:微服务是一种架构风格,按照业务板块来划分应用代码,使单个应用的职责更清晰,相互之间可以做到独立升级迭代。

  • 本质:将原本"大一统"的单体应用,拆分为一组小型、独立、松耦合的服务,每个服务围绕具体业务能力构建。

2. 出现原因(单体应用的痛点)

  • 扩展性差:应用程序无法轻松扩展,因为每次需要更新应用程序时,都必须重新构建整个系统。

  • 持续开发困难:一个很小的代码改动,也需要重新部署整个应用,无法频繁并轻松地发布版本。

  • 不可靠:即使系统的一个功能不起作用,可能导致整个系统无法工作。

  • 不灵活:无法使用不同的技术构建单体应用程序。

  • 代码维护难:所有功能耦合在一起,新人不知道何从下手。

3. 架构工作原理(以电子商城为例)

  • 拆分方式:一个商城应用拆分成了多个微服务,如用户服务、交易服务和商品服务。

  • 协作方式:各个服务相互之间协作,共同支持整个商城的应用。每个服务可以独立部署、独立扩展、独立升级。

4. 技术案例

5. 架构优缺点

  • 优点:

    • 灵活性高:服务独立测试、部署、升级、发布。

    • 独立扩展:每个服务可以各自进行扩展。

    • 提高容错性:一个服务问题并不会让整个系统瘫痪。

    • 新技术的应用容易:支持多种编程语言。

  • 缺点:

    • 运维复杂度高:业务不断发展,应用和服务都会不断变多,应用和服务的部署变得复杂,同一台服务器上部署多个服务还要解决运行环境冲突的问题。此外,对于如大促这类需要动态扩缩容的场景,需要水平扩展服务的性能,就需要在新增的服务上准备运行环境、部署服务等,运维将变得十分困难。

    • 资源使用变多:所有这些独立运行的微服务都需要占用内存和 CPU。

    • 处理故障困难:一个请求跨多个服务调用,需要查看不同服务的日志完成问题定位。

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

随着业务发展,前面的应用服务器在同一个服务程序中承载大量业务逻辑,代码会愈发臃肿复杂。 为降低维护成本,可以将单体应用拆分为多个职责单一、体量更小的独立服务,也就是微服务,服务的种类与数量随之增加。

重点**:微服务本质是解决团队协作(人) 的问题**。 单体应用代码庞大之后,需要更多开发人员共同维护。人员变多,就需要划分组织结构、分组分工,每组配备对应的负责人。 对应到系统架构:按业务功能维度,把单体应用拆分成多个功能单一、逻辑简单的独立微服务。

从业务功能的角度来看,把应用服务器拆分成更多的功能更单一、更简单、更小的服务器。

相关软件

Spring Cloud、Dubbo


引入微服务带来的代价(缺点)

  1. 系统性能下降。想要尽可能抵消性能损耗,需要新增更多服务器与硬件资源,增加资金成本。
  2. 系统整体复杂度大幅上升,可用性风险增加。服务实例变多,故障发生概率随之提高;需要配套完善的监控、报警体系,同时增加运维人力保障系统稳定。

微服务的优势

  1. 解决团队协作("人")的问题,方便多人、多团队并行开发维护。
  2. 便于业务功能复用。
  3. 不同服务可以独立部署、独立扩容。

8.容器化引入 ------ 容器编排架构

1. 简介

  • 定义:借助容器化技术(如 Docker)将应用/服务打包为镜像,通过容器编排工具(如 K8s)来动态分发和部署镜像,服务以容器化方式运行。

  • 本质:将微服务架构中的每个服务打包成容器,由编排工具统一管理其生命周期。

2. 出现原因(微服务架构的运维痛点)

  • 部署工作量大:微服务拆分细,服务多部署工作量大,而且配置复杂,容易出错。

  • 扩缩容麻烦:微服务数量多,扩缩容麻烦,而且容易出错,每次缩容后再扩容又需要重新配置服务对应的环境参数信息。

  • 环境冲突:微服务之间运行环境可能冲突,需要更多的资源来进行部署,或者通过修改配置来解决冲突。

3. 架构工作原理(以电子商城为例)

  • 拆分与打包:一个商城应用拆分成了多个微服务,如用户服务、交易服务和商品服务,每一个微服务打包到容器之中。

  • 协作方式:容器之间相互协作来完成系统功能,通过容器编排工具完成部署运维。

4. 技术案例:如下图

5. 架构优缺点

  • 优点:

    • 部署、运维简单快速:一条命令就可以完成几百个服务的部署或者扩缩容。

    • 隔离性好:容器与容器之间文件系统、网络等互相隔离,不会产生环境冲突。

    • 轻松支持滚动更新:版本间切换都可以通过一个命令完成升级或者回滚。

  • 缺点:

    • 技术栈变多,对研发团队要求高:需要掌握 Docker、K8s、Helm 等一系列工具,学习曲线陡峭。

    • 机器成本与运维成本高:机器还是需要公司自身来管理,在非大促的时候,还是需要闲置着大量的机器资源来应对大促,机器自身成本和运维成本都极高,资源利用率低(可以通过购买云厂商服务器解决)。

随着业务增长,然后发现系统的资源利用率不高,很多资源用来应对短时高并发,平时又闲置,需要动态扩缩容,还没有办法直接下线服务器,而且开发、测试、生产每套环境都要隔离的环境,运维的工作量变的非常大。容器化技术的出现给这些问题的解决带来了新的思路。

目前最流行的容器化技术是 Docker,最流行的容器管理服务是 Kubernetes(K8S),应用 / 服务可以打包为 Docker 镜像,通过 K8S 来动态分发和部署镜像。Docker 镜像可理解为一个能运行你的应用/服务的最小的操作系统,里面放着应用 / 服务的运行代码,运行环境根据实际的需要设置好。把整个 "操作系统" 打包为一个镜像后,就可以分发到需要部署相关服务的机器上,直接启动 Docker 镜像就可以把服务起起来,使服务的部署和运维变得简单。服务通常会有生产和研发 k8s 集群,一般不会公用,而研发集群通过命名空间来完成应用隔离,有的公司按照研发目的划分为研发和测试集群,有的公司通过组织架构完成部门间的资源复用。


相关软件

Docker、K8S


9.一个互联网应用架构


四.结尾

⾄此,⼀个还算合理的⾼可⽤、⾼并发系统的基本雏形已显。注意,以上所说的架构演变顺序只

是针对某个侧⾯进⾏单独的改进,在实际场景中,可能同⼀时间会有⼏个问题需要解决,或者可能先达到瓶颈的是另外的⽅⾯,这时候就应该按照实际问题实际解决。如在政府类的并发量可能不⼤,但业务可能很丰富的场景,⾼并发就不是重点解决的问题,此时优先需要的可能会是丰富需求的解决⽅案。

对于单次实施并且性能指标明确的系统,架构设计到能够⽀持系统的性能指标要求就⾜够了,但要留有扩展架构的接⼝以便不备之需。对于不断发展的系统,如电商平台,应设计到能满⾜下⼀阶段⽤⼾量和性能指标要求的程度,并根据业务的增⻓不断的迭代升级架构,以⽀持更⾼的并发和更丰富的业务。

所谓的"⼤数据"其实是海量数据采集清洗转换、数据存储、数据分析、数据服务等场景解决⽅

案的⼀个统称,在每⼀个场景都包含了多种可选的技术,如数据采集有Flume、Sqoop、Kettle等,数据存储有分布式⽂件系统HDFS、FastDFS,NoSQL数据库HBase、MongoDB等,数据分析有Spark技术栈、机器学习算法等。总的来说⼤数据架构就是根据业务的需求,整合各种⼤数据组件组合⽽成的架构,⼀般会提供分布式存储、分布式计算、多维分析、数据仓库、机器学习算法等能⼒。⽽服务端架构更多指的是应⽤组织层⾯的架构,底层能⼒往往是由⼤数据架构来提供

业务是更重要的,技术只是给业务提供支持的。

所谓的分布式系统,就是想办法引入更多的硬件资源。


五.问题补充

1.如何决策要不要演进?

不是说我们的架构越大就越好,要结合实际业务场景,考虑成本、团队,再来决定是否要引进,满足业务需求即可。

具体的决策维度包括:

  • 业务规模:日活、QPS、数据量。

  • 团队能力:是否有 DevOps 经验,是否有人懂 K8s。

  • 成本预算:机器成本、运维成本、人力成本。

  • 演进节奏:逐步演进,每一步都要验证收益是否大于成本。


2.架构必须这么演进吗?

当然不是。例如,从微服务架构开始,至于要不要引入 Docker、K8s,要看团队技术栈的储备,如果贸然引进,出现问题就很麻烦。

架构演进是问题驱动 的,而不是技术驱动的。只有当现有架构真的扛不住了,才考虑演进。


3.架构必须是这么几个吗?

不是,可以将上述架构再进行拆分。

架构演进路线不是"标准答案",而是"参考模板"。实际场景中,很多架构是混合的。关键是理解每种架构解决的问题和代价,然后根据实际情况组合使用。


4.Docker 的核心作用是什么?

完成了核心的打包,进行容器化的运行。

更精确地说,Docker 的核心作用有三点:

  1. 打包:把应用和依赖打包成镜像,解决环境一致性问题。

  2. 隔离:容器之间文件系统、网络、进程空间互相隔离。

  3. 可移植:镜像可以在任何支持 Docker 的机器上运行。

Docker 是容器化的基石 ,K8s 是容器编排的大脑 。

相关推荐
Flynt1 小时前
把 bug tracker 塞进 git 仓库,同步和冲突怎么解决?我把 git-bug 拆开实测了一遍
分布式·git·开源
灯澜忆梦18 小时前
【RabbitMQ #3】 | Go 客户端 + SpringAMQP
分布式·golang·rabbitmq
Q26433650231 天前
【有源码】基于Spark的电商客户细分与盈利洞察分析系统-面向精准营销的电商客户细分模型构建与盈利能力可视化研究
大数据·hadoop·分布式·数据挖掘·数据分析·spark·毕业设计
新思维软件1 天前
基于无线传输的地衡系统:三节点 LoRa 组网与 MQTT 上云的分布式称重方案
分布式·stm32·单片机·嵌入式硬件·物联网·物联网开发
俊哥大数据1 天前
Flink1.20.3 实时消费 Kafka 数据并解析入湖 Paimon1.4.2 全流程实战
分布式·flink·kafka·数据湖·paimon
宸津-代码粉碎机1 天前
OpenAI 连夜迎战 Grok Bot 和 Muse:AI 智能体从 “会聊天” 到 “能办事”,现在入场还来得及吗
java·大数据·人工智能·分布式·python
程序猿乐锅1 天前
【黑马点评 | 第八篇】Redisson分布式锁
java·数据库·spring boot·redis·分布式·spring·缓存
灯澜忆梦1 天前
【RabbitMQ #7】 | 消息转换器
分布式·rabbitmq·ruby
需要8261 天前
分布式事务:Seata AT/TCC/SAGA 的取舍与踩坑
java·spring boot·分布式·spring·spring cloud