高并发的哲学原理(一)-- 找出单点,进行拆分

news2024/11/24 20:41:16

人列计算机

《三体》中,刘慈欣设计了一个用人进行二进制运算的计算机,使用了三千万名士兵(晶体管):

alt
  • 计算机名:秦一号
  • CPU:秦始皇最精锐的五个军团
    1. 挥舞旗帜进行二进制运算
    2. 用三个士兵来组成与门、或门、与非门、或非门、异或门、同或门和三态门,又用两个士兵组成了非门
    3. 将这些基本部件组合起来,构成了计算阵
  • 内存:由文化程度较高的人组成,每个人挥舞多个颜色的旗帜,可以替代 20 个挥舞单色旗帜的人
  • 硬盘:三百万文化程度较高的人(据说是上次坑儒留下来的)
  • 显示阵列:至少配有红色和绿色像素单元(双色显示阵列)
  • 维护部件:一组骑兵
    1. 传输信号
    2. 处理“故障”士兵
    3. 由秦始皇最精锐的骑兵团构成
  • 维护方式:更换出错部件

一提到高并发,很多人的第一反应都可以归纳为以下两种情况:

1. 进程间通信(IPC)、共享内存、管道、队列、事件:这是学院派

2. 内存缓存、消息队列、分库分表、NoSQL、ES 搜索:这是实战派

其实,高并发之路,无论是学院派还是实战派,甚至是刘慈欣设计的人列计算机,其背后的哲学原理都是一样的。如果你问人列计算机和高并发有什么关系?按照上面的设计,最多一万名士兵就够了,为什么需要三千万呢?还不是为了提高性能。

其实,高并发的哲学原理早就隐藏在了现代计算机的基础结构之中,感兴趣的欢迎去看我的《性能之殇(二)-- 分支预测、流水线与多核 CPU》¹。

本文目标

上面只是我的喃喃私语,下面我们进入正题。

本文的目标是在我有限的认知范围内,讨论一下高并发问题背后隐藏的一个哲学原理。我们将从动静分离讲起,一步步深入 Apache、Nginx、epoll、虚拟机、k8s、异步非阻塞、协程、应用网关、L4/L7 负载均衡器、路由器(网关)、交换机、LVS、软件定义网络(SDN)、Keepalived、DPDK、ECMP、全冗余架构、用户态网卡、集中式存储、分布式存储、PCI-E 5.0、全村的希望 CXL、InnoDB 三级索引、内存缓存、KV 数据库、列存储、内存数据库、Shared-Nothing、计算存储分离、Paxos、微服务架构、削峰、基于地理位置拆分、高可用等等等等。并最终基于地球和人类社会的基本属性,设计出可以服务地球全体人类的高并发架构。

先说结论,这个哲学原理就是:找出单点,进行拆分

准备工作

性能问题要靠架构解决

在展开这个哲学原理前,我们需要先明确一下高并发问题的解决思路:性能问题要靠架构解决。

首先,在架构上动刀是最简单的,也是最容易获得收益的。其次,即便是真的去做单个资源的性能优化,例如 MySQL 单机性能优化(软件优化)、x86 CPU 多核性能提升(硬件优化),拆到微观来看,也是在做架构优化:

没有银弹就是计算机世界的第一准则,你想获得收益,总得拿出一些东西,和信息之神交换。

我们讨论“哪个”高并发?

本文讨论的是“web 服务高并发”问题,典型场景为电商秒杀:同一个时刻,数万人抢同一个低价商品,会给系统的每一个层面都造成显著的性能瓶颈,这种场景的集大成者,就是每年的双 11。

一个小目标

找出单点,进行拆分,就是将每一个大单点都拆成一个小单点+多资源并行的形式。

在解决高并发问题的过程中,我们会不断地遇到新的单点:web server、单个操作系统、虚拟化/容器技术、编程语言运行架构、网络、UNIX 进程模型、数据库等。每遇到一个单点,我们都要见招拆招,使用架构工具拆掉它。计算机的虚拟化程度非常高,几乎每个单点都可以继续往下拆。

接下来大家就跟着我一起,一步一步将系统性能的上限从单机 100 QPS 提升到 1,000,000(一百万)QPS。

