首页 > 其他分享 >结合automaxprocs理解cgroups

结合automaxprocs理解cgroups

时间:2024-09-13 15:14:35浏览次数:7  
标签:sys rw cgroups func err fs automaxprocs 理解 cgroup

源码地址

总结

必须使用类似的方法设置容器中的核心数,通过runtime.GOMAXPROCS可能会和容器限制核心数不符
/proc/self下是当前进程的信息
/proc/self/cgroup 当前进程的cgroup信息
如下

11:freezer:/
10:memory:/
9:pids:/
8:blkio:/
7:hugetlb:/
6:devices:/
5:net_prio,net_cls:/
4:cpuset:/
3:cpuacct,cpu:/
2:perf_event:/
1:name=systemd:/user.slice/user-1000.slice/session-25788.scope

/proc/self/mountinfo 当前进程的挂载信息
如下

26 25 0:22 / /sys/fs/cgroup/systemd rw,nosuid,nodev,noexec,relatime shared:9 - cgroup cgroup rw,xattr,release_agent=/usr/lib/systemd/systemd-cgroups-agent,name=systemd
27 18 0:23 / /sys/fs/pstore rw,nosuid,nodev,noexec,relatime shared:20 - pstore pstore rw
28 25 0:24 / /sys/fs/cgroup/perf_event rw,nosuid,nodev,noexec,relatime shared:10 - cgroup cgroup rw,perf_event
29 25 0:25 / /sys/fs/cgroup/cpu,cpuacct rw,nosuid,nodev,noexec,relatime shared:11 - cgroup cgroup rw,cpuacct,cpu
30 25 0:26 / /sys/fs/cgroup/cpuset rw,nosuid,nodev,noexec,relatime shared:12 - cgroup cgroup rw,cpuset
31 25 0:27 / /sys/fs/cgroup/net_cls,net_prio rw,nosuid,nodev,noexec,relatime shared:13 - cgroup cgroup rw,net_prio,net_cls
32 25 0:28 / /sys/fs/cgroup/devices rw,nosuid,nodev,noexec,relatime shared:14 - cgroup cgroup rw,devices
33 25 0:29 / /sys/fs/cgroup/hugetlb rw,nosuid,nodev,noexec,relatime shared:15 - cgroup cgroup rw,hugetlb
34 25 0:30 / /sys/fs/cgroup/blkio rw,nosuid,nodev,noexec,relatime shared:16 - cgroup cgroup rw,blkio
35 25 0:31 / /sys/fs/cgroup/pids rw,nosuid,nodev,noexec,relatime shared:17 - cgroup cgroup rw,pids
36 25 0:32 / /sys/fs/cgroup/memory rw,nosuid,nodev,noexec,relatime shared:18 - cgroup cgroup rw,memory
37 25 0:33 / /sys/fs/cgroup/freezer rw,nosuid,nodev,noexec,relatime shared:19 - cgroup cgroup rw,freezer

根据把/self/proc/cgroup中的路径翻译成/self/proc/mountinfo中的
比如cpu就是/sys/fs/cgroup/cpu

这边需要读取/sys/fs/cgroup/cpu/cpu.cfs_period_us和/sys/fs/cgroup/cpu/cpu.cfs_quota_us

而cfs_quota_us/cfs_period_us就是核数

首先看到使用方式

import _ "go.uber.org/automaxprocs"

func main() {
  // Your application logic here.
}

automaxprocs.go 中

func init() {
    maxprocs.Set(maxprocs.Logger(log.Printf))
}

maxprocs/maxprocs.go中

func Set(opts ...Option) (func(), error) {
    cfg := &config{
        procs:         iruntime.CPUQuotaToGOMAXPROCS,
        minGOMAXPROCS: 1,
    }
    ...
    maxProcs, status, err := cfg.procs(cfg.minGOMAXPROCS)
    if err != nil {
        return undoNoop, err
    }
    ...
}

internal/runtime/cpu_quota_linux.go中

func CPUQuotaToGOMAXPROCS(minValue int) (int, CPUQuotaStatus, error) {
    cgroups, err := cg.NewCGroupsForCurrentProcess()
    ...
    quota, defined, err := cgroups.CPUQuota()
    ...
}

internal/cgroups/cgroups.go中

const (
    _procPathCGroup    = "/proc/self/cgroup"
    _procPathMountInfo = "/proc/self/mountinfo"
)

func NewCGroupsForCurrentProcess() (CGroups, error) {
    return NewCGroups(_procPathMountInfo, _procPathCGroup)
}

func NewCGroups(procPathMountInfo, procPathCGroup string) (CGroups, error) {
    cgroupSubsystems, err := parseCGroupSubsystems(procPathCGroup)
    if err != nil {
        return nil, err
    }

    cgroups := make(CGroups)
    newMountPoint := func(mp *MountPoint) error {
        if mp.FSType != _cgroupFSType {
            return nil
        }
        ...
        cgroupPath, err := mp.Translate(subsys.Name)
        ...
    }

    parseMountInfo(procPathMountInfo, newMountPoint)
}

func (cg CGroups) CPUQuota() (float64, bool, error) {
    cpuCGroup, exists := cg[_cgroupSubsysCPU]
    if !exists {
        return -1, false, nil
    }

    cfsQuotaUs, err := cpuCGroup.readInt(_cgroupCPUCFSQuotaUsParam)
    if defined := cfsQuotaUs > 0; err != nil || !defined {
        return -1, defined, err
    }

    cfsPeriodUs, err := cpuCGroup.readInt(_cgroupCPUCFSPeriodUsParam)
    if err != nil {
        return -1, false, err
    }

    return float64(cfsQuotaUs) / float64(cfsPeriodUs), true, nil
}

