高并发的哲学原理(三)-- 基础设施并发:虚拟机与 Kubernetes(k8s)

news2024/12/23 15:37:24

上篇文章说到,Apache 无法处理海量用户的 TCP 连接,那要是由于宇宙时空所限,你的系统就是无法离开 Apache,该怎么承接高并发呢?有办法:既然单机不行,那就把单机虚拟化成多个 Linux 机器,就能顶得住高并发了。

Apache 成为了单点,那就把它拆了

基于虚拟化做多节点集群,可以相对线性地提升系统性能,你只要在前面搭建一个负载均衡即可。

一个负载均衡服务器 + 多个上游服务器的技术架构正是“找出单点,进行拆分”思想的具体体现。如果 Apache 顶不住,那我们就仔细思考一下,Apache 架构中,到底哪个单点是不好拆的,哪些部分是可以并行的?

监听 443 端口的进程(root 用户)是单点

显然,监听 HTTPS 443 端口的进程就是肉眼可见的单点,而执行 PHP 的进程在一台服务器上本身就是并行的。

(其实监听单点也能拆,只是我们在这一步还不需要拆,后面会拆。)

跑 PHP 的进程(apache 用户)可以并行

在单机上,PHP 解释器进程本身就是并行的,那我们把它拆到多台机器上,就是顺理成章的事情。

百亿架构

下面是我为自研电商设计的可伸缩技术架构: alt

经过一年多的运行,我发现它撑到年 GMV 100 亿问题不大,以今年十多亿的 GMV 为例,目前 2 核 4G Kong 网关虚拟机的 CPU 占用最大只到了 20%,那 8 核 Kong 网关应该就能顶住 100 亿的冲击了。

这套架构的核心是两个东西:Kong 网关和服务发现。

Kong 网关

虚拟机技术无法单独提升系统容量,因为必须有东西来承接“监听 443 端口”这个单点,在这里我选择了 Kong 网关作为 HTTP 反向代理服务器,将用户的海量 HTTPS 请求 handle 住,再以 HTTP 协议发送到后端的多台 2 核 4G 虚拟机上。

Kong 是基于 国产 OpenResty 技术 开发的开源网关,OpenResty 将非常轻量、高效的 Lua 语言嵌入进了 Nginx 生命周期,大幅扩展了 Nginx 的功能。Kong 除了拥有 HTTP 网关的一整套功能外,还有插件系统和基于数据库的水平扩展能力,理论上可以支撑超高并发的系统。这部分具体的内容我们会在后面《百万人民币的负载均衡硬件以及它的软件替代方案》里面做详细的讨论。

服务发现

在流量低谷期我们使用一台虚拟机跑 Apache 作为上游服务器,在开团前需要再开出来一台上游服务器的话,Kong 该怎么知道这台服务器开出来了,并且获取到他们的 ip 呢?答案是使用服务发现技术。

像 Kong 一样,HashiCorp 开源的 consul 也可以独立于 k8s 环境运行,于是我选择了它来做服务发现。服务发现的原理说起来其实非常简单:构造一个共识集群,各个节点之间会使用固定的端口相互通信,当新的上游服务器开机后,它上面的 consul 服务会开机启动,之后就会和配置好的一个 master 的 ip 进行通信,加入这个集群,并广播本机可以提供的服务名称,假设名叫up。这时,同样在集群内的 Kong 网关服务器就可以通过它本机上安装的 consul 提供的 DNS 服务拿到新加入集群的这台机器的 ip 了。

Kong 向 consul DNS 发送一个查询:查找up.service.consul这个域名对应的 ip,之前,这个域名只会返回一个 ip,在新机器开机并成功加入集群后,这个域名对应的就是两个 ip 了,Kong 就可以把 HTTP 请求均匀地发送给新旧两台上游服务器了。

好了,基础架构准备就绪,下面我们深入一下本文的主题:基础设施并发。

何为基础设施并发