文章列表

  1. 找出单点,进行拆分(本文)
  2. Apache 的性能瓶颈与 Nginx 的性能优势
  3. 基础设施并发:虚拟机与 Kubernetes(k8s)
  4. 隐藏在语言背后的魔鬼:运行架构为何会成为性能瓶颈
  5. 拆分网络单点(上):应用网关、负载均衡和路由器(网关)
  6. 拆分网络单点(下):SDN 如何替代百万人民币的负载均衡硬件(网关、LVS、交换机)
  7. 最难以解决的单点:数据库以及它背后的存储
  8. 将 InnoDB 剥的一丝不挂:B+ 树与 Buffer Pool
  9. 细数四代分布式数据库并拆解 TiDB 和 OceanBase(主从、中间件、KV、计算与存储分离、列存储、CAP定理)
  10. 理论无限容量:站在地球表面

找出第一个单点

大部分系统都是从单个虚拟机开始的,原始的资源可能只有 1 核 2G,你安装了一个 Apache,一个 MySQL,把代码部署上去,这个系统就开始对外服务了。如果系统用户数量增加了,你会发现,CPU 满了,这个时候,我们第一个应该拆的就是静态流量。

动静分离

大概是在 2013 年,我用从同学那里买的二手 MacBook Pro 跑过 Apache 和 Nginx 的性能测试,在本机访问同一张 jpg 图片的情况下,Apache 的 QPS 为 2 万出头,而 Nginx 则超过 8 万,四倍性能。

所以,如果你还在用 Apache 承载所有流量,在前面加一个 Nginx 就能显著降低 CPU 占用率,大幅提升系统性能。如果你再利用云服务商把这些静态资源用 CDN 来承载,你的静态资源压力还能再降低 90%。

动静分离以后,CPU 又满了,该怎么办呢?这个时候就需要把数据库拆出去了。

最适合独立部署的软件:数据库

如果应用代码和数据库跑在一个系统上,压力稍微大一点,很容易出现“债股双杀”的局面:MySQL 的响应变慢,应用代码就需要更长时间的等待,又要消耗更多的 CPU 资源,从而形成“内卷”和“踩踏”。只要你的系统不是用户极其少,或者你们公司极其抠,把数据库独立部署的收益都是要高于投入的:1 核 2G 的虚拟机就够 MySQL 跑到 200 QPS了,配合缓存支撑一个日 PV 100 万的小系统应该够了。

我的实际经验

进击的爬虫

2017 年,我维护的一个 SEO 网站突然遭遇大量爬虫的袭击:由于这个网站拥有数百万个内容页面,页面内也有着大量的“类似文章推荐”,在只依靠 MySQL like语句的情况下,单个页面的返回时间长达 300-500ms。一天两万的真实用户 UV 对系统的压力并不大,但这些爬虫不讲武德,上来就是 100 QPS,当时 1 核 2G 的虚拟机和 1 核 1G 的 MySQL 可遭了殃了,完全顶不住。

这些爬虫并不是正规大厂的爬虫,而是采集机器人,由于拥有海量代理 ip,对网站形成了 DDOS 态势,没法使用常规手段封禁,只能想办法抗住。

我首先做的,就是将静态资源全部 CDN 化,直接让 CPU 占用率降低了一半。然后就开始着手提升系统性能:

  1. 使用 ElasticSearch 提供“类似文章推荐”,将每个页面的响应时间压缩到了 200ms
  2. 提升数据库性能:增加索引,增加 Redis 缓存,使用定时任务刷新文章总数而不是实时计算,将响应时间压缩到了 120ms
  3. 访问 ES 的 HTTP 请求进行并行化:虽然 PHP 是一种阻塞语言,但是一次性发送多个 HTTP 请求的能力还是有的,平均每个页面有五次请求,每次 15ms,并行化以后从 15ms*5 减少到了 25ms,最终将平均响应时间压缩到了 70ms

同时,服务器和数据库也进行了计算资源的扩容,增加到了 2 核 4G 的虚拟机和 2 核 4G 的 MySQL,最终顶住了每天 200 万次页面访问的冲击,对比之下,真实用户 PV 每天只有十万左右。

这个时候可能有人会问了,既然是内容网站,为什么不静态化呢?因为数据量太大了,500 万个页面,一个页面 100KB,就是 476GB 的磁盘容量,这个量级太夸张了,不如做性能优化硬抗了,这么多静态资源的管理和刷新反而是个更大的问题。在百万量级下,数据库绝对是更好的数据存储解决方案,远比自己管理文件要更简单更稳定。

即便我做了那么多,还是不乏有一些爬虫愣头青在学习了 swoole 和 go 协程之后,对我的网站发动数千 QPS 的死亡冲锋,这个时候再怎么性能优化都是没用的,这时就需要使用倒数第二个工具:限流。