internal/cgroups/mountpoint.go中


func NewMountPointFromLine(line string) (*MountPoint, error) {
    ...
}

// parseMountInfo parses procPathMountInfo (usually at `/proc/$PID/mountinfo`)
// and yields parsed *MountPoint into newMountPoint.
func parseMountInfo(procPathMountInfo string, newMountPoint func(*MountPoint) error) error {
    ...
    mountPoint, err := NewMountPointFromLine(scanner.Text())
    newMountPoint(mountPoint)
    ...
}

func (mp *MountPoint) Translate(absPath string) (string, error) {
    ...
    return filepath.Join(mp.MountPoint, relPath), nil
}
// NewCGroup returns a new *CGroup from a given path.
func NewCGroup(path string) *CGroup {
    return &CGroup{path: path}
}

// readInt parses the first line from a cgroup param file as int.
func (cg *CGroup) readInt(param string) (int, error) {
    text, err := cg.readFirstLine(param)
    if err != nil {
        return 0, err
    }
    return strconv.Atoi(text)
}



标签:sys,rw,cgroups,func,err,fs,automaxprocs,理解,cgroup
From: https://www.cnblogs.com/cheyunhua/p/18412228

相关文章

  • 【C++基础概念理解——std::invoke()函数基础知识】
    std::invoke定义std::invoke是C++17引入的一个标准库函数,用于通用地调用可调用对象(如函数指针、成员函数指针、函数对象、lambda表达式等)。它提供了一种统一的方式来调用这些可调用对象,而不需要关心它们的具体类型。功能std::invoke可以调用以下类型的可调用对象:......
  • 深入理解日志轮转:管理日志文件的最佳实践
    日志轮转(LogRotation)是管理日志文件的一种技术。它的主要目的是防止日志文件占用过多磁盘空间,同时保持系统的稳定性和日志的可用性。工作原理日志文件生成:系统或应用程序会生成日志文件,这些文件记录系统运行或应用程序操作的信息。触发条件:日志文件的大小或时间间隔达到预设的......
  • 《深入理解 Java 中的 super 关键字》
    目录一、为什么需要super?二、super的理解及可调用结构(一)super是对父类的引用(二)super调用构造器三、子类对象实例化全过程一、为什么需要super?子类继承父类以后,可能会对父类的方法进行重写。在这种情况下,有时候我们需要在子类中调用父类中被重写的方法。此外,如果子类和......
  • SpringSecurity原理解析(二):认证流程
    1、SpringSecurity认证流程包含哪几个子流程?   1)账号验证   2)密码验证   3)记住我—>Cookie记录   4)登录成功—>页面跳转2、UsernamePasswordAuthenticationFilter   在SpringSecurity中处理认证逻辑是在UsernamePasswordAuthenticationFilter这个过......
  • SpringSecurity原理解析(二):认证流程
    1、SpringSecurity认证流程包含哪几个子流程?   1)账号验证   2)密码验证   3)记住我—>Cookie记录   4)登录成功—>页面跳转2、UsernamePasswordAuthenticationFilter   在SpringSecurity中处理认证逻辑是在UsernamePasswordAuthenticationFilter这个过......
  • E2LLM:长上下文理解与推理的新纪元
    在当今的人工智能研究中,长上下文理解已成为大型语言模型(LLMs)不可或缺的一部分,特别是在多轮对话、代码生成和文档摘要等任务中。随着人们对LLMs能力的期望不断提高,如何有效处理长文本并保持高效性、性能与兼容性之间的平衡,成为了一个备受关注的挑战。为了解决这一“无法实现......
  • 深入理解指针(5)
    1.sizeof和strlen的对⽐在学习操作符的时候,我们学习了sizeof,sizeof计算变量所占内存内存空间⼤⼩的,单位是字节,如果操作数是类型的话,计算的是使⽤类型创建的变量所占内存空间的⼤⼩。sizeof只关注占⽤内存空间的⼤⼩,不在乎内存中存放什么数据。 strlen是C语⾔库函数......
  • GNN图神经网络简单理解
    GNN简单理解文章目录一、GNN图神经网络综述1什么是图1.1图基础1.2图的分类1.3数据成图1.3.1图像转图1.3.2文本转图1.3.3其他转图1.4图结构化数据的问题类型1.4.1图层面任务graph-leveltask1.4.2节点层面任务node-leveltask1.4.3边层面任务edge-leve......
  • C语言深入理解指针六(19)
    文章目录前言一、sizeof&strlensizeofstrlensizeof和strlen的对比二、数组和指针笔试题解析一维数组字符数组二维数组三、指针运算笔试题解析题目1题目2题目3题目4题目5题目6题目7总结前言  本篇都将是练习题,从而让你对指针的理解更上一层楼一、sizeof&s......
  • 系统设计需要理解的延迟数量级
    1ns=10^{-9}s1ms=10^(-6)s1ms=10^(-3)s1ns范围:包括访问cpu寄存器速度,现在cpu的时钟周期1-10ns:包括l1和l2缓存访问一些昂贵的cpu操作如分支错误预测惩罚10-100ns:l3缓存现代cpu的主内存访问100-1000ns:linux系统调用(陷入内核并且直接返回的直接成本),对64位数字进行md5加密1-......