cgroup限制PySpark内存使用

根据业务需求,需要对pyspark内存资源进行限制

本文使用的环境为pyspark 3.1.2,standalone模式

不足之处还请指出

pyspark进程说明

首先我们需要知道对pyspark进行内存限制,是限制哪部分的内存。

先看一下执行pyspark任务需要启动哪些进程

pyspark与原版基于scala的spark启动的进程大体相似但略有不同。

当启动一个pyspark任务时,可以看到产生了2个系列的进程,分别是负责driver和executor

driver:

cgroup限制PySpark内存使用

编号 说明 内存 d1 spark的driver端,spark-submit进程,运行在jvm,启动sparkContext,构建dag等 spark算子在driver端用到的内存,包括collect等 d2 spark的driver端启动的pyspark的driver端,执行python部分代码,通过py4j与
d1

通信 python代码中所用到的内存,包括创建一些变量等

executor:

cgroup限制PySpark内存使用

编号 说明 内存 e1 spark的worker节点 不关注 e2 设备上其他spark任务的executor backend,与本文无关 不关注 e3 本任务对应的spark的executor backend,运行jvm中 spark在executor端使用的内存,包括collect等算子、shuffle等 e4 本任务对应的pyspark的executor backend,管理具体执行task的worker 占用少量内存 e5 具体执行pyspark中的python task的任务的worker,由
e4

fork得到,执行算子中的自定义Python函数等 pyspark在executor端使用的内存,通过python执行,包括map中的func等

可以看到,pyspark任务中,主要需要对4处进行内存限制

  • spark的driver
  • spark的executor
  • pyspark的driver
  • pyspark的executor

后两个是pyspark比spark多出来的。

官方配置

关于spark中的内存,可以关注官方配置文档

其中,重点关注3条配置信息

Property Name
Default Meaning

Since Version spark.driver.memory 1g Amount of memory to use for the driver process, i.e. where SparkContext is initialized, in the same format as JVM memory strings with a size unit suffix (“k”, “m”, “g” or “t”) (e.g. 512m 2g

).

Note:

In client mode, this config must not be set through the SparkConf

directly in your application, because the driver JVM has already started at that point. Instead, please set this through the --driver-memory

command line option or in your default properties file. 1.1.1 spark.executor.memory 1g Amount of memory to use per executor process, in the same format as JVM memory strings with a size unit suffix (“k”, “m”, “g” or “t”) (e.g. 512m 2g

). 0.7.0 spark.executor.pyspark.memory Not set The amount of memory to be allocated to PySpark in each executor, in MiB unless otherwise specified. If set, PySpark memory for an executor will be limited to this amount. If not set, Spark will not limit Python’s memory use and it is up to the application to avoid exceeding the overhead memory space shared with other non-JVM processes. When PySpark is run in YARN or Kubernetes, this memory is added to executor resource requests.

Note:

This feature is dependent on Python’s resource

module; therefore, the behaviors and limitations are inherited. For instance, Windows does not support resource limiting and actual resource is not limited on MacOS. 2.4.0

_spark.driver.memory_和 _spark.executor.memory_这两个参数限制就是 spark端driver和executor的内存,

对需要在jvm中执行的任务进行了很好的限制,

但如上文所述,还需要对 pyspark端的内存进行限制。

pyspark的executor内存限制

_spark.executor.pyspark.memory_这个参数是对pyspark的executor内存进行了限制

根据pyspark中worker.py

set up memory limits
memory_limit_mb = int(os.environ.get('PYSPARK_EXECUTOR_MEMORY_MB', "-1"))
if memory_limit_mb > 0 and has_resource_module:
    total_memory = resource.RLIMIT_AS
    try:
        (soft_limit, hard_limit) = resource.getrlimit(total_memory)
        msg = "Current mem limits: {0} of max {1}\n".format(soft_limit, hard_limit)
        print(msg, file=sys.stderr)

        # convert to bytes
        new_limit = memory_limit_mb * 1024 * 1024

        if soft_limit == resource.RLIM_INFINITY or new_limit < soft_limit:
            msg = "Setting mem limits to {0} of max {1}\n".format(new_limit, new_limit)
            print(msg, file=sys.stderr)
            resource.setrlimit(total_memory, (new_limit, new_limit))

    except (resource.error, OSError, ValueError) as e:
        # not all systems support resource limits, so warn instead of failing
        print("WARN: Failed to set memory limit: {0}\n".format(e), file=sys.stderr)

看到,其实这个参数主要是使用了Python的resource模块进行了内存限制

