前言 性能调优是一个老生常谈的话题,通常情况下,一个应用在上线之前会进行容量规划、压力测试并进行验证,而性能调优则是在容量规划与验证结果之间出现差异时会进行的必然手段。从某种角度来讲,性能调优是一个非常需要经验的领域,需要调优人员对应用的架构、调用的链路、使用的语言、操作系统的差异、内核的参数表现等等都有完整的了解。

前言

性能调优是一个老生常谈的话题,通常情况下,一个应用在上线之前会进行容量规划、压力测试并进行验证,而性能调优则是在容量规划与验证结果之间出现差异时会进行的必然手段。从某种角度来讲,性能调优是一个非常需要经验的领域,需要调优人员对应用的架构、调用的链路、使用的语言、操作系统的差异、内核的参数表现等等都有完整的了解。大部分情况下,系统性能调优都是通过各种各样的工具监听、跟踪、分析、检测来检查解决的。所以通常情况下,性能调优的老手都有一套自己的诊断工具集以及相应的诊断方式。但是当性能调优遇到Docker的时候,很多事情发生了转变甚至恶化。

经常有客户抱怨说应用进入Docker后,应用的QPS无法和ECS进行媲美,并且时常会出现DNS查询超时、短连接TIME_OUT、网络丢包等等,这极大打击了客户对使用容器技术的信心与决心。诚然,容器化的方式根据网络模型的不同,会在传输效率上面略有差异,但远远达不到客户反馈的性能损耗,而在容器中进行调优与诊断的效果因为安装工具的复杂度大大折扣。

那么到底该如何针对容器的场景进行调优呢?

性能调优的“望闻问切”

在讨论容器化场景的性能调优之前,想先和大家谈一下性能调优中的“望闻问切”的问题。对于性能问题,大部分人第一个想到的是CPU利用率高,但是得到CPU利用率高这个现象后,我们改如何解决呢?从某种意义来讲,这个只是现象,并不是症状。为了方便大家理解,在此我打一个比方:感冒的时候我们去医院看病,病人跟大夫描述的是现象,包括头部发热、流鼻涕等等;而大夫通过探查、化验,得到的医学症状是病人的白细胞较多,喉咙有红肿等等,然后大夫确诊是细菌性感冒,给你开了999感冒灵。诊断病情的过程和性能调优是一样的,也需要找到现象、症状和解法。我们回到刚才CPU利用率高的例子:我们已知的现象是CPU的利用率高,然后我们通过strace进行检查,发现futex_wait系统调用占用了80%的CPU时间,而这才是真正的症状,根据这个症状,我们业务逻辑代码降低了线程切换,CPU利用率降低。

大部分的性能调优问题都可以通过发现现象、探测症状、解决问题这三个步骤来进行,而这在容器的性能调优中就更为重要的,因为在主机的性能调优过程中,我们有很多的经验可以快速找到症状,但是在容器的场景中,很多客户只能告诉我们的是现象。从某种角度来讲是由于客户并不了解使用的容器引擎的工作原理以及容器化架构的实现方式。那么接下来我们来看下容器化场景中性能调优面对的挑战。