我做了三道限流关卡才最终顶住采集机器人 DDOS:

  1. 针对单个 ip 做请求频率限制
  2. 针对整个 /24 ip 段做请求频率限制(很多爬虫采用同一段内的多个 ip 绕过限流)
  3. 针对每个 UA 做请求频率限制

在这三板斧使出来以后,天下太平了,网站再也没有被突然发起的死亡冲锋搞挂过。

对了,既然限流是倒数第二个工具,肯定有人好奇最后一个工具是什么?那就是熔断,熔断属于系统鲁棒性工具,是善后用的,我们最后一篇文章还会再提一嘴。

本文由 mdnice 多平台发布

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

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

相关文章

Python批量实现word中查找关键字

一、背景 在日常办公和文档处理中,我们常常需要在大量的Word文档中查找特定的关键字,然后进行接下来的操作,比如关键字替换等。手动逐个打开并搜索文档显然是费时费力的。因此,利用Python编写一个批量实现Word中查找关键字的程序可…

18、气象学中风场的绘制

文章目录 前言一、批量读取数据二、绘制2022年的平均风场三、绘制每个季节的平均风场四、绘制每个月的风场 前言 数据及代码下载链接➡️:如何绘制自定义颜色的风场图 一、批量读取数据 import os import xarray as xrfolder_path "./" file_pattern …

22、ThreadLocal的原理和使用场景

ThreadLocal的原理 每一个thread对象均含有一个ThreadLocalMap类型的成员变量threadLocals&#xff0c;它存储本线程中所有 ThreadLocal对象及其对应的值 ThreadLocalMap 由一个个Entry对象构成 Entry继承自WeakReference<ThreadLocal<?>>&#xff0c;一个Entry…

Qt6 绘制矩形和一些字符串函数讲解

Qt6 绘制矩形和一些字符串函数讲解 【1】Qt 6 模拟C的cout输出QTextStream类简介举例 &#xff08;标准输出&#xff09; 【2】Qt 6 绘制移动的矩形事件运行效果UI界面头文件.h源文件.cpp 【1】Qt 6 模拟C的cout输出 只教方法&#xff0c;更多内容请学习官方文档 QTextStream…

使用FreeMarker自定义生成word文档

使用FreeMarker自定义生成word文档 最终生成word文档如下&#xff1a; 实现思路&#xff1a; 按照要生成的文档模板格式&#xff0c;创建一个新的word&#xff08;doc&#xff09;文档&#xff0c;将其调整成所需格式&#xff0c;然后处理其中需要动态填充的数据&#xff0…

stable diffusion如何确保每张图的面部一致?

可以使用roop插件&#xff0c;确定好脸部图片后&#xff0c;使用roop固定&#xff0c; 然后生成的所有图片都使用同一张脸。 这款插件的功能简单粗暴&#xff1a;一键换脸。 如图所示&#xff1a; 任意上传一张脸部清晰的图片&#xff0c;点击启用。 在其他提示词不变的情况下…

LoRA: 大模型快速训练的秘诀

本文是四两拨千斤&#xff0c;训练大模型的PEFT方法的最后一小节&#xff0c;感兴趣读者可以阅读完整版。 LoRA LORA: LOW-RANK ADAPTATION OF LARGE LANGUAGE MODELS 核心思路是对模型参数做低秩分解&#xff0c;仅训练分解后的参数&#xff0c;模型部署也需额外保存低秩参数&…

SIP业务之BLF

BLF&#xff08;Busy Lamp Field&#xff09;是SIP应用中的一项重要业务&#xff0c;用来监视目标号码的状态&#xff0c;常用于调度、坐席监控等场景。 一、 BLF原理 BLF功能需要IP终端或话机与SIP服务器协同实现的&#xff0c;主要流程如下&#xff1a; IP话机向SIP服务器发…

如何使用 ChatGP在TTPU(张量处理单元)上训练模型的指令

推荐&#xff1a;将NSDT场景编辑器加入你的3D工具链 3D工具集&#xff1a;NSDT简石数字孪生. ChatGPT 作为您的专家助手 ChatGPT 可以帮助我们学习新的编程语言、课程、技术和技能。它已成为许多寻求改进工作流程或学习新事物的专业人士的首选工具。ChatGPT 专家助手提示可以减…

IntelliJ IDEA安装教程