然而,这里面设置的 _resource.RLIMIT_AS_是对虚拟内存进行限制

我们通常想限制的是驻留内存。

例如一个小测试

import resource
resource.setrlimit(resource.RLIMIT_AS, (1*1024**3, -1))

def fun():
    tmp = []
    for i in range(1024**3):
        try:
            tmp.append('a'*1024)
        except MemoryError:
            break
    return tmp

x = fun(), fun(), fun(), fun()

通过resource.setrlimit限制了1g内存。resource.RLIMIT_AS为虚拟内存的flag,RLIMIT_RSS为驻留内存,但只在老linux内核中生效,现在无法对内核态操作

运行后资源如下

cgroup限制PySpark内存使用

virt达到了限制的1g,但res只有900m。在其他情况下,通常virt远远大于res,这样virt达到了我们限制好的数值,但是res很小,内存远远没得到充分利用,造成资源浪费。

另注:

在standalone模式下,每个worker(e5)限制的virt内存是在application启动时计算好的。通过spark.executor.pyspark.memory 除以 –executor-cores 得到。

(workerMemoryMb =memoryMb / execCores)​

减少每个stage的task个数并不能增加每个worker的virt内存限制大小

pyspark的driver内存限制

pyspark的driver负责执行python流程代码,内存包含Python中创建的各种变量等

spark官方似乎没有参数对这部分内存进行限制

可以自行使用resource模块,对virt内存进行限制

报错信息参考

spark的driver和executor出现oom后,会产生java.lang.OutOfMemoryError: Java heap space报错信息

pyspark的driver和executor出现oom后,产生MemoryError,附有对应python代码

cgroup管理内存

Control groups,是一种Linux内核特性,对进程进行分级分组管理,不同组用不同资源限制并监控。

可以对pyspark的驻留内存进行管理

安装

以centos为例

yum install -y libcgroup libcgroup-tools

分组配置

这里先设置了一个组,用作pyspark的总体控制

再在这个组中设置两个组,分别对driver端的进程和executor的进程进行了限制

/sys/fs/cgroup/memory这个路径是cgroup对memory进行控制的配置,在这里建立对应文件夹来建立具体分组

首先是整体分组

mkdir /sys/fs/cgroup/memory/pyspark

再driver和executor分别建组控制

mkdir /sys/fs/cgroup/memory/pyspark/driver
mkdir /sys/fs/cgroup/memory/pyspark/executor

建组后,cgroup会自动生成一些配置文件,如下图

cgroup限制PySpark内存使用

关于每一项的说明可以参考大佬的文档

在这里主要关注memory.limit_in_bytes和cgroup.procs

memory.limit_in_bytes为当前限制的内存额度。超过额度的话会对相应进程进行kill

可以使用echo重定向对这个进行限制

echo 10g > /sys/fs/cgroup/memory/ai_pyspark/driver/memory.limit_in_bytes
echo 50g > /sys/fs/cgroup/memory/ai_pyspark/executor/memory.limit_in_bytes

则将这个分组的内存限制为10g和50g

cgroup.procs中包含这个分组中的pid

可将spark-submit和worker的pid追加进这个文件,cgroup便将这个进行拉进这个分组进行管理

cgroup限制PySpark内存使用
echo 160224 >> /sys/fs/cgroup/memory/ai_pyspark/driver/cgroup.procs
echo 167910 >> /sys/fs/cgroup/memory/ai_pyspark/executor/cgroup.procs

cgroup会将进程中新产生的子进程自动加入cgroup.procs

例如当产生新的pyspark.daemon时,cgroup会将对应的pid添加到executor分组中

linux系统中每一个进程都有自己的分组,我们没配置分组的进程会在/sys/fs/cgroup/memory分组中,如果想将某个分组中的某个pid移除这个分组,只需将他移动到另一个分组,例如

echo 167910 >> /sys/fs/cgroup/memory/cgroup.procs

另注:

如果executor发生oom,当前spark executor backend进程挂掉,spark会启动一个新的executor backend,不要忘记将新的executor pid再加入cgroup.procs

参考

Spark Configuration

cgroups(7) — Linux manual page

Linux Cgroup系列(04):限制cgroup的内存使用(subsystem之memory)

如何限制python进程的内存使用量 – 酷python的文章 – 知乎