虚拟机是第一代基础设施并发技术:既然由于软件架构的限制导致单机性能有上限,那我就把多核服务器拆成多机。因为现在服务器核心数越做越多,除了 web 服务,周边的 MySQL、Redis、ElasticSearch 等也需要计算资源,将多核服务器虚拟化,除了可以提升系统性能,还能减少资源浪费,换个词就是:省钱。在今天整个行业都在降本增效的大背景下,省钱无疑是技术潮头。

而 k8s 容器编排技术是最新一代基础设施并发技术:可以把它看成一种更优秀且更容易进行自动化管理的虚拟机技术。

虚拟化技术的价值

不知道屏幕前的读者有没有想过,在一台裸金属服务器的操作系统内直接运行 Apache、MySQL、Redis、ElasticSearch,和开四台虚拟机分别运行他们,到底有什么区别。系统设计哲学不是“如无必要勿增实体”吗?虚拟机技术到底有什么价值来让我们新增四个实体呢?

1. 资源隔离

后端技术拥有很多成熟的开源软件,每个软件都拥有独特的发展路径,百花齐放,群魔乱舞。如果把所有服务都装在裸金属服务器上,理论上讲使用内存管道通信的效率比虚拟机之间通过虚拟以太网通信还要更高,但是资源隔离就难做了。

拥有自我资源限制能力的软件不多,大部分软件都是“有多大屁股穿多大裤衩”:根据请求压力任意获取计算资源,这就让计算资源的分配容易出现问题,产生木桶效应,最终导致系统整体性能反而更低。

虚拟化技术通过将虚拟机和物理核心进行强绑定,可以无限接近 “将一台 64 核服务器拆成 32 台 2 核服务器” 的目标,内存也可以进行完全预分配,虚拟机之间的相互干扰可以做到最低。

2. 降低运维复杂度

市面上成熟的监控软件都是基于操作系统的,进程也能监控,但是比较困难。控制虚拟机也比控制进程要更加容易。当然,控制 k8s 容器平台更加灵活高效,我们下面会讲到。

虚拟机显著降低了对每个重要服务进行资源监测的复杂度,大幅提升了运维效率,甚至实现了第一代的“自动运维”,时至今日,VMWare 在超融合领域也拥有统治地位:基于三台服务器的小集群,就可以提供高可用架构的全套基础设置:统一应用网关、共享存储、虚拟机热漂移、自动故障转移等。如果只用一台物理服务器直接安装 Linux,很显然这些高可用特性都做不到,一旦这台物理机的某个部件发生了故障导致宕机的话,全部服务都会挂掉。

3. 隐藏价值:性能氮泵

由于很多软件都拥有 Apache 一样的“单机性能极限”,所以虚拟化技术将单机拆成多机,就可以直接实现性能增益。如果你把 Apache、Redis、MySQL、ElasticSearch 都装在裸金属操作系统上的话,他们就会异口同声说:给我那么多核心有什么用,我真的用不上啊。

Apache 我们前文已经讲过,下面我们讨论一下其他几种技术的“单机性能极限”。

Redis 的单机性能极限

Redis 作为单线程内存数据库,两核就能做到十万 QPS,你给他 32 核,还是十万 QPS,对资源是一种浪费。

在前几天 Redis 回应新兴内存数据库 Dragonfly 挑战的文章中,Redis 维护团队建议大家搭建“单机集群”¹ 来实现对机器上所有 CPU 的完全利用,Redis 团队的内心 OS 一定是:宝宝心里苦但宝宝不说。

而且,基于虚拟化技术搭建多虚拟机上的 Redis 集群,是一种比单机集群更加稳妥的高性能 Redis 解决方案。

MySQL 的单机性能极限

在今天这个 NVME PCI-E 4.0 时代,单个闪存磁盘的读写速度已经站上了 7GB/S,MySQL 的单机 CPU 使用强度已经大大提高,但是,如果我拿最新的双路 AMD EPYC 9654 96 核服务器来跑单机 MySQL 呢?显然单节点 MySQL 无论如何是无法吃完 192 个物理核心,384 个线程的,而它的性能极限也会停在几万 QPS。

