从automaxprocs库浅窥Linux容器的资源控制
automaxprocs能够自动调整Go程序中的Goroutine数量,以充分利用系统资源并提高程序的性能。
automaxprocs通过读取系统信息,如CPU核心数和Cgroups限制,来动态调整Goroutine的数量
automaxprocs获取CPU限额的关键方法在
// CPUQuotaToGOMAXPROCS converts the CPU quota applied to the calling process
// to a valid GOMAXPROCS value. The quota is converted from float to int using round.
// If round == nil, DefaultRoundFunc is used.
func CPUQuotaToGOMAXPROCS(minValue int, round func(v float64) int) (int, CPUQuotaStatus, error) {if round == nil {round = DefaultRoundFunc}cgroups, err := _newQueryer()if err != nil {return -1, CPUQuotaUndefined, err}quota, defined, err := cgroups.CPUQuota()if !defined || err != nil {return -1, CPUQuotaUndefined, err}maxProcs := round(quota)if minValue > 0 && maxProcs < minValue {return minValue, CPUQuotaMinUsed, nil}return maxProcs, CPUQuotaUsed, nil
}
可以看到是先获取到cgroup的实现,然后调用实现方法获取限制
获取cgroup2实现如下
func newCGroups2From(mountInfoPath, procPathCGroup string) (*CGroups2, error) {// 检查是否是cgroup2// 通过/proc/self/mountinfo中文件系统类型是否为cgroup2或者挂载点在/sys/fs/cgroupisV2, err := isCGroupV2(mountInfoPath)if err != nil {return nil, err}if !isV2 {return nil, ErrNotV2}// 从/proc/self/cgroup解析子系统对应的cgroupsubsystems, err := parseCGroupSubsystems(procPathCGroup)if err != nil {return nil, err}// Find v2 subsystem by looking for the `0` id// 找到v2子系统var v2subsys *CGroupSubsysfor _, subsys := range subsystems {if subsys.ID == 0 {v2subsys = subsysbreak}}if v2subsys == nil {return nil, ErrNotV2}return &CGroups2{mountPoint: _cgroupv2MountPoint,groupPath: v2subsys.Name,cpuMaxFile: _cgroupv2CPUMax,}, nil
}
具体算限制方法如下
其实就是取cpu.max文件中指定的限额
// CPUQuota returns the CPU quota applied with the CPU cgroup2 controller.
// It is a result of reading cpu quota and period from cpu.max file.
// It will return `cpu.max / cpu.period`. If cpu.max is set to max, it returns
// (-1, false, nil)
func (cg *CGroups2) CPUQuota() (float64, bool, error) {// 打开/sys/fs/cgroup下对应cgroup的cpu.max文件cpuMaxParams, err := os.Open(path.Join(cg.mountPoint, cg.groupPath, cg.cpuMaxFile))if err != nil {if os.IsNotExist(err) {return -1, false, nil}return -1, false, err}defer cpuMaxParams.Close()scanner := bufio.NewScanner(cpuMaxParams)if scanner.Scan() {fields := strings.Fields(scanner.Text())if len(fields) == 0 || len(fields) > 2 {return -1, false, fmt.Errorf("invalid format")}if fields[_cgroupv2CPUMaxQuotaIndex] == _cgroupV2CPUMaxQuotaMax {return -1, false, nil}// 解析最大额度max, err := strconv.Atoi(fields[_cgroupv2CPUMaxQuotaIndex])if err != nil {return -1, false, err}var period intif len(fields) == 1 {period = _cgroupV2CPUMaxDefaultPeriod} else {period, err = strconv.Atoi(fields[_cgroupv2CPUMaxPeriodIndex])if err != nil {return -1, false, err}if period == 0 {return -1, false, errors.New("zero value for period is not allowed")}}// 返回限额// 也就是最大额度除以周期return float64(max) / float64(period), true, nil}if err := scanner.Err(); err != nil {return -1, false, err}return 0, false, io.ErrUnexpectedEOF
}
cgroup2了解
cgroup允许对进程进行资源限制与管理,由负责分层组织进程的核心与负责沿层次
cgroup2则引入了更一致的设计和体验
统一层次结构
cgroup2引入统一层次结构,所有子系统(如cpu、memory)都共享同一个层次结构,从而减少了管理的复杂性
也简化了API,统一了配置接口,使其更加易用
基于权重的CPU调度
cgroup2以权重来控制CPU资源的分配。相对的权重越高,则获得的CPU时间越多。
如此,通过权重机制,用户可以很轻松地为不同任务分配 CPU 资源,而无需指定具体的 CPU 配额。这使得 CPU 使用更加灵活,同时调度系统也会根据实际负载动态调整资源分配
更安全的容器子树委派:
cgroup子树委派是将部分资源控制交予非特权用户的方式。
非特权用户可以管理自己子树下的 cgroup 控制器,而不会有权限修改父级或同级 cgroup 的资源控制设置
对内存管理进行更严格控制、记账
- 内核内存和用户内存 的统一管理
- 改进了内存压力下的行为,通过 压力感知提供实时的内存压力监控
内存控制相关文件
- memory.high: 高水位线,超过这个值时,系统会尝试回收内存
- memory.low: 若内存使用率在其有效下限内,则除非可以从不受保护的 cgroup 中回收内存,否则不会回收 cgroup 的内存
- memory.max: 硬性内存限制,超出该值后将触发 OOM
- memory.swap.max: 控制交换区使用的最大内存量。
- memory.current: 实时显示当前 CGroup 使用的内存量
thread mode
在 cgroup v1 中,资源控制一般是基于进程组的,无法对同一进程中的不同线程进行独立的资源控制和隔离
为此在v2中,便支持thread mode,将进程中不同线程分配到不同cgroup中,这意味着可以对单个线程设置 CPU、内存等资源限制
在线程式子树中,只能启用线程式控制器。在线程子树中启用线程控制器时,它仅考虑和控制与 cgroup 及其后代中的线程关联的资源消耗。所有未绑定到特定线程的消费都属于线程域 cgroup。
控制PID
限制某个 CGroup 中允许的进程数量,防止某些容器或进程滥用系统资源
Ref
- https://kubernetes.io/docs/concepts/architecture/cgroups/
- https://github.com/uber-go/automaxprocs
- https://docs.kernel.org/admin-guide/cgroup-v2.html
相关文章:
从automaxprocs库浅窥Linux容器的资源控制
automaxprocs能够自动调整Go程序中的Goroutine数量,以充分利用系统资源并提高程序的性能。 automaxprocs通过读取系统信息,如CPU核心数和Cgroups限制,来动态调整Goroutine的数量 automaxprocs获取CPU限额的关键方法在 // CPUQuotaToGOMAXP…...