一、下载安装包 首先进入IDEA官网下载2021.2.1版本的安装包&#xff0c;不要问我为什么不下最新版&#xff0c;后面我会说。 二、安装与配置 打开安装包&#xff0c;安装完成后选择Evaluate for free&#xff08;免费试用&#xff09;&#xff0c;创建一个项目&#xff0c;进入…

基于单片机空气质量检测二氧化碳 一氧化碳温湿度PM2.5检测系统的设计与实现

功能介绍 以51单片机作为主控系统&#xff1b;对空气空气中有毒有害气体进行监测&#xff1b;使用LCD1602液晶显示&#xff0c;采集到的PM2.5值通过单片机串口传输&#xff1b;通过传感器对室内PM2.5粉尘进行检查&#xff1b;通过按键设置的上限值&#xff1b;当检测到有毒气体…

5.2 基于ROP漏洞挖掘与利用

通常情况下栈溢出可能造成的后果有两种&#xff0c;一类是本地提权另一类则是远程执行任意命令&#xff0c;通常C/C并没有提供智能化检查用户输入是否合法的功能&#xff0c;同时程序编写人员在编写代码时也很难始终检查栈是否会发生溢出&#xff0c;这就给恶意代码的溢出提供了…

网络ping丢包什么原因(附解决方案)

​  数据包丢失是一种网络问题&#xff0c;当通过网络(或设备之间或通过 Internet)传输的数据包在传输过程中丢失或丢弃并且无法到达目的地时&#xff0c;就会发生这种情况。简单来说&#xff0c;数据包丢失是指数据包无法通过互联网从发送者成功传输到接收者。 如何检测数据…

阿里云RockMQ与SpringBoot的整合

前言&#xff1a; 开源版本Rocket和商业版本的RocketMQ有些不同&#xff0c;研究的是商业版本的RocketMQ&#xff0c;阿里云的官方文档&#xff0c;感觉有点乱。看不咋明白&#xff0c;网上虽然有教程&#xff0c;大都还是有点缺少&#xff0c;有时候会突然跳了步骤&#xff0c…

微信小程序开发1

这里写目录标题 一、结构1.项目结构页面结构 3.小程序的通信模型4.小程序运行机制 二、组件视图容器组件 : 一、结构 1.项目结构 页面结构 2.语言结构 WXML与HTML区别 : WXSS与CSS区别 : .Js文件的分类 3.小程序的通信模型 ①他是由渲染层与逻辑层 根据微信客户端进行转…

RPC分布式网络通信框架(三)—— 服务配置中心Zookeeper模块

文章目录 一、使用Zookeeper的意义二、Zookeeper基础1 文件系统2 通知机制3 原生zkclient API存在的问题4 服务配置中心Zookeeper模块 三、Zk类实现Start方法创建节点、get节点值方法 四、框架应用rpc提供端框架rpc调用端&#xff08;客户端&#xff09;框架 总结 一、使用Zook…

平均精度 (mAP):常见定义、误区和误解

我们分解并揭开了常见对象检测指标的神秘面纱,包括平均精度 (mAP) 和平均平均召回率 (mAR)。 这篇文章深入介绍了如何正确计算和使用平均平均精度 (mAP) 和平均平均召回率 (mAR) 进行对象检测,同时消除对 AP、mAP 和第三方库(例如 TorchMetrics 或 pycocotools)的常见误解。…

基于冻土水文模拟的松花江流域水资源演变规律

原文信息 题目&#xff1a;基于冻土水文模拟的松花江流域水资源演变规律 作者&#xff1a;刘水清 周祖昊 刘佳嘉 李佳 谢新民 贾仰文 王浩 期刊&#xff1a;《南水北调与水利科技&#xff08;中英文&#xff09;》23年1期 摘要 为分析松花江流域水资源的演变规律&#…

基于SpringCloud微服务图书管理系统设计与实现

一、引言 本次设计基于JavaEE和SpringCloud微服务的图书馆管理系统。利用当前计算机技术的快速发展来构建图书馆管理系统。 随着计算机技术和网络的飞速发展,互联网与互联网加的程序应用在世界范围内越来越流行,当今社会正迅速进入信息社会,信息自动化的作用也日益增强。…

MySQL基础篇第7章(单行函数)

文章目录 1、函数的理解1.1 什么是函数1.2 不同DBMS函数的差异1.3 MySQL的内置函数分类 2、数值函数2.1 基本函数2.2 角度与弧度互转函数2.3 三角函数2.4 指数和对数2.5 进制间的转换 3、字符串函数4、日期和时间函数4.1 获取日期、时间4.2 日期与时间戳的转换4.3 获取月份、星…