惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
Tor Project blog
B
Blog RSS Feed
M
MIT News - Artificial intelligence
WordPress大学
WordPress大学
H
Hackread – Cybersecurity News, Data Breaches, AI and More
罗磊的独立博客
GbyAI
GbyAI
N
Netflix TechBlog - Medium
博客园 - 司徒正美
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
宝玉的分享
宝玉的分享
W
WeLiveSecurity
Stack Overflow Blog
Stack Overflow Blog
Y
Y Combinator Blog
SecWiki News
SecWiki News
V
Vulnerabilities – Threatpost
Google DeepMind News
Google DeepMind News
C
CERT Recently Published Vulnerability Notes
T
Tailwind CSS Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
The Register - Security
The Register - Security
Cisco Talos Blog
Cisco Talos Blog
Martin Fowler
Martin Fowler
A
About on SuperTechFans
S
Security @ Cisco Blogs
T
Tenable Blog
C
Check Point Blog
N
News and Events Feed by Topic
S
SegmentFault 最新的问题
The GitHub Blog
The GitHub Blog
C
Cyber Attacks, Cyber Crime and Cyber Security
Attack and Defense Labs
Attack and Defense Labs
美团技术团队
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
C
Cisco Blogs
P
Palo Alto Networks Blog
V
V2EX
博客园 - 聂微东
Project Zero
Project Zero
酷 壳 – CoolShell
酷 壳 – CoolShell
D
Docker
N
News | PayPal Newsroom
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
小众软件
小众软件
Application and Cybersecurity Blog
Application and Cybersecurity Blog
人人都是产品经理
人人都是产品经理
V2EX - 技术
V2EX - 技术
I
Intezer
L
LINUX DO - 最新话题

顾宇的博客

用 AI 重启生活 初始化 MacOS 关于我 再次见面,期待相遇 演讲和分享 如何通过政策红利获利?——海南发展(SZ.002163)交易复盘 2025年的总结 2024年的总结 2023年的总结 2022年的总结 《敏捷测试价值观、方法与实践》序 【翻译】函数式编程中的领域驱动设计 【翻译】通过跟踪技术债来改进你的开发实践 【翻译】不要把测试用例自动化 【翻译】持续部署 vs 持续交付 【翻译】测试替身 【翻译】做多少测试才足够 【翻译】蓝绿部署的起源 【翻译】持续部署 【翻译】作为演进式架构的微服务架构 【翻译】gRPC 的动机和设计原则 【翻译】分布式计算谬误 【翻译】微服务和分布式对象第一法则 采用 Multipass 管理本机虚拟 K8S 集群 博客主题升级到 Congo 2.0 【翻译】Terraform 最佳实践:模块组合 【翻译】Kubernetes 部署语言(Kubernetes Deployment Language) 通过 Vagrant 一键初始化 K8S 集群 2021年的总结 通过 Github Actions 部署 Mkdocs 文档 博客迁移到了新的 Hugo 主题 2020年的总结 2019年的总结 千人规模组织级 DevOps 演进的 9 个实践技巧 从技术雷达看 DevOps 的十年——容器技术与微服务 DevOps 模式 - 引入 DevOps 顾问 DevOps 模式 - 索引 DevOps 模式 - 定义你的DevOps 从技术雷达看 DevOps 的十年——基础设施即代码与云计算 DevOps 模式 - 采用模式语言讨论 DevOps 从星巴克店面运营学习 DevOps 从技术雷达看 DevOps 的十年——DevOps与持续交付 【翻译】微服务安全:所有应该被问到的问题 云原生下的 DevSecOps 实践 【翻译】软件定义交付宣言 微服务演进中的经验和反思 迟到的 2018 年终总结 成功微服务实施的组织演进 从第19期技术雷达看 DevOps 的发展趋势 成功微服务实施的技术演进 我们如何衡量微服务的成功? 关于四周四 AWS 架构工作坊的设计和实践 讨论微服务之前,你知道微服务的 4 个定义吗? 公有云(AWS)上的生产环境架构优化案例和迁移套路总结 一怒之下,我又写了一个开源流量测试工具 采用 DevOps 故事落地 DevOps 测试驱动开发 Nginx 配置 云原生 DevOps 翻译-混沌工程的原则 Serverless 风格的微服务的持续交付 从最新一期技术雷达看 DevOps 的发展 关于 DevOps ,咱们聊的可能不是一回事 Serverless 风格的微服务的架构案例 提升微服务实施效率的 7 个步骤 微服务实施常被忽视的 5 个难点 你的 CI 在挖矿吗? DevOps前世今生 - 4. DevOps 的文化 DevOps发展的九个趋势 不要让你的持续集成服务器成为安全隐患 DevOps 前世今生 - 3. DevOps 的目标和核心 DevOps 前世今生 - 2. DevOps 矛盾从何而来 DevOps 前世今生 - 1. DevOps 编年史
公有云(AWS)上的生产环境性能分析案例
顾宇 · 2018-08-07 · via 顾宇的博客
  1. 顾宇的博客/
  2. Blogs/
  3. 公有云(AWS)上的生产环境性能分析案例/