AI 读文献(二):综述论文10倍速读和整理
我是娜姐 迪娜学姐 ,一个SCI医学期刊编辑,探索用AI工具提效论文写作和发表。 上一篇娜姐讲了research研究论文的速度框架和效果, AI阅读研究论文,这个方法10倍速提升效率还不损失关键信息! 学员们反馈效果很好&#x…...

【AAOS】Android Automotive 10模拟器源码下载及编译
源码下载 repo init -u https://android.googlesource.com/platform/manifest -b android-10.0.0_r47 repo sync -c --no-tags --no-clone-bundle 源码编译 source build/envsetup.sh lunch aosp_car_x86_64-userdebug make -j8 运行效果 emualtor Cluster Home Map All …...

前端开发攻略---使用css实现滚动吸附效果
实现代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><title>Document</title><style>…...
解析 MySQL 查询优化:提升性能的十个关键策略
1. 避免全表扫描 当查询的数据量非常大时,全表扫描的效率会很低。应尽量通过在WHERE和ORDER BY涉及的列上创建索引,避免全表扫描。索引就像一本书的目录,可以快速定位到需要的数据,而不用从头开始逐页查找。 示例: 如…...

QT--QPushButton设置文本和图标、使能禁能、信号演示
按钮除了可以设置显示文本之外,还可以设置图标 文本 可以获取和设置按钮上显示的文本 // 获取和设置按钮的文本 QString text() const void setText(const QString &text)该属性,既可以在 Qt 设计师右侧的属性窗口中修改,也可以在代码…...

