【问题标题】:How to assign a "memory priority" to a linux process?如何为linux进程分配“内存优先级”?
【发布时间】:2014-08-20 12:25:48
【问题描述】:

我在一个小型 OpenWRT 路由器上运行 tor,由于可用内存有限 (32mb),交换无法避免。

大多数时候路由器不做任何其他事情,但是有时会访问也在路由器上运行的 postgresql 数据库。由于tor不断运行,postgresql被完全换出,前几次访问延迟非常高,这很糟糕,因为它是一个交互使用的系统。

我已经为 postgres 分配了一个不错的值 -15,为 tor 分配了 +15,但它似乎对内存管理影响不大。全局设置 swappiness=1 也不会改变任何事情,因为交换是无法避免的,而且由于 postgresql 大部分时间都没有运行,所以无论如何它都会被交换出去。

有没有办法让 Linux 进程的内存优先级之类的东西? 我查看了 cgroup 特定的 swappiness,但我发现的唯一描述是它影响决策页面缓存与交换。

我正在寻找的是一个参数来告诉 linux 内核不要像其他进程那样积极地换出 postgresql(但我不想锁定整个进程)。 或者为 postgresql 分配 swappiness=80 系统范围和 swapiness=1 会将 postgresql 保留在内存中,同时在需要时换出其他所有内容?

【问题讨论】:

    标签: linux memory-management swap cgroups


    【解决方案1】:

    严格来说,在 Linux 中,您无法阻止进程换出。 您可以完全避免使用 swapoff -a 进行交换(并添加一些 RAM),但这会导致系统不稳定。

    但在这种情况下,Linux 做得很好:“不时”使用的进程必须换掉,无论您有多少空闲 RAM。也许您使用了错误的配置。你能把 postgres 放在另一台主机上,也许用更快的硬盘?

    顺便说一句:如果你想防止在当前配置中换出 postgres 进程,我认为你可以尝试使用类似 keep alive 的东西:让守护进程(或简单的 bash 脚本)定期发送一些查询让系统看到进程处于活动状态。

    I.E.你可以这样做:

    #!/bin/bash
    DBHOST=localhost
    DBPORT=5432
    DBNAME=theDBname
    DBUSER=theUserName
    THEQUERY="SELECT 1"
    
    psql -h $DBHOST -p $DBPORT -d $DBNAME -U $DBUSER  -c "$THEQUERY"
    

    让 cron 每分钟左右调用一次。

    如果你想要更复杂的东西,你可以创建一个守护进程来发送一些“真实”的查询并缓存结果,这样 postgres 就可以在你已经缓存结果的时候换掉。

    【讨论】:

    • > 严格来说,在 Linux 中你无法阻止进程换出......你可以,只需调用 mlock 并使用正确的参数,进程就会被固定在内存中。感谢守护进程的想法——这就是我目前所做的,导致 postgres 被定期换入/换出。我想要实现的是 postgresql 的优先级低于其他进程。
    • 是的,你可以使用 mlock,但在这种情况下你必须修改 postgres 源代码,这不是一件容易的事。
    【解决方案2】:

    我认为您应该做的是将 PostgreSQL 配置为使用更少的内存。它使用大量内存来尝试提高性能,但在您的情况下它不起作用。您的 OpenWRT PostgreSQL 安装的默认配置大概已经从其大量的正常默认值中减少了它的内存占用,但看起来您需要更进一步。

    PostgreSQL documentation 列出了许多影响其资源使用的选项。

    如果 StefanoF 和 Basile Starynkevitch 提出的其他建议将 PostgreSQL 服务器移动到另一台机器或使用更高效的数据库(如 sqlite)比试图将交换性能从绝对糟糕提高到仅仅糟糕更好的解决方案。

    【讨论】:

      【解决方案3】:

      您可能会在您的程序(可能是 Postgresql)中使用mlock(2),更可能使用madvise(2)

      但是,我认为 Postgresql(或 Mysql)对于 32 MB RAM 系统来说太大了。你考虑过sqlite 吗?它是一个(不是服务器),您可以将其链接到您的应用程序,并且您可以使用它对本地 sqlite 文件(充当数据库)执行 SQL“请求”。当然,您可能需要让您的应用程序能够通过 Web 进行交互(例如,使用 FASTCGI 或使用一些 HTTP 服务器库,如 libonion)。

      也许ionice(1) 可能是相关的(但我猜不是)。

      【讨论】:

      • sqlite 是什么意思?据我所知,sqlite 不运行守护进程,也不提供 tcp/ip。
      猜你喜欢
      • 1970-01-01
      • 2023-04-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-25
      • 2023-04-08
      • 1970-01-01
      • 1970-01-01
      • 2012-09-24
      相关资源
      最近更新 更多