【问题标题】:How do I limit resources for ffmpeg, called from a python-script, running in a docker container?如何限制 ffmpeg 的资源,从 python 脚本调用,在 docker 容器中运行?
【发布时间】:2023-03-14 21:18:01
【问题描述】:

我部署了一项服务,该服务会定期在我的服务器上进行视频编码;每次这样做,所有其他服务都会显着减慢。编码隐藏在多层抽象之下。限制这些层中的任何一层都可以。 (例如,限制 docker-container 与限制 ffmpeg-sub 进程一样有效。)

我的堆栈:

  1. VPS (ubuntu:zesty)
  2. 码头工人撰写
  3. docker-container (ubuntu:zesty)
  4. 蟒蛇
  5. ffmpeg(通过 python 中的 subprocess.check_call())

我想限制什么:

  • CPU:单核
  • 内存:最大 2 GB
  • 硬盘:最大 4 GB

如果需要,可以重新编译 ffmpeg。

在这个堆栈中设置限制的地方是什么?

【问题讨论】:

    标签: python docker ffmpeg resources docker-compose


    【解决方案1】:

    您可以使用 docker compose 文件轻松完成:)

    https://docs.docker.com/compose/compose-file/#resources

    只需使用 limits 关键字并设置您的 CPU 使用率!

    【讨论】:

    • 这似乎只在集群模式下工作(我不知道那是什么,但我只有一个容器,所以这可能不适用)。但显然在第 2 版(撰写 1.14)中,选项 cpu_count 和 mem_limit 似乎可以解决问题:.但我仍然不知道如何限制磁盘空间。
    • 我发现有人设法限制了磁盘空间,您将不得不更改您的 docker 存储驱动程序。我不知道怎么做,但我相信你能找到怎么做:) stackoverflow.com/questions/33013904/…
    【解决方案2】:

    在普通 docker 中,您可以使用命令行选项来实现每个限制:

    一个容器可以限制为单个 CPU 内核(或当前英特尔硬件上的超线程):

    docker run \
      --cpus 1 \
      image
    

    或受限于Dockers CPU shares,默认为 1024。这仅在您的大部分减慢任务也在 Docker 容器中时才有帮助,因此它们也被分配了 Docker 共享。

    docker run \
      --cpu-shares 512 \
      image
    

    Limiting memory 有点挑剔,因为如果达到限制,您的进程就会崩溃。

    docker run \
      --memory-reservation 2000 \
      --memory 2048 \
      --memory-swap 2048 \
      image
    

    Block or Device IO 比性能的总空间更重要。这可能会受到每台设备的限制,因此如果您将数据保存在特定设备上以进行转化:

    docker run \
      --volume /something/on/sda:/conversion \
      --device-read-bps /dev/sda:2mb \
      --device-read-iops /dev/sda:1024 \
      --device-write-bps /dev/sda:2mb \
      --device-write-iops /dev/sda:1024 \
      image 
    

    如果您还想限制总磁盘使用量,则需要correct storage setup。在devicemapperbtrfszfs 存储驱动程序上支持配额,并且在使用pquota 选项挂载的xfs 文件系统上使用overlay2 驱动程序时也支持配额。

    docker run \
       --storage-opt size=120G
       image
    

    撰写/服务

    Docker compose v3 似乎已将其中一些概念抽象为可应用于服务/群的内容,因此您无法获得相同的细粒度控制。

    对于 v3 文件,使用 resources 对象为 cpu 和内存配置 limitsreservations

    services:
      blah:
        image: blah
        deploy:
          resources:
            limits:
              cpu: 1
              memory: 2048M
            reservations:
              memory: 2000M
    

    基于磁盘的限制可能需要支持设置限制的卷驱动程序。

    如果您可以返回到v2.2 Compose file,您可以在服务的基础级别的容器上使用full range of constraints,这类似于docker run 选项:

    cpu_countcpu_percentcpu_sharescpu_quotacpuscpusetmem_limitmemswap_limitmemswap_limitmem_swappinessmem_reservationmem_reservation,@98654352@,@98765435@

    【讨论】:

    • "If you can go back to a v2.2..." 实际上在尝试 V3 时,它告诉 limit-option 仅适用于 swarms(我不知道如何操作)。所以 V2.2 - 技巧就是我要做的。注意:使用 compose
    【解决方案3】:

    我想限制什么:

    CPU:单核

    内存:最大 2 GB

    硬盘:最大 4 GB

    其他答案已经从 docker 的角度解决了这个问题,这实际上可能是您在这种情况下的最佳方法,但这里有一些关于 ffmpeg 的更多见解:

    常规

    没有用于限制 CPU、RAM 和 HDD 的 ffmpeg 选项,您必须了解很多关于转码的知识,才能根据您的要求专门达到指标,并且没有关于输入文件和输出文件的任何信息(s) 不可能给你具体的建议。编码和解码会根据它们来自和去往的地方占用不同的资源。

    CPU

    这里最接近的是 -threads 选项,它将限制使用的线程总数(不是 CPU 内核),或者您可以提供 0 以允许最大线程数。同样,不同的编码器/解码器/编解码器对此有不同的限制。

    内存

    再次失败,这取决于您的媒体和编解码器选择。

    硬盘

    我以前没有这样做过,但是看看这个article。如果这不起作用,您需要对整体输出比特率进行研究,并将其与输入视频持续时间进行比较。 -t 选项可用于根据持续时间限制输出(或限制从输入读取)

    最后

    ...所有其他服务都显着变慢

    这是意料之中的,ffmpeg 尝试尽可能多地占用您机器的资源,因为转码允许,最好的办法是将转码移动到单独的服务器,特别是考虑到它已经在 docker 容器中。

    【讨论】:

      【解决方案4】:

      最好的办法是围绕 cgroup 编写少量脚本;在独立的 linux 上或与 docker 容器一起使用。

      对于前者,基本上是通过创建一个新的cgroup来完成的;为其指定资源并将主进程 pid 移动到创建的 cgroup。详细说明在https://www.cloudsigma.com/manage-docker-resources-with-cgroups/

      对于后者,请参阅https://www.cloudsigma.com/manage-docker-resources-with-cgroups/

      【讨论】:

        猜你喜欢
        • 2021-07-02
        • 2021-03-29
        • 1970-01-01
        • 2022-01-13
        • 1970-01-01
        • 2020-03-23
        • 2020-12-31
        • 1970-01-01
        • 2017-02-21
        相关资源
        最近更新 更多