PostgreSQL学习笔记六:模式SCHEMA
模式(Schema) PostgreSQL中的模式(Schema)是一个命名的数据库对象集合,包括表、视图、索引、数据类型、函数、存储过程和操作符等。模式的主要作用是组织和命名空间数据库对象,使得同一个数据库中可以包含…...

基础IO -- 理解文件(1)
目录 一:回顾文件 二:加深对文件的理解 1.概念 2.以w写方式打开 3.以a追加方式打开 4.重定向 一:回顾文件 以前学习过在C语言中的文件操作, 但那根本是不足以理解文件的,即站在语言角度是不可能理解文件的 我们要…...

golang包管理
package 在工程化的Go语言开发项目中,Go语言的源码复用是建立在包(package)基础之上的。本文介绍了Go语言中如何定义包、如何导出包的内容及如何导入其他包。 包与依赖管理 本章学习目标 掌握包的定义和使用掌握init初始化函数的使用掌握…...

outlook 添加企业邮箱账号出现 553 authentication is required 错误解决
系统报错如下 问题原因 发件服务器身份验证设置错误,或者未勾选发送服务器验证的选项。 解决方案 Outlook客户端 本文以Outlook 2016为例,具体操如下: 1、在Outlook客户端的电子邮件设置窗口中,单击其他设置; 2、…...
一个开源可本地部署的英文翻译服务----EnToZhAPI
EnToZhAPI项目简介 项目背景 提供本地化的英文翻译服务API。支持单句翻译请求或者批量翻译请求。支持建立查询词汇表。 项目架构 前端:使用原生js,使用MDB作为CSS框架。django模板引擎渲染可视化界面。 后端:使用waitress作为后端服务器…...
【unity】编辑器扩展——在OnValidate中创建、删除游戏物体
我们知道在OnValidate中创建游戏物体会发出警告,删除游戏物体会报错。 所以我们使用协程,将开始动作的信号放在OnValidate中,将动作的执行放在帧结尾。 参考代码如下: using System.Collections; using UnityEngine;public clas…...
学习记录:js算法(六十四):最后一块石头的重量
文章目录 最后一块石头的重量思路一思路二 最后一块石头的重量 有一堆石头,每块石头的重量都是正整数。 每一回合,从中选出两块 最重的 石头,然后将它们一起粉碎。假设石头的重量分别为 x 和 y,且 x < y。那么粉碎的可能结果如…...
单片机探秘:从理论到应用
单片机探秘:从理论到应用 在这个科技飞速发展的时代,单片机的应用如同一颗璀璨的星星,照亮了我们生活的方方面面。今天,让我们一同深入探讨单片机的原理与应用,揭开这个技术领域的神秘面纱。 1. 单片机概述 1.1 什么…...
options妙用
options妙用 设置默认浏览器为 Chrome options(browser “chrome”) 再次尝试运行 igsva() res <- igsva() 加载 BiocManager library(BiocManager) 设置超时时间 options(timeout 3600) 安装包 BiocManager::install(c(“org.Hs.eg.db”, “org.Mm.eg.db”)) …...

UE5 圆周运动、贝塞尔曲线运动、贝塞尔曲线点
圆周运动 贝塞尔曲线路径运动 蓝图函数库创建贝塞尔曲线点 // Fill out your copyright notice in the Description page of Project Settings.#pragma once#include "CoreMinimal.h" #include "Kismet/BlueprintFunctionLibrary.h" #include "MyB…...
线程局部存储(TLS)
很多时候,我们可能想存储一些线程的私有数据,属于线程的私有变量有局部变量,函数的参数,假如我们要在线程中存储全局变量,多个线程访问都对这个变量有自己的一个副本。 一、隐式实现 __thread int a; //linux __dec…...

