IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    浅谈Linux ulimit以及max memory locked

    armsword发表于 2016-07-09 14:03:17
    love 0

    刚入职,我在索引这个组,需要熟悉下之前的搜索索引模块的代码,以便后续开发。我在新申请的测试机器上编译代码部署索引这个模块就报错了。定位出现问题的地方,代码大致流程是这样子的:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    if (conf->use_memlock_for_mmap) {
    // add MAP_LOCKED to lock the buffer
    attr_hash = (AttrIndexInfo*)mmap(NULL, fsize, PROT_WRITE | PROT_READ, MAP_SHARED | MAP_LOCKED, fd, 0);
    } else {
    attr_hash = (AttrIndexInfo*)mmap(NULL, fsize, PROT_WRITE | PROT_READ, MAP_SHARED, fd, 0);
    }

    而参数里配置了use_memlock_for_mmap 选项,于是代码就走到第一个mmap逻辑处。

    使用ulimit -a查看下系统属性:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    [armsword@search-querybs1 ~]$ ulimit -a
    core file size (blocks, -c) 4194304
    data seg size (kbytes, -d) unlimited
    scheduling priority (-e) 0
    file size (blocks, -f) unlimited
    pending signals (-i) 256726
    max locked memory (kbytes, -l) 64
    max memory size (kbytes, -m) unlimited
    open files (-n) 1000000
    pipe size (512 bytes, -p) 8
    POSIX message queues (bytes, -q) 819200
    real-time priority (-r) 0
    stack size (kbytes, -s) 10240
    cpu time (seconds, -t) unlimited
    max user processes (-u) 102400
    virtual memory (kbytes, -v) unlimited (注:相当于limits.conf中的as和cgroup中的memory.limit_in_bytes.)
    file locks (-x) unlimited

    我们知道索引程序在启动时候,需要加载倒排/正排等索引原文件,这些文件是比较大的,几十G或者过百G也是可能的,但是系统下的max locked memory对应值是64k,而mmap选项也设置了MAP_LOCKED选项,此选项的意思就是lock一段地址范围内已map的内存,相应的数据在unlock之前一直存在于物理内存中,不会被回收。对于应用程序来说,可以将内存中一些对程序性能影响较大的数据lock起来,避免非预期的页面回收或者换入/换出引起性能波动。所以将max locked memory设置为unlimited就解决问题。

    linux系统提供了以下几个系统调用用于内存的lock和unlock。

    1
    2
    3
    4
    5
    mlock/munlock:lock/unlock一段地址范围内已map的内存
    mlockall/munlockall:lock进程虚拟地址空间内已map的内存,还可以选择对于此后新map的空间是否自动lock
    mmap使用MAP_LOCKED选项时表示在mmap的同时,对相应地址范围进行mlock

    一般情况下,我们使用ulimit多用于提高性能,最常用的地方就是设置打开文件描述符的数量,web服务器等需要大量的文件句柄,一旦开太小,比如默认1024,在句柄使用完毕的时候,系统就频繁出现emfile错误,这时候系统很容易陷入不可用。但是如果设定太大了,又会有这样的副作用。很多服务器程序是事件派遣的,比如说用epoll,程序在启动的时候通常会根据最大的文件句柄数来预留内部的slot,一个slot貌似要占用几K的资源,如果你设定文件句柄数目太大,就可能无端的浪费了几百M内存。所以要设置一个合适的值有利于提高程序性能。

    ulimit 用于限制 shell 启动进程所占用的资源,支持以下各种类型的限制,具体楼上已列出,注意下H/S选项的意义,

    -H 设置硬资源限制,硬资源限制用于控制软限制。限定一旦设置只有root用户可以增加硬限制,普通用户只能减少自己的硬限制大小。
    -S 设置弹性资源限制,弹性限制用于限制具体的用户或者进程。设置后普通用户可以增加,但是不能超过硬限制大小。
    如果不指定-S或者-H,那么弹性资源限制和硬限制将同时设置。

    作为临时限制,ulimit 可以作用于通过使用其命令登录的 shell 会话,在会话终止时便结束限制,并不影响于其他 shell 会话。而对于长期的固定限制,修改 /etc/security/limits.conf 文件即可。



沪ICP备19023445号-2号
友情链接