
vivo 容器集群监控系统优化之道
2023-08-17 08:37:05本文介绍了vivo容器团队基于 Prometheus等云原生监控生态来构建的容器集群监控体系,在业务接入容器监控的过程中遇到的挑战、困难,并分享了相应的应对策略和优化方案。
一、背景介绍
随着vivo业务迁移到容器平台,vivo云原生监控体系面临着指标量快速上涨带来的一系列挑战,本文将分享vivo 容器化项目中容器监控遇到的问题以及我们的解决和优化方法。
二、监控架构
首先对vivo容器监控架构进行一个简单的介绍。
原生Prometheus没有提供高可用的标准方案,我们通过自研 Adapter “分组选举”方式实现去重,即每个 Prometheus 副本对应一组 Adapter,两组 Adapter 之间会进行选主,只有Leader组的 Adapter才会转发数据。通过这种方式既实现了去重,也实现了Prometheus双副本高可用。
三、问题现象
过去几年来,vivo容器化服务快速增长,监控流量上涨数倍,我们主要遇到如下三个问题: 监控组件负载快速升高、容器监控数据断点和数据存储组件负载陡增 。
3.1 监控组件负载快速升高
容器化每次部署IP都会变化的特性,导致容器监控指标量相比物理机和虚拟机要高出好几个数量级。同时由于集群规模的不断增加以及业务的快速增长,导致监控 Prometheus、VictoriaMetrics 负载快速增高,给我们容器监控带来极大的挑战。监控总时间序列可以精简为以下的表达式,即与 Pod数量、Pod指标量、指标Label维度数量 呈线性关系:
TotalSeries = PodNum * PerPodMetrics * PerLabelCount
而随着集群规模的不断增加以及容器数量的不断增多,监控序列就会快速增长,同时监控组件负载快速升高,会对容器监控系统的稳定性产生影响。
vivo容器层面(业务)的监控数据则通过自研Adapter转发给Kafka,进而存储到公司基础监控做业务监控展示和告警配置,同时也存储一份到Druid做更多维度的统计报表。我们在推送监控数据的时候发现,Pod维度的指标难以保证发送频率,即配置指标采集频率为 10s,但是在推送的数据中频率无法做到10s,且会有波动。下图为 采集频率设置 10s,查询1分钟的指标数据。
一分钟内某一容器的 conTainer_cpu_user_seconds_total 指标的值:
可以看到只取到了4个值,与期望的 6个值不相符,即发生了“掉点”的情况,监控面板按指定频率展示数据会有频繁掉0现象。
3.3 数据存储组件负载陡增
vivo容器监控使用 VictoriaMetrics的v1.59.1-cluster版本做为后端时序数据库来持久化存储监控数据。在使用过程中发现 VictoriaMetrics的负载有不定期增高的情况,而后端数据库的延迟会导致监控查询告警功能的异常影响用户体验。
四、解法
4.1 监控组件负载快速升高
我们使用 Prometheus-Operator 管理 Prometheus,因为优化方案中有 Prometheus-Operator 相关的名词,故为了下面的理解,先对 Prometheus-Operator 做一个介绍:
上图是Prometheus-Operator官方提供的架构图,下面来介绍下图中各组件:
我们重点关注 ServiceMonitor,因为ServiceMonitor为我们提供了指定 target 采集的配置,例如采集频率,target内指标过滤,指标中label重命名等等操作。
对于监控组件负载快速升高问题的解决,我们主要从两个方面着手,分别是 指标治理 以及 性能优化 。
4.1.1 指标治理
1、过滤未使用指标
第一个工作 是过滤无用指标,Prometheus 会去从 Target 中去获取指标数据。每个 Target 下会有多个 endponit。每一个endpoint 又会提供几十上百个指标,而每个指标下的数据量也很大。但在生产环境中我们实际上用到的指标可能只有几十个,Prometheus采集过来我们又没有用到的指标就会浪费资源并降低监控系统的稳定性。因此我们需要对Prometheus 采集到的指标进行一定程度的过滤,从而减少资源的占用。
通过Prometheus提供的
scrape_samples_scraped指标对采集的 target进行分析找到采集样本量大的Target。
我们进行指标过滤主要就是关注这些数据量大的 target,在进行指标过滤之前需要收集 Prometheus所采集的所有指标数据以及当前监控告警面板以及相关依赖服务所使用到的指标。再根据采集的指标和正在使用的指标进行正则表达式的书写。最终在对应 target的 ServiceMonitor将正则表达式写入。Prometheus则会过滤掉我们不需要的指标。下面就是过滤 cAdvisor这个 target 的 container_threads 开头的指标的示例。
# 过滤container_threads开头的指标- action: dropregex: container_threads(.*)sourceLabels:- __name__
完成指标精简后,监控单次采集样本量从 1000万降低到 250万。Prometheus 的CPU 使用量降低 70% ,内存 使用量降低 55%。
2、过滤低优先级 pod 相关指标
对精简后的指标进行分析,发现 Pod维度的监控指标占比为70%,且有相当比例的 Pod 是集群组件的 Daemonset的Pod。而Daemonset的Pod是随着集群规模的增加而增加的。
而对于大部分的集群组件Daemonset,因为设置了资源上限,我们不需要关注其资源消耗情况,只需要关注是否存活和正常提供服务即可。故可以对这部分 Pod 的指标进行一个精简,不收集这些 Pod的 memory、cpu 等容器监控指标。
一个 Daemonset 提供的 Pod 的 Namespace 是相同的,且Pod名称前缀相同。
# 名称为cadvisor的 daemonset 提供的 podcadvisor-xxxx11/1Runningcadvisor-xxxx21/1Running
且提供的指标中包含了 namespace 和 pod 的 label。
container_memory_cache{cnotallow="POD", namespace="monitoring", pod="kube-state-metrics-xxxx-xxxx", service="cadvisor"}
所以我们通过在 ServiceMonitor 上面组合指标的 pod 和 namespace,并与指定的规则进行匹配丢弃掉我们不需要的 daemonset pod 的序列。
# 过滤掉 monitoring namespace 下面 telegraf 这个daemosnet提供的 pod 的相关指标- action: dropregex: monitoring@telegraf(.*)separator: '@'sourceLabels:- namespace- pod
在对集群中部分ds Pod 的指标进行过滤后。
对的单次采集数据量下降 70%。效果十分明显。
4.1.2 性能优化
1、均衡 Prometheus 负载
vivo 容器监控架构中最核心的组件就是 Prometheus了,而 Prometheus 也是日常出现问题最多的一个组件,因为 Prometheus 不仅是需要采集数据,还需要将数据通过remote_write的方式推送的VictoriaMetrics 和 Kafka中。
将监控 target 进行分类交由不同的组 Prometheus 采集,且每类 Prometheus 为双副本模式。随着集群规模的增加,发现当前模式的不合理之处,即因为Pod维度监控数据量级十分高,导致container 类型 Prometheus 负载远远高于其他类型的 Prometheus。在高负载的情况下面会发生重启,remote_write 异常等情况。
我们 Prometheus组件架构为按类型采集监控指标。其中 Container类型的 Prometheus采集的指标数量远远大于 Component、Host、Resource类型。故需要手动平衡 集群中 Prometheus的负载 将集群的 container类型 Prometheus上面kubelet 和 kube-state-metrics 转移到 resource-Prometheus 上面 降低 container-Prometheus负载。(与此同时resource-Prometheus也会发送到 kafka-adapter)。且在负载低的Prometheus上 监控跳转面板用到的监控指标(核心指标)进行重复采集,尽可能防止数据丢失。降低了container-Prometheus 40%的负,极大的减少了Prometheus异常情况的发生。
2、减少Prometheus存储数据时间
我们的第2个修改点在 Prometheus的数据存储时间上,Prometheus的默认存储时间为2周,后续测试发现 Prometheus的存储数据时间对内存的影响很大,且现在监控数据的持久化存储都放在 VictoriaMetrics 上面,Prometheus存储的数据主要用于排查问题,不需要承担持久化存储的任务。故我们修改Prometheus采集的数据本地存储时间从7天改为2天。Prometheus 内存消耗降低 40%。
4.2.1 问题定位
最初我们认为是 Prometheus 在remote_write 的过程中发生了丢点的情况,但是通过在社区查询和配置问题Prometheus 远程写相关的监控指标发现Prometheus并没有在远程写的时候丢弃数据,且发现在推送数据的过程中只有kubelet 内置的提供的数据有”丢点”的情况。故我们开始研究指标提供端组件,发现”丢点”问题的原因在于组件有自己的刷新频率 和 时间戳。会去 cgroup 中读取数据并存储到内存中供外部使用。Kubelet的的刷新数据频率达不到 10s,并且会根据刷新时间放到指标中。而 Prometheus 按 10s 采集频率去采集数据时,底层的如果还没有去刷新数据,内存中则还是上次的数据。而在0.31版本及之后的版本中添加了时间戳支持,即 cadvisor 提供的数据会带上自己的时间戳。当 Prometheus 去采集 cadviosr数据时会以提供的时间戳为准。故当 Prometheus 按照ServiceMonitor 设置的采集频率10s去采集cAdvisor 提供的数据时,如果在此期间 cAdvisor 没有进行数据更新,则Prometheus会采集到与上次采集时间戳和值相同的情况,Prometheus 就只会记录一条数据。这就是“丢点”的本质。的刷新频率由 housekeeping相关参数 和 抖动 机制确定。
kubelet 内置设置的参数:
// Kubelet 内置 cadvisor 默认参数// cadvisor housekeeping 的间隔,刷新数据的间隔const defaultHousekeepingInterval = 10 * time.Second// cadvisor 是否开启动态 housekeepingconst allowDynamicHousekeeping = true/*cadvisor housekeeping 的最大间隔,allow_dynamic_housekeeping=true的时候, 会判断容器活跃程度动态的调整 HousekeepingInterval, 当发现一段时间为容器状态为发生改变会将 housekeeping 的间隔 设置为maxHousekeepingInterval 。*/const maxHousekeepingInterval = 15 * time.Second
4.2.2 解决方案
根据上面的分析,定位到无法保证指标频率的根本原因在于的默认启动参数,而目前我们采集的是内置于 kubelet 中的,如果要修改参数的话需要改动 kubelet。故综合考虑集群稳定性和维护成本等因素,我们决定以 daemonset 的方式部署一套,并根据需求设置 housekeeping 相关的参数来保证刷新数据的频率,并设置 Prometheus 采集数据的时候忽略自带的时间戳,即通过单独部署的提供Pod的监控数据并保证监控数据的频率。
我们的工作主要在部署和 修改对应的 ServiceMonitor。
1、部署 :主要是确定启动参数, 主要操作为禁用dynamic_housekeeping 和 设置 housekeeping_interval 为 1s,来保证获取数据的频率。
containers:// 参数设置- -allow_dynamic_housekeeping=false- -housekeeping_interval=1s
2、创建对应的ServiceMonitor 让让Prometheus 忽略cadviosr自带的时间戳。(因为 cadviosr自身的抖动机制,频率无法固定)
的抖动机制:
// return jitter(cd.housekeepingInterval, 1.0)func jitter(duration time.Duration, maxFactor float64) time.Duration {if maxFactor <= 0.0 {maxFactor = 1.0}wait := duration + time.Duration(rand.Float64()*maxFactor*float64(duration))return wait}
的 ServiceMonitor上配置忽略指标自带时间戳
通过单独部署的和 Prometheus 的忽略自带的时间戳,我们成功的解决了容器监控断点的问题,保证了监控的频率。
spec:endpoints:- honorLabels: true// 忽略时间戳honorTimestamps: falseinterval: 10s
可以看到再去采集 1分钟内的容器相关监控数据,是很标准的 6 个数据点。至此监控“掉点”问题解决。
监控面板展示数据连续,无中断现象发生。
4.3.1 问题定位
从监控架构图可以看到,我们使用社区 v1.59.1-cluster版本的VictoriaMetrics 作为监控后端的时序数据库,并在Prometheus 采集的数据后通过remote_write写入到时序数据库VictoriaMetrics中进行持久化存储,Grafana会从VictoriaMetrics 读取数据展示在对应的 Dashboard上面。而在我们的实际使用中发现,Prometheus 远程写入VictoriaMetrics有不定期延迟飙升的现象。
Prometheus写入VictoriaMetrics延迟
写入数据库延迟的飙升会导致,监控面板展示延时、监控误告警等一系列问题。
我们对 VictoriaMetrics的详细指标进行分析。发现 vmstorage 组件在底层执行 indexdb merge 操作的时候,其 CPU、内存等资源使用量会有一个突增, 即indexdb 的 Merge 操作非常消耗资源。
4.3.2 解决方案
正是由于VictoriaMetrics 这些的资源突增,导致自己负载过高,无法正常响应 Prometheus的 remote_write的数据。我们所期望的是在 indexdb merge 的时候,资源使用量的增长不会影响到正常的数据插入和查询。经过查询相关资源得到VictoriaMetrics在1.73.0版本中对indexdb的 merge进行优化,提升了整体性能。故我们对VictoriaMetrics 进行了版本升级以优化这个问题。在版本升级后,未发现 VictoriaMetrics 在indexdb merge时有资源突增的情况发生。
五、总结
在Kubernetes大规模使用的今天,以 Prometheus 为核心的监控系统已成为云原生监控领域的事实标准。原生Prometheus没有提供高可用和持久化存储的标准方案,vivo通过自研adapter实现了Prometheus双副本高可用,并将数据写入到VictoriaMetrics中实现了数据的持久化存储。而在业务规模的增长的过程中,监控数据量也在快速增长,对监控采集和存储组件都带来了不小的压力,当前我们通过降低数据提供端指标数量、优化采集组件参数、升级开源存储组件版本的方式,提升了监控系统的性能。
而架构的演变是随着业务规模的增长而不断的演变改进的,未来我们将结合业务实际规模优化监控架构提升容器监控整体性能。后续我们规划在监控采集、监控查询、监控数据提供三个方向继续提升提供系统性能:
vivo手机如何显示瞬时流量
您好! 进入I管家-流量监控-设置-状态栏显示网速开启即可,原系统手机管家-流量监控-设置-流量实时监控窗口开启即可如果还有什么疑问欢迎随时来咨询,我们将尽力为您解答。 感谢您的来访,祝您生活愉快!如果有任何问题可以随时来咨询我们的。 非常感谢您对我们vivo的支持,祝您生活愉快!
vivo另一摄像头已损坏,无法切换,和软件有关系吗?
建议尝试以下方法解决:1、重启手机后再开启相机使用;2、进入手机设置--更多设置--应用程序--全部--找到相机清除数据和缓存;3、进入设置--系统更新--下载最新系统版本安装;4、进入手机设置--更多设置--恢复出厂设置--还原所有设置--此操作是不会丢失数据的。 如果按照以上方法操作了还是无法解决,可以去当地的售后服务中心检测处理,进入vivo官网--服务--服务网点查询--查询距离最近的售后地址。
分屏多任务是哪个键?
方法一:1.打开“设置,通用, 辅助功能, AssistiveTouch。 2. 打开AssistiveTouch ,设备, 更多, 多任务。 方法二:双击home键。 分屏如我们所知道的,vivo手机现在有分屏功能,所谓分屏就是,一个屏幕上显示出本来应该几个页面的内容,即几个页面拼接同事出现在同一页面,同时不影响各自的功能。 1浏览器浏览器的浏览模式之一,可以在电脑的一个窗口上同时浏览两个页面,十分方便,例如遨游就有这个功能2数分屏数是多屏显示卡最重要的一个指标,它表示一个多屏显示卡最多可以连接的显示器数目。 多屏显示卡的分屏不是简单的多个显示器显示多个相同内容,而是多个屏幕上显示各自不同的画面,并可显示拼接的组合大画面。 比如分屏数为4的多屏显示卡可以连接4台显示器,既可以让这4台显示器分别显示画面的一部分,一起组成一副画面,也可以让这4台显示器各自显示不同的画面。 一般多屏显示卡的分屏数是2个或者4个,如果需要连接更多的显示器,可以在一台计算机上连接多个多屏显示卡3多屏显示多屏显示卡是专为今天的PC机更深层的应用要求而设计的高性能的多屏卡。 它使一台PC机支持多台VGA显示器、电视机或DVI数字平面显示器,它是专为当今图形图像应用而设计的,特别是在windows下进行多种运行参数开发设计、编辑、控制、多媒体。 多屏显示卡并不是简单的多个显示器显示多个相同内容,而是多个屏幕上显示各自不同的画面,并可显示拼接的组合大画面。 比如分屏数为4的多屏显示卡可以连接4台显示器,既可以让这4台显示器分别显示画面的一部分,一起组成一副画面,也可以让这4台显示器各自显示不同的画面。 鼠标及窗口还可以在各个屏幕间漫游移动,而无需软件的任何改动。 多屏显示卡广泛应用于:监控、指挥、调度系统;公安、消防、军事、气象、铁路、航空等监控系统中;视讯会议、查询系统等。
发表评论