容器化性能调优的难点

  1. VM级别的调优方式在容器中实现难度较大
    在VM级别我们看到的即是所有,网络栈是完整暴漏在我们面前的,CPU、内存、磁盘等也是完全没有限制的。性能调优老司机的工具箱安个遍,诊断流程走一趟基本问题就查个八九不离十了,但是在容器中,很多时候,都是默认不自带诊断、调优工具的,很多时候连ping或者telnet等等基础命令都没有,这导致大部分情况下我们需要以黑盒的方式看待一个容器,所有的症状只能从VM层的链路来看。但是我们知道容器通过namespace的隔离,具备完整网络栈,CPU、内存等通过隔离,只能使用limit的资源,如果将容器当做黑盒会导致很多时候问题症状难以快速发现。排查问题的方式变难了。
  2. 容器化后应用的链路边长导致排查问题成本变大
    容器的场景带来很多酷炫的功能和技术,比如故障自动恢复,弹性伸缩,跨主机调度等等,但是这一切的代价是需要依赖容器化的架构,比如Kubernetes网络中需要FullNat的方式完成两层网络的转发等等,这会给排查问题带来更复杂的问题,当你不清楚编排引擎的架构实现原理的时候,很难将问题指向这些平时不会遇到的场景。例如上面这个例子中,FullNat的好处是降低了网络整体方案的复杂性,但是也引入了一些NAT场景下的常见问题,比如短连接场景中的SNAT五元组重合导致包重传的问题等等。排查问题的方位变大了。
  3. 不完整隔离带来的调优复杂性
    容器技术本质是一种虚拟化技术,提到虚拟化技术就离不开隔离性,虽然我们平时并不需要去考虑隔离的安全性问题,但是当遇到性能调优的时候,我们发现内核的共享使我们不得不面对的是一个更复杂的场景。举个,由于内核的共享,

    系统的proc是以只读的方式进行挂载的,这就意味着系统内核参数的调整会带来的宿主机级别的变更。在性能调优领域经常有人提到C10K或者C100K等等类似的问题,这些问题难免涉及到内核参数的调整,但是越特定的场景调优的参数越不同,有时会有彼之蜜糖,我之毒药的效果。因此同一个节点上的不同容器会出现非常离奇的现象。

  4. 不同语言对cgroup的支持
    这个问题其实大多数场景下我们是不去考虑的,但是在此我们把他列在第四位的原因是期望能够引起大家的重视。一次在和Oracel

    Java基础库的负责同学聊天中了解到Java针对与Cgroup的场景做了大量的优化,而且时至今日,在Java的标准库中对于Cgroup的支持还是不完全的,好在这点在大多数的场景中是没有任何影响,也就不过多的讨论。排查问题的脑洞更大了。

  5. 网络方案不同带来的特定场景的先天缺欠
    提到容器架构我们逃不掉的话题是网络、存储和调度,网络往往是一个容器架构好坏的最根本的评判标准,不同的网络方案也会有不同的实现方式与问题。比如在阿里云的Kubernetes中我们使用了Flannel的CNI插件实现的网络方案,标准Flannel支持的Vxlan的网络方案,Docker的Overlay的macVlan,ipvlan的方案等等。这些不同的网络方案无一例外都是分布式的网络方案而存储的数据都会存放在一个中心存储中,因此越大型的集群对网络中心存储的压力也就越大,出错的可能性就越大。此外跨宿主机的二层网络很多都会通过一些封包解包的方式来进行数据传输,这种方式难免会增加额外的系能损耗,这是一种先天的缺欠,并不是调优能够解决的问题。有的时候排查出问题也只能绕过而不是调优。
  6. 镜像化的系统环境、语言版本的差异
    应用容器化是一个需要特别值得注意的问题,很多公司其实并没有严格的配管流程,比如系统依赖的内核版本、语言的小版本等等,进行应用容器化很多时候都是选择一个大概的版本,这会带来很多语言层级的BUG,比如PHP7.0中php-fpm的诡异行为,而这个现象在客户原本的5.6版本上已经修复过了。环境的问题本是一个严肃的问题,需要严格个管控,但是当遇到了容器,很多时候我们会分不清哪些不经意的行为会带来严重的问题。警惕性因为容器镜像能够正常启动而降低。

最后

这篇文章中我们主要讨论了基础的性能调优的方式以及容器化场景中性能调优的难点,在下篇文章中我们会来套路下不同的性能瓶颈现象对应的诊断和调优方法。