本文是我在 gitchat 上的文章云计算生产环境架构性能调优和迁移套路总结(以 AWS 为例)([原平台已下线,此为历史存档])的前半部分,本文对原文有所修改和总结。交流实录请点击这里([原平台已下线,此为历史存档])。

案例背景 #

案例是一个泰国网站的生产环境(请脑补一句“萨瓦迪卡”,为了叙述方便,下文中均以"萨瓦迪卡"指代这个网站。)“萨瓦迪卡”是一个 采用 Wordpress + MySQL搭建的应用。这个遗留系统已经工作了五年。客户已经把在其他 VPS 上平移到 AWS 上。平移(lift and shift)是说原样复制,而迁移(migration)还要进行改造。而客户唯一发挥 AWS 优势的一点就是用了一个配置很高的 EC2 虚拟机 —— m4.4xlarge。这样一台配置的虚拟机有 16 个虚拟 CPU,64 GiB 的内存,以及 2000 Mbps 的网络带宽,最高 3000 IOPS 的 200GiB 的块存储设备(也就是硬盘)。

知识点: GiB 是用二进制计算的,GB 是用十进制计算的。1 GiB 是 2的30 次方,而1 GB 是10 的 9 次方,1 GiB 略大于 1GB。 而且,AWS 的 FreeTier 免费计划是按 GB 计算的哦!

除了基本的网络和虚拟机以外,“萨瓦迪卡” 的所有东西都放在一台虚拟机上。没错,是所有东西——Web 服务器,反向代理,数据库,上传的文件——都放在一台虚拟机上。唯一个一个负载均衡用来承载 HTTPS 证书,没有使用集群,没有高可用,没有数据库/应用分离,没有防火墙,没有 WAF,没有 APM,没有 CDN 而且,没有持续交付流水线,所有部署都要 ssh 到机器上进行操作。如图所示:

原始架构

“萨瓦迪卡”的生产环境可以被认为是一个裸奔的肉鸡。我曾经一度它已经被轮番入侵很久了,只是还没有被发现而已。而且,“萨瓦迪卡”生产环境的唯一一台服务器的内存率使用经常超过 95%,我很担心它的状况,任何一个小的 DoS,都不需要 DDoS,就可以让它整站宕机了。

我于是把我的担忧汇报给了客户,客户也意识到了问题。在我发现问题之前的一个月就启动了“萨瓦迪卡”的翻新(Revamp)项目,让这个应用保持原样(Keep it as is),直到 6 个月后新项目上线,替换掉当前应用。

然而,没想到我一语成谶。一天,“萨瓦迪卡”被删库了!

“删库?别慌!” #

作为一个运维工程师,最悲催的事情就是“人在家中坐,锅从天上来”。这天是世界杯的某一场小组赛,而我刚吃完晚饭正在洗碗。突然被客户的 P1 告警(P1 - Priority 1,最高级别告警)惊吓到,得知“萨瓦迪卡”被删库了。

判断的依据是:

  1. “萨瓦迪卡”主页打开是 Wordpress 的初始化安装页面。证明应用是正常的,数据不在了。
  2. 在服务器上用 MySQL 客户端登录数据库,找不到“萨瓦迪卡”的数据库。

还好客户每天有全量数据备份,于是客户快速从全量备份恢复了数据库,只是缺少了从备份点到故障点的业务数据。全量数据库的备份文件有 10 GiB,这么大的表如果采用 mysqldump 会因为锁表而导致 10 分钟左右的停机时间(别问我怎么知道的)。

问题分析 #