Original: https://www.cnblogs.com/antelx/p/16107238.html
Author: Antel
Title: cgroup限制PySpark内存使用

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/642783/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 测试开发角色定位

    知乎上看到一个很有意思的话题: 测试开发是代表 “懂测试的开发” 还是”懂开发的测试”? 这是个很有意思的话题: 我一开始画了这么一…

    技术杂谈 2023年5月31日
    072
  • Java8 日期时间API

    一、转换 1、转字符串 1.1、LocalDateTime与字符串 //LocalDateTime 转 字符串 String str = DateTimeFormatter.ofP…

    技术杂谈 2023年7月11日
    077
  • 天空卫士陆明:数据法在企业如何落地

    导读:数据安全立法2018年9月于十三届全国人大常委会列入立法规划。经过三次审议,在2021年6月10日,十三届全国人大常委会第二十九次会议正式表决通过,并于2021年9月1日起施…

    技术杂谈 2023年7月25日
    076
  • [Python]-tqdm模块-给for循环加上进度条

    import tqdm 使用tqdm模块,可以在漫长的for循环加上一个进度条,显示当前进度百分比。 将tqdm写在迭代器之外即可: tqdm(iterator) for i in…

    技术杂谈 2023年7月10日
    078
  • 关于大衍求一术的一个延拓

    今天是一个明朗的日子,心情闲暇,于是,研究了一下我国的算术,我国的算术其实是非常博大精深的,只是由于某些偶然原因,我国算术没能发展起来,否则,现代算术中心必在东方之华夏,在我的印记…

    技术杂谈 2023年5月31日
    095
  • njoj 1251 zlly长了一张包子脸

    njoj 1251 zlly长了一张包子脸 题意: zlly长了一张包子脸。他特别喜欢吃糖果。如今他手头有若干种糖果,每种糖果有个口味值,每种糖果有无数多个。然后娄童鞋也很喜欢吃糖…

    技术杂谈 2023年5月30日
    0106
  • PyTorch 介绍 | TENSORS

    Tensor是一种特殊的数据结构,非常类似于数组和矩阵。在PyTorch中,我们使用tensor编码模型的输入和输出,以及模型的参数。 Tensor类似于Numpy的ndarray…

    技术杂谈 2023年7月25日
    070
  • 寿司店问题 PV操作 pthread表示

    寿司店问题。假设一个寿司店有 5 个座位,如果你到达的时候有一个空座位,你可以立刻就坐。但是如果你到达的时候 5 个座位都是满的有人已经就坐,这就意味着这些人都是一起来吃饭的,那么…

    技术杂谈 2023年7月25日
    073
  • Mac 睡眠唤醒 不睡眠 问题

    问题 之前一直有夜晚睡觉前电脑💻关机的习惯,主要是想着电脑也跟人一样♨️要休息😂。然后最近想着自己 Mac 干脆每天睡眠💤算了,省得每天开关机麻烦,所以就最近这段时间每次夜晚睡觉前…

    技术杂谈 2023年7月11日
    0110
  • centos7安装zabbix-agent客户端

    1.官方下载zabbix-agent安装包链接:wget https://cdn.zabbix.com/zabbix/binaries/stable/5.4/5.4.6/zabbi…

    技术杂谈 2023年7月10日
    061
  • ord chr 字符串切片 字母转数字

    func CharToASCII(a string) int { return int(a[0]) } func ByteToASCII(a byte) int { return …

    技术杂谈 2023年5月31日
    083
  • 【主流技术】ElasticSearch 在 Spring 项目中的实践

    前言 ElasticSearch简称es,是一个开源的高扩展的分布式全文检索引擎。 它可以近乎实时的存储、检索数据,其扩展性很好,ElasticSearch是企业级应用中较为常见的…

    技术杂谈 2023年7月10日
    087
  • 数据科学、数据工程学习路线

    大家见过这张图吗? Swami Chandrasekaran在2013年用地铁图来描述如何通过”一段旅程”来成为数据科学家 (链接:http://nirva…

    技术杂谈 2023年7月25日
    079
  • 谈谈Raft

    本文主要参考: 极客时间-etcd 实战课 GitChat-分布式锁的最佳实践之:基于 Etcd 的分布式锁 谈到分布式协调组件,我们第一个想到的应该是大名鼎鼎的Zookeeper…

    技术杂谈 2023年7月25日
    085
  • 建造者模式详解

    建造者模式详解 1.1 建造者模式概述 1.1.1 定义 建造者模式(Builder Pattern)将一个复杂对象的构建过程与它的表示分离,使得同样的构建过程可以创建不同的表示,…

    技术杂谈 2023年6月21日
    078
  • Python实践项目2

    #南昌理工学院人工智能学院实验室WORKSHOP实践项目 import time import random SCRIPT_NPC_SCHOOL_SISTER = [‘你好!’, …

    技术杂谈 2023年6月21日
    0102
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球