Docker中应用的性能调优指南(一)- 先谈谈容器化性能调优的更多相关文章

  1. 《linux性能及调优指南》 3.5 网络瓶颈

    3.5 Network bottlenecks A performance problem in the network subsystem can be the cause of many prob ...

  2. 在Docker中安装和部署MongoDB集群

    此文已由作者袁欢授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 在Docker中安装mongodb 采用的mongodb镜像:https://registry.hub.doc ...

  3. <Linux性能调优指南>主要思路流程

    网上IBM很早放出的一本免费电子书, 十来年了,参考意义还是很大. 国内有翻译成中文在线阅读的版本. 见如下两个URL Linux Performance and Tuning Guidelines ...

  4. Java性能优化权威指南-读书笔记(五)-JVM性能调优-吞吐量

    吞吐量是指,应用程序的TPS: 每秒多少次事务,QPS: 每秒多少次查询等性能指标. 吞吐量调优就是减少垃圾收集器消耗的CPU周期数,从而将更多的CPU周期用于执行应用程序. CMS吞吐调优 CMS包 ...

  5. 《Linux 性能及调优指南》写在后面的话

    感谢飞哥的翻译. 目前飞哥 (http://hi.baidu.com/imlidapeng)的网址已经不能访问了. <Linux 性能及调优指南>这本书的原文地址:http://www.r ...

  6. ElasticSearch中的JVM性能调优

    ElasticSearch中的JVM性能调优 前一段时间被人问了个问题:在使用ES的过程中有没有做过什么JVM调优措施? 在我搭建ES集群过程中,参照important-settings官方文档来的, ...

  7. 调优 | Apache Hudi应用调优指南

    通过Spark作业将数据写入Hudi时,Spark应用的调优技巧也适用于此.如果要提高性能或可靠性,请牢记以下几点. 输入并行性:Hudi对输入进行分区默认并发度为1500,以确保每个Spark分区都 ...

  8. xgboost 参数调优指南

    一.XGBoost的优势 XGBoost算法可以给预测模型带来能力的提升.当我对它的表现有更多了解的时候,当我对它的高准确率背后的原理有更多了解的时候,我发现它具有很多优势: 1 正则化 标准GBDT ...

  9. 直通BAT必考题系列:JVM性能调优的6大步骤,及关键调优参数详解

    JVM内存调优 对JVM内存的系统级的调优主要的目的是减少GC的频率和Full GC的次数. 1.Full GC 会对整个堆进行整理,包括Young.Tenured和Perm.Full GC因为需要对 ...

  10. Spark调优指南

    Spark相关问题 Spark比MR快的原因? 1) Spark的计算结果可以放入内存,支持基于内存的迭代,MR不支持. 2) Spark有DAG有向无环图,可以实现pipeline的计算模式. 3) ...

随机推荐

  1. IM跨平台技术学习(七):得物基于Electron开发客服IM桌面端的技术实践

    本文由得物技术团队Uni分享,即时通讯网收录时有内容修订和排版优化. 一.引言 本文要分享的是得物技术团队基于Electron开发客服IM桌面端的技术实践过程,内容包括桌面技术选型.Electron的 ...

  2. [炼丹术]Yolov8训练使用总结

    Yolov8训练使用总结 Yolov8训练使用总结 介绍 安装 Install pip install ultralytics Development git clone https://github ...

  3. 一站式解决方案 :OFD电子证照生成

    前言 证照的电子化是一个趋势:可以预计,未来几年内,绝大部分证照都会电子化.电子证照的种类越来越多,应用场景也复杂多样:这就给电子证照规范的制定.电子证照的生成提出了更高的要求.电子证照采用的格式有两 ...

  4. CDS标准视图:一次性账户的客户行项目 I_ONETIMEACCOUNTCUSTOMER

    视图名称:一次性账户的客户行项目 视图类型:基础 视图代码: 点击查看代码 @EndUserText.label: 'One-Time Account Data for Customer Items' ...

  5. C#正则表达式匹配候选词

    来自文心一言(多次修改才正确的): public App() { string input = "例子文字{备选,:'词1t324|备选词2gdfg,该方法|备选词3dsfdsf}继续{备选 ...

  6. C# 调用FFmpeg 合并视频和音频

    C#修改环境变量: string pathStr = System.Environment.GetEnvironmentVariable("Path", EnvironmentVa ...

  7. Docker与联合文件系统

    1. 联合文件系统 概念 UnionFS(联合文件系统)是一种分层,轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次次的提交来一层一层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(u ...

  8. Kotlin基础语法

  9. 数组中的常见异常: 1. 数组角标越界的异常:ArrayIndexOutOfBoundsExcetion 2. 空指针异常:NullPointerException

    数组中的常见异常:  1. 数组角标越界的异常:ArrayIndexOutOfBoundsExcetion   2. 空指针异常:NullPointerException package com.ch ...

  10. Rookie Mistake pg walkthrough Intermediate jwt+ssti

    nmap ┌──(root㉿kali)-[~/lab] └─# nmap -p- -A 192.168.189.221 Starting Nmap 7.94SVN ( https://nmap.org ...