在恢复应用的同时,我们也开始进行了分析的工作。首先,我们怀疑是被攻击了。于是通过 AWS 的 CloudTrail(一种审计工具,用来记录登录 AWS 用户的操作)和 主机上的命令历史(history 命令)和登录日志进行分析,结果一无所获。其次,我开始检查 MySQL 的日志(/var/lib/mysql/*.err),在日志上发现如下片段:

InnoDB: Log scan progressed past the checkpoint lsn 126908965949
180622 17:21:09  InnoDB: Database was not shut down normally!
InnoDB: Starting crash recovery.

<此处省略很多行>

180622 17:21:32 InnoDB: Initializing buffer pool, size = 3.0G
InnoDB: mmap(3296722944 bytes) failed; errno 12
180622 17:21:32 InnoDB: Completed initialization of buffer pool
180622 17:21:32 InnoDB: Fatal error: cannot allocate memory for the buffer pool
180622 17:21:32 [ERROR] Plugin 'InnoDB' init function returned error.
180622 17:21:32 [ERROR] Plugin 'InnoDB' registration as a STORAGE ENGINE failed.

通过分析,我们发现 mysql 发现自己有问题的时候尝试恢复数据库,但因为虚拟机可用内存不足而加载存储引擎失败,导致找不到数据库。因此,解决方案有以下三种:

  1. 采用工具进行对 mysql 服务器参数进行调优。
  2. 扩大内存,换个配置更高的虚拟机。
  3. 将应用和数据库部署在不同的虚拟机实例或者 RDS (关系数据库服务)上。

而三种有各自的问题:

对于方案1,数据库调优需要频繁重启。对于生产环境来说,必须在低流量的时段(一般是夜间)进行。而且所花时间未知且效果很难保证。由于资源有上限,且进程相互影响,很难发现问题。所以风险较高,价值有限。

对于方案2,需要对虚拟机进行不停机镜像复制,因此会导致部分数据丢失,而且数据同步恢复困难大。而且,不知道需要多少资源的虚拟才足够。问题同方案1,只不过由于资源更多,下次出现同样问题的时间更晚罢了。这个方案的风险虽然比第一种小,但用空间换时间的价值仍然有限,不晓得能撑到什么时候。而且,可能会带来一定的资源浪费。

方案3是风险最小,价值最大的方案。它将数据作为核心资源并托管至高可用服务上,有效了隔离了风险,保护了数据的可用性。但唯一的缺点就是对于需要的资源和性能是未知的。因此,在实施这个方案之前,我们需要进行性能测量。

你可能会想,只需要增加一些基础设施监控和 APM (Application Performance Monitoring,应用性能监控)就可以得到相应的数据了。然而,在生产环境的性能度量没那么简单。

**首先,我们要保证生产环境的业务连续性。**APM 也是一种应用程序,也会占用资源,你如何确定安装和运行 APM 的过程不会造成生产环境停机?其次,如果一定会造成停机,那么会停机多久?当这些问题都是未知的情况下,鲁莽的行为只能增加更多的不确定性风险。

因此,在迁移之前,我们要模拟生产环境进行度量并进行分析

设计性能度量 #

性能度量是一个从“未知”到“已知”的过程。

**首先,你需要明确所要度量的问题。**你可以和你的小组一起商定需要解决的问题。在上面这个案例里,我们所需要回答的问题包括:

  1. 正常运行应用程序需要多少内存?
  2. 正常运行数据库需要多少内存?
  3. 进行哪些操作会导致停机时间?停机时间会持续多久?
  4. 资源使用对性能的影响有多少?
  5. 性能拐点在哪里?

当然,对于 CPU,网络和存储,你也可以设计以上的问题。

然后,找到数据基线 (Benchmark) #

由于资源的使用是和用户访问数量息息相关的,你还需要知道资源使用的均值峰值边际值

均值是资源使用基线,也就是最小值。

峰值是资源使用的警告线,如果过去发生过这么高。

边际值是指每单位的用户请求所消耗的资源。

一般来说,这些数据都可以从云计算提供商的非侵入式监控服务获得,它的数据收集不会影响资源的性能。例如 AWS 的 CloudWatch 。我们可以根据过去 6 个月或者 3个月的时间来估计均值和峰值。**但由于未来是不确定的,因此过去 6 个月或者 3 个月的数据是建立在“未来访问量不会突变”的假设基础上的。**例如,如果有类似于“6·18” 或者 “双十一” 的流量高峰,则日常的数据参考意义不大。

如果缺乏这样的手段,就要通过复制生产环境来度量了。

复制生产环境 #

复制生产环境的一点原则就是“尽量减少不同”,尽可能的按照生产环境的配置来构建你的沙盒环境以得到更接近真实的数据。很多云提供商都提供镜像(Image)或者快照(Snapshot)的功能用来复制当前有状态的资源。有时候二者是同一个意思。如果有区别,二者的区别在于以下几点:

  1. 镜像是全量,快照是增量。
  2. 镜像的构建需要停机,而快照不需要。
  3. 镜像生成时间长,快照生成时间短。
  4. 镜像不能指定时间点部分还原,快照可以根据时间点部分还原。

无论是哪一种,我们都要选择一个对生产环境影响最小的方案。在 AWS 中,我们可以根据当前的虚拟机实例构建虚拟机镜像 AMI (Amazon Machine Images)。它提供两种方式:一种是不重启(no reboot),这种方式的缺点是会造成构建镜像时间点以后的数据丢失。另外一种是在构建之前重启实例,这样不会导致数据丢失。

**对于上述的案例来说,生产数据的完整性并不会影响我们的度量,因此,无需重启实例。**但如果你要度量重启实例会带来多少数据丢失,则需要重启实例。

此外,为了保证你不会误操作,我建议你在非生产环境的云计算账号下重建应用。如果你一定要在同一个账户中进行复制,请确保你做好了生产环境资源隔离。

设计测试场景 #

当你在测试环境下复制了生产环境,你就有了一个安全的沙箱来进行测试了。当我们开始进行性能测试的时候,我们要通过“整体”的测试来计算对“局部”的影响。并找到。以“萨瓦迪卡”为例,我们通过 AWS 上的数据得到了“萨瓦迪卡”生产环境的平均响应时间:0.2 ~ 0.4 秒,RPM(Requests Per Minute 每分钟请求)大概在 4500 左右。

因此我们设计了如下测试场景:

  1. 空闲使用率:0 请求的时候,资源使用率。
  2. 1 个,10 个,20 个 并发请求的时候,资源使用率和响应时间,用于计算边际资源使用率。
  3. RPM 和生产环境 RPM 均值相等的情况下,资源使用率和响应时间。
  4. 2 倍 ,4 倍, 10 倍 生产环境 RPM 均值的情况下,资源使用率和响应时间。
  5. 模拟生产环境的 RPM 增长速度(逐步增加请求到相应值,例如 5 分钟增长到 2000 RPM)进行测试。
  6. 模拟生产环境极限 RPM 增长速度(一次增加请求到对应值,例如 5 秒钟增长到 2000 RPM)进行测试。

根据以上的测试场景,我们可以构建资源使用率和响应时间之间的关系。

如果你有 CDN 或者 URL 访问分析数据,可以它来构建你的测试案例。如果什么没有,例如“萨瓦迪卡”这种情况,你就可以使用主页的 URL 来进行测试。常用的工具有 Selenium, Jmeter 和 Gatling。你可以用 Selenium 录制一个用户访问的脚本,来模拟用户访问。你也可以通过 Jmeter 或 Gatling 来增加并发进行负载测试,后者能提供更加有用的信息。

如果你无法模拟足够多的真实用户数据,把以上的工具生成的脚本或配置放到 flood.io 上运行(该服务已下线,此为历史存档),得到更好的参考报告,如下图所示:

flood.io

如果你需要度量某些操作的停机时间,你可以在进行负载测试的时候进行操作。也可以使用我写的小工具 wade (Web Application Downtime Estimation)来测试。关于 wade 的故事可以参考 一怒之下,我写了一个开源流量测试工具

通过模拟“萨瓦迪卡”的访问数据,我得到了以下数据:

  1. 当 Web 服务器(Apache)重启完,仅有健康检查访问的情况下,系统占用 367 MiB 内存。
  2. 数据库占用 10 GiB 左右内存,也就是说,给 Web 应用剩下的内存有 53 GiB 左右。
  3. 分别度量了 1个用户,10 个用户,20 个用户并发访问下的内存使用情况。平均每处理一个请求,最多需要消耗 133 MiB 内存。
  4. 也就是说,剩下的内存最大能服务 400 个左右的用户的并发访问。如果超过 400 个用户,系统会因为资源不足而宕机。
  5. 升级虚拟机 Linux 中的软件包和安全补丁会带来 5 秒钟左右的停机。
  6. APM (NewRelic)的安装会占用 63 MiB 左右内存且无停机时间。

编写性能度量报告 #

当我们完成了性能度量的时候,就要编写一份性能度量报告。性能度量报告包含以下 6 个部分:

  1. 背景:主要回答为什么(Why)要做这一次性能度量。
  2. 关键问题:通过性能度量期望知道哪些问题(What)。
  3. 测试设计:主要介绍度量方法(How),以及度量方法中的注意事项。
  4. 测试条件:由于是模拟测试,要强调与真实值的匹配情况,哪些部分重要,哪些部分不重要。
  5. 测试数据结果:采用工具得出的真实数据,要有源可查,最好是截图。
  6. 结论:根据数据的计算解答第 2 步 提出的关键问题。
  7. 建议:根据度量数据得出的下一步优化建议。

至此,我们完成了对生产环境性能的分析。接下来,就要为性能设计架构迁移方案了。请关注下篇《 AWS 上的生产环境架构优化案例