实际上,标准 MySQL 的性能瓶颈在内存容量和磁盘速度,对 CPU 资源的需求并不是很高,在两台虚拟机拥有独立固态硬盘的情况下,把 16 核虚拟机拆成两台 8 核虚拟机并打造成一个半同步一主一从的 MySQL 集群,便可以轻松将数据库的读性能提升一倍,只需要稍微牺牲一丢丢写性能。

web 系统的瓶颈在数据库,数据库的瓶颈在存储,这个话题很大,我们后面有三篇文章专门讨论数据库和存储。

ElasticSearch 的单机性能极限

ES 作为一个 Java 应用,显然拥有着明确的单机性能极限:线程切换需要读写内存,性能上限就在那里。ES 自己就采用了自选举集群架构来实现水平扩展:官方建议单节点不要超过 32GB 内存。

如果你的母机 CPU 和内存很多,就可以基于虚拟机技术做多节点 ES 集群,ES 集群的扩展能力是非常不错的:作为一个搜索引擎,大家竟然都拿他当数据库用,从这里就足以看出它优秀的水平扩展能力。

k8s 技术的本质

容器技术是谷歌给人类社会的又一个重大贡献,不仅开发了 Cgroups 并将其合并进了 Linux Kernel(2008 年),还开源了自己的容器编排工具 Kubernetes(简称 k8s,2014 年开源),而在这两件事之间,2013 年 Docker 为容器世界贡献了一个决定性的新思想:镜像技术。

镜像技术开天辟地

Docker 发明了镜像,并提出了 build、ship、run 的概念,通过将整个操作系统的文件系统打包进容器镜像,真正实现了一次构建、处处运行。而在这之前,只有拥有完整操作系统的虚拟机才能做到这一点,而 Java 则号称自己能做到。

git 一样的镜像

比容器思想更为重要的是,Docker 项目还在容器镜像的制作上引入了“层”的概念,这种基于“层”(也就是“commit” ) 进行 build,push,update 的思路,显然是借鉴了 Git 的思想。所以这个做法的好处也跟 GitHub 如出一辙:制作 Docker 镜像不再是一个枯燥而乏味的事情,因为通过 DockerHub 这样的镜像托管仓库,你和你的软件立刻就可以参与到全世界软件分发的流程当中了²。

Docker 的成功主要就是靠的 DockerHub,它将开源软件推进了一大步:开源软件可以直接分发 “下载即可用” 的标准化软件镜像,大家可以像在开源社区协作一样,在镜像社区协作,一层一层地搭建出适合自己的镜像,人类作为群居动物的本能嘎的一下就觉醒了。

软件架构本质上是软件维护团队的组织架构

稍微扯远一点,说说软件架构和运维架构。我认为,容器、镜像、容器编排的兴起,与其说是一种技术创新,不如说是一种生产关系的创新:在越来越大的服务器数量面前,以前那套基于虚拟机的管理技术不再适用了,Google 需要一种少数人管理数十万台服务器的新技术,于是 k8s 诞生了。

正如软件架构本质上是软件维护团队的组织架构,运维架构本质上也是运维团队的组织架构:规模大到必须自动化,于是容器编排便自然而然地出现了(唯物史观有木有)。

重要的不是电影拍摄(讲述)的年代,而是拍摄电影的年代。 —— 戴锦华(北京大学教授,电影评论家)

k8s 是一种更加优秀的基础设施并发技术

k8s 是人类面对暴增的物理服务器和上面数不清的虚拟机的管理难题时想出的一种解决方案,正如设计模式是面向对象编程思想对现实问题的一种妥协。

以 k8s 为代表的容器编排技术,就是一种更容易被软件自动化管理的“虚拟机”,它可以实现虚拟机一样的功能——资源隔离、降低运维复杂度和性能氮泵,而且,它还可以在裸金属环境下快速部署出一个数千台服务器的集群。虽然虚拟化技术研发出了很多像 SR-IOV 一样的硬件直通技术,但无论是物理网卡性能还是虚拟网卡性能,都不如容器技术:五年前我在一台非常老的服务器上做过超过一天的压测,docker 的内存网关又快又稳,可以实现超过万兆的带宽,并持续 24 小时一个包都不丢。

