zoukankan      html  css  js  c++  java
  • Erlang C1500K长连接推送服务-内存

    上篇 Erlang C1500K长连接推送服务-性能 提到:150w连接,使用了23GB内存,每个连接占用15KB,约一半是内核使用。

    大概分析一下:

    1. Erlang 节点

      12GB,内部因为有内存池碎片问题,实际使用9GB,也就是实际每个进程+Port占用越6K,因为采用hibernate策略,已经没水分了。

    2. linux内核

      11GB,通过运行前后, cat /proc/meminfo 中 MemTotal - AnonPages 值的增加量基本就是内核占用。

      实际Slab: 5388732 kB,只有5GB,另外6GB上哪儿去了?。。。

      slabtop:  

     Active / Total Objects (% used)    : 9821361 / 9912211 (99.1%)
     Active / Total Slabs (% used)      : 967448 / 967448 (100.0%)
     Active / Total Caches (% used)     : 91 / 174 (52.3%)
     Active / Total Size (% used)       : 4664151.73K / 4676348.50K (99.7%)
     Minimum / Average / Maximum Object : 0.02K / 0.47K / 4096.00K
    
      OBJS ACTIVE  USE OBJ SIZE  SLABS OBJ/SLAB CACHE SIZE NAME
    1500136 1500097  99%    1.69K 375034        4   3000272K TCP
    1500330 1500268  99%    0.69K 300066        5   1200264K sock_inode_cache
    1808780 1808377  99%    0.19K  90439       20    361756K dentry
    1501840 1501054  99%    0.19K  75092       20    300368K filp
    1529370 1501237  98%    0.12K  50979       30    203916K eventpoll_epi
    1529474 1501153  98%    0.07K  28858       53    115432K eventpoll_pwq
    116030 113558  97%    0.78K  23206      5     92824K ext3_inode_cache
     30560  30538  99%    1.00K   7640        4     30560K ext4_inode_cache

     TCP 内存使用

      参考:

      1.  高性能网络编程7--tcp连接的内存使用

      2. 内核协议栈tcp层的内存管理

       配置示例:

    net.ipv4.tcp_mem=1523712 2031616 3047424  tcp 总内存限制,单位页(low pressure high)

    net.ipv4.tcp_rmem = 8192 87380 8738000 单个连接的接收buff (min, default, max)

    net.ipv4.tcp_wmem = 4096 65536 6553600 单个连接的发送buffer(min, default, max)

    net.ipv4.tcp_adv_win_scale = 2 也就是1/4 的buffer 会被用于存放应用数据

       设置buffer大小

       - 默认对于单个连接buffer 都是动态分配的,max 限制最大buffer

       - 网关不要使用SO_SNDBUF, SO_RECVBUF 限制设置,会导致buffer 预留,而不是动态分配,造成内存浪费

       - 关闭应用层封装buffer,不少IO库应用层都有buffer,应关闭减少不必要copy和内存浪费

      控制内存

       测试环境没网络畅通,而实际生产环境复杂多样,尤其移动终端。网络拥挤、攻击容易会使得服务实际内存消耗会更大。

       设备需要配备更高内存,并且做好流控:

      1. 接收

        一般来说只要包不是太小,现在应用使用CPU单核心都能跑满KM网卡,对于网关应用而言,CPU不应该是瓶颈。

        也就是客户端发多快,应用就能收多快。

        gen_tcp {active, true}

      2. 发送

        因为环境多变,下行链路,移动设备网络状况,拥塞是不可避免的,所以需要控制发送buff内存。

        - 内核

          上面提到3个参数,根据系统内存,合理配置,至少保证内核buffer满时应用还有内存可用

        - 应用

          设置 gen_tcp {recbuf, 0}, {sndbuf, 0}, {send_timeout, 5000} 设置buffer=0 保证不会在应用层buffer堆积过多的包,

        send_timeout 后,说明此连接从此拥塞,失败后如果发现后续很多包,且应用内存过高,可选择丢弃部分。

          就像再windows 平台IOCP下,send 永远是无阻塞成功,对方拥塞也能一直发下去直到OOM,需要通过回调维护未写入tcp buffer的packet 长度,超过一定时采用丢弃策略。

  • 相关阅读:
    [To be translated] Nova:libvirt image 的生命周期
    Neutron 理解(5):Neutron 是如何向 Nova 虚机分配固定IP地址的 (How Neutron Allocates Fixed IPs to Nova Instance)
    Cinder 调试
    SSH 无密码访问其它机器 和 Windows 上 putty 无密码访问 Linux 机器
    Hadoop 数据库
    Hadoop 分布式文件系统
    C++ 在继承中虚函数、纯虚函数、普通函数,三者的区别
    Google Scholar 论文参考文献的自动生成
    Linux shell ${}简单用法
    C/C++ 获取目录下的文件列表信息
  • 原文地址:https://www.cnblogs.com/lulu/p/4132374.html
Copyright © 2011-2022 走看看