JavaSE——集合7:Set接口实现类—TreeSet
目录 一、TreeSet基本介绍 二、TreeSet核心方法 三、TreeSet排序方法 四、TreeSet源码解析 1.无参构造时,底层是创建TreeMap对象 2.有参构造时,底层也创建TreeMap对象 3.执行add方法 4.执行put方法 一、TreeSet基本介绍 TreeSet是 Java 集合框架…...

【idea技巧篇】idea的类注释和方法注释模版自定义设置
这块idea技巧虽然常用,谁没事会经常修改模版设置呢,一般是搭建开发环境的时候或者开发规范要求等设置一次就行了。用的虽然少,但几乎每次搭建环境都会用到,这里记录下并分享设置的过程已经发现的更高级的一些使用技巧。 注释模版…...

【Kubernetes① 基础】一、容器基础
目录 一、进程二、隔离与限制三、容器镜像总结参考书籍 一、进程 容器技术的兴起源于PaaS技术(平台即服务)的普及;Docker公司发布的Docker项目具有里程碑式的意义;Docker项目通过“容器镜像”解决了应用打包这个根本性难题(CloudFoundry)。 容器本身的价…...

ElasticSearch搜索引擎之倒排索引及其底层算法
文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...

让AI看见世界:MCP协议与服务器的工作原理
让AI看见世界:MCP协议与服务器的工作原理 MCP(Model Context Protocol)是一种创新的通信协议,旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天,MCP正成为连接AI与现实世界的重要桥梁。…...
大数据学习(132)-HIve数据分析
🍋🍋大数据学习🍋🍋 🔥系列专栏: 👑哲学语录: 用力所能及,改变世界。 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言Ǵ…...

【从零开始学习JVM | 第四篇】类加载器和双亲委派机制(高频面试题)
前言: 双亲委派机制对于面试这块来说非常重要,在实际开发中也是经常遇见需要打破双亲委派的需求,今天我们一起来探索一下什么是双亲委派机制,在此之前我们先介绍一下类的加载器。 目录 编辑 前言: 类加载器 1. …...
uniapp 集成腾讯云 IM 富媒体消息(地理位置/文件)
UniApp 集成腾讯云 IM 富媒体消息全攻略(地理位置/文件) 一、功能实现原理 腾讯云 IM 通过 消息扩展机制 支持富媒体类型,核心实现方式: 标准消息类型:直接使用 SDK 内置类型(文件、图片等)自…...
华为OD最新机试真题-数组组成的最小数字-OD统一考试(B卷)
题目描述 给定一个整型数组,请从该数组中选择3个元素 组成最小数字并输出 (如果数组长度小于3,则选择数组中所有元素来组成最小数字)。 输入描述 行用半角逗号分割的字符串记录的整型数组,0<数组长度<= 100,0<整数的取值范围<= 10000。 输出描述 由3个元素组成…...

Python训练营-Day26-函数专题1:函数定义与参数
题目1:计算圆的面积 任务: 编写一个名为 calculate_circle_area 的函数,该函数接收圆的半径 radius 作为参数,并返回圆的面积。圆的面积 π * radius (可以使用 math.pi 作为 π 的值)要求:函数接收一个位置参数 radi…...
WEB3全栈开发——面试专业技能点P7前端与链上集成
一、Next.js技术栈 ✅ 概念介绍 Next.js 是一个基于 React 的 服务端渲染(SSR)与静态网站生成(SSG) 框架,由 Vercel 开发。它简化了构建生产级 React 应用的过程,并内置了很多特性: ✅ 文件系…...

Windows电脑能装鸿蒙吗_Windows电脑体验鸿蒙电脑操作系统教程
鸿蒙电脑版操作系统来了,很多小伙伴想体验鸿蒙电脑版操作系统,可惜,鸿蒙系统并不支持你正在使用的传统的电脑来安装。不过可以通过可以使用华为官方提供的虚拟机,来体验大家心心念念的鸿蒙系统啦!注意:虚拟…...
C++核心编程_继承同名成员处理方式
问题:当子类与父类出现同名的成员,如何通过子类对象,访问到子类或父类中同名的数据呢? 访问子类同名成员 直接访问即可 访问父类同名成员 需要加作用域 class Base { public:Base(){m_A 100;}void func(){cout << "B…...