传统虚拟机镜像巨大、启动缓慢、多个操作系统同时运行带来了资源浪费、迁移缓慢、管理困难,而 k8s 镜像很小,启动迅速,资源损耗低,管理 API 丰富,更是可以轻易实现“单机多实例部署”和“目录共享”,是海量服务器新时代的优秀基础架构。

k8s 就是云时代的虚拟机 + 操作系统。

还记得我们的目标吗?一百万 QPS

通过使用负载均衡 + 虚拟机,或者负载均衡 + k8s,在依然使用前面那台双路 E5-2682 V4 64 vCore 的情况下,我们可以把单个系统的 QPS 从上篇文章的 1000 提升到 5000。

(实际上在这个 QPS 下,数据库早就成为瓶颈了,这个问题我们留到后面几篇文章再详细讨论。)

参考资料

  1. Redis 维护团队建议大家搭建“单机集群” https://redis.com/blog/redis-architecture-13-years-later/
  2. 你和你的软件立刻就可以参与到全世界软件分发的流程当中了 http://liupzmin.com/2019/11/06/docker/container-chat/

出自:https://github.com/johnlui/PPHC

本文由 mdnice 多平台发布

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/748429.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

关于typescript的类型推断一些理解

我们先看一段代码: interface defaultObjType {[key: string]: any; } interface SquareConfig {color?: string | defaultObjType;width?: number; } let obj:SquareConfig {color: {qw:123}, }if(obj.color && obj.color.qw) { // 这里报错&#xff…

【重要】MThings V0.6.0更新要点

我们听到了您的声音并采取了行动!现在为您提供了一次全面的软件升级,让您的体验更加顺畅、稳定和安全。立即更新,畅享新功能! 下载地址: http://gulink.cn/download 01. [新增]支持系统数据、历史数据、告警功能个人版…

Liunx命令大全及基础知识扫盲

文章目录 1,ifconfig命令2,ens10和eth103,查看PCI地址 1,到达最后一行 ctrl end 1,ifconfig命令 ifconfig 是一个用于配置和显示网络接口信息的命令行工具 1,ifconfig这将显示所有网络接口的详细信息,包括接口名称、MAC 地址、IP 地址、子…

2023中国企业绿电国际峰会

会议时间/地点/主办方 2023年11月16-17日,中国上海,ECV International 会议形式 峰会采用“线下线上”的方式同步进行,中英双语同声传译,线上、线下并行进行和实时互动。 峰会背景 当下全球气候问题正在不断显现,对…

conda修改环境保存地址

可以在命令行中通过conda config指令进行修改 如: 添加环境目录envs_dirs conda config --add envs_dirs F:\conda_env\envs 添加pkgs_dirs conda config --add pkgs_dirs F:\conda_env\pkgs 也可以直接进入Anaconda Nacigator进行修改

Java反序列化:URLDNS的反序列化调试分析

URLDNS链子是Java反序列化分析的第0课,网上也有很多优质的分析文章。 笔者作为Java安全初学者,也从0到1调试了一遍,现在给出调试笔记。 一. Java反序列化前置知识 Java原生链序列化:利用Java.io.ObjectInputStream对象输出流的w…

Openlayers实战:加载OpenStreetMap(快速显示无加载不出状态)

Openlayers官方一直演示的都是用Openstreetmap, 但是目前国内使用通用的new OSM(), 是加载不出来OSM地图的。在我们的实战中代码中,不但能够加载出Openstreetmap, 而且速度非常的快,这就涉及到一个曲线救图的处理方式,请参考源代码。 效果图 源代码 /* * @Author: 大剑师…

如何提取音频中的纯人声?分享三个方法给大家!

在处理音频文件时,有时候我们只希望提取其中的纯人声,以便进行后续处理或编辑。本文将介绍三种简单有效的方法,帮助您提取音频中的纯人声。方法一使用记灵在线工具,方法二使用Audacity,方法三则为您补充其他可选方案。…

Linux—实操篇:实用指令

目录 1、指定运行级别 1.1基本介绍 1.2、示例 1.3、CentOS7 后运行级别说明 2、找回root密码 3、帮助指令 3.1、man指令 3.2、help指令 4、文件目录指令 4.1、pwd 指令 4.2、ls 指令 4.3、cd 指令 4.4、mkdir 指令 4.5、rmdir 指令 4.6、touch 指令 4.7、cp 指…

Unified Named Entity Recognition as Word-Word Relation Classification

原文链接:https://arxiv.org/pdf/2112.10070.pdf AAAI 2022 介绍 NER主要包括三种类型:flat、overlap和discontinuous。目前效果最好的模型主要是:span-based和seq2seq,但前者注重于边界的识别,后者可能存在exposure b…

保护用户数据隐私:Web3 技术在电商行业中的应用

电商行业一直是全球经济发展的重要推动力。然而,随着电商行业的不断发展,中心化的支付、物流和数据存储方式逐渐暴露出安全隐患和隐私问题。这时,Web3 技术以其去中心化、安全性和透明性等特点,为电商行业带来了新的解决方案和可能…

关于var、let、const相同与不同

相同:var、let、const都可以声明变量 var milliaA "milliaA" let milliaB "milliaB" const milliaC "milliaC"console.log(milliaA,milliaB,milliaC) 不同: 一、变量提升,var有提升,let、cons…

初识 Redis - 分布式,内存数据存储,缓存

目录 1. 什么是 Redis 1.1 Redis 内存数据存储 1.2 Redis 用作数据库 1.3 Redis 用作缓存 (cache) 1.4 用作消息中间件 1. 什么是 Redis The open source , in-memory data store used by millions of developers as a database, cache, streaming engine, and message br…

使用 Elastic 时间序列数据流探索 Nginx 指标

作者:Lalit Satapathy Elasticsearch 最近发布了用于指标的时间序列数据流。 这不仅为 Elastic Observability 提供了更好的指标支持,而且还有助于降低存储成本。 我们在之前的博客中讨论过这个问题。 在本博客中,我们通过回顾什么是时间序列…

rar文件怎么打开?简单4步,轻松解决!

什么是rar文件? Rar文件是一种专用的文件格式,比较常用于归档打包和数据的压缩,我们可以将原有的文件数据压缩后保存为rar文件格式。其常用于将文件夹或者大型文件压缩为单个文件,以便更方便地传输和存储。 在日常的工作中&…

jmeter 终端命令执行jmx文件 生成jtl日志文件

终端命令执行jmx文件 生成jtl日志文件, 步骤如下: 步骤1:终端进入jmx文件目录 步骤2:执行命令:jmeter -n -t ****.jmx -l ****.jtl -n 以cli模式(命令行运行模式)运行jmeter -t 需要运行的…

怎么快速敲代码,最简单的代敲代码工具,codeWhisperer走起

题记:谁不想提升工作效率,谁不想有人帮你敲代码,来吧,上菜; 第一步:下载并安装AWS Toolkit(下载有点慢,请耐心等待); 第二步:点击start。 第三步…

【论文阅读笔记】Attack-Resistant Federated Learning with Residual-based Reweighting

个人阅读笔记,如有错误欢迎指出 Arxiv 2019 [1912.11464] Attack-Resistant Federated Learning with Residual-based Reweighting (arxiv.org) 问题: 联邦学习容易受到后门攻击 创新: 提出一种基于残差的重新加权聚合算法 聚合算法…

windows系统下jdk8和jdk17灵活切换

安装了jdk8和jdk17后环境变量path中会多出2条 C:\Program Files\Common Files\Oracle\Java\javapath C:\Program Files (x86)\Common Files\Oracle\Java\javapath 将它们下移到最下面,点击确认 这样做的原因是为了JAVA_HOME的优先级最高,达到更换JAVA…