V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
kmdd33
V2EX  ›  问与答

请问后端和运维小伙伴们,你们都是如何优化 centos 服务器的内存?

  •  
  •   kmdd33 · 2017-02-26 13:35:04 +08:00 via iPad · 5675 次点击
    这是一个创建于 2862 天前的主题,其中的信息可能已经有所发展或是发生改变。

    请问后端和运维小伙伴们,你们都是如何优化 centos 服务器的内存?自己的小博客放在 vps 上, centos , lnmp 环境,每天也就不到 10 个人访问,内存已经被占用了 400mb 了,怎么办?有没有一些实用的方法把一些不用的功能给关闭掉,大家又是如何优化自己的服务器内存的,

    24 条回复    2017-02-27 05:53:09 +08:00
    privil
        1
    privil  
       2017-02-26 14:43:34 +08:00
    把所有启动的服务看一遍,然后选择性关闭,通常服务器内存都比较足
    liyvhg
        2
    liyvhg  
       2017-02-26 14:45:28 +08:00 via Android
    你看到的占用内存,有可能只是用来加速的 cache
    hl
        3
    hl  
       2017-02-26 14:48:10 +08:00   ❤️ 6
    Linux 内存不是用的越少越好, Centos7 版本以前,通常看到的内存 used 比较多是因为包含了 buffer 和 cache 占用
    Centos7 版本以后,内存 used 显示数值不包含 buffer 和 cache

    Linux 中内存不用白不用,会尽可能的 cache 和 buffer 一些数据,以方便下次使用。
    但实际上这些内存大部分也是在应用需要的时候可以释放出来供应用使用。

    大部分人在对 linux 做内存优化,都是简单的关闭不使用的服务,调整自己应用的参数来减少内存的占用
    因此我也仅通过最简单的方式来介绍下如何调整

    关闭服务
    =======
    Centos7 版本以前可以通过 chkconfig --list 来查看服务列表
    找到当前 runlevel 下自启动的服务名,然后通过 chkconfig --level 3 service_name off 关闭指定 RUNLEVEL 下自启动服务
    重启后生效或者通过 /etc/init.d/servicce_name stop 的方式来实时生效。

    Centos7 以后的版本需要通过 systemctl list-unit-files --type=service --state=enabled 查看自启动服务
    通过 systemctl disable service_name 关闭启动
    通过 systemctl stop service_name 停止服务运行

    调整应用参数
    ==========
    这个部分需要了解自己启动的服务软件简单的工作原理和配置方法
    VPS 中安装的 LNMP 环境主要包含三个套件: Nginx, MySQL, php

    Nginx
    ======
    工作进程数量直接决定了 Nginx 对内存的占用,平均一个工作进程占用 10~40m 不等
    可通过配置文件中 worker_processes 指定

    MySQL
    ======
    MySQL 比较复杂,大致可以从全局共享内存使用和线程独享内存使用两个方向入手

    全局共享内存可理解为 MySQL 启动的时候就需要分配的全局内存使用
    比较明显的是可以调整以下几个参数(但不完全就是以下几个)
    key_buffer_size
    innodb_buffer_pool_size
    innodb_additional_memory_pool_size
    innodb_log_buffer_size
    query_cache_size

    线程独享内存使用可以理解为每个到 MySQL 的链接都会分配一部分内存
    read_buffer_size
    sort_buffer_size
    read_rnd_buffer_size
    tmp_table_size

    除此之外 MySQL 还有灰常多的参数可以调整影响到内存的使用,可以参考官方文档了

    以上列出的参数,也并不是调整了就有效果,因为 MySQL 还有一个重要的东西就是存储引擎
    常用的比如 InnoDB , MyISAM 很多参数都是针对存储引擎的,比如你只使用 InnoDB,却调整了 MyISAM 的参数
    那也是没有效果的

    php
    ====
    由于本人没有搞过 php 所以具体也不清楚详细的调整
    php 没有运行在 nginx 下的 module ,所以大部分通过 php-fpm 的方式启动
    php-fpm 提供 fastcgi 的协议访问, nginx 再通过 fastcgi 反代到 php-fpm

    所以这里的 php-fpm 也是一个多进程应用,也可以通过调整 php-fpm 的启动进程数量来达到控制内存占用的效果


    以上这些都是从简单的方面来优化的,但还是那句话,一切看你时机的使用情况,这些参数不是越低越好
    比如 nginx 只给 1 个进程。 php-fpm 只给一个进程,在你狂刷浏览器时就会发现你经常会遇到 502 , 503 错误

    鉴于在题主是在放在 vps 中的小博客,实在不需要搞到太深度的调优。如果想了解仍可去搜索一些相关的资料:
    linux 内核参数调优
    linux io 队列调优
    nginx 如何通过编译安装精简模块
    php 编译安装 精简不必要模块
    mysql 编译安装精简存储引擎
    uzumaki
        4
    uzumaki  
       2017-02-26 15:03:52 +08:00 via Android
    我会参考俄罗斯某面板。号称 512 内存 10 万访问没问题。。
    SgtDaJim
        5
    SgtDaJim  
       2017-02-26 15:26:56 +08:00
    @hl 你的回复对我很有启发!请问我可以将你的回复转载到我的博客中吗?
    hl
        6
    hl  
       2017-02-26 15:27:46 +08:00   ❤️ 1
    @SgtDaJim 随意转载 :)
    kmdd33
        7
    kmdd33  
    OP
       2017-02-26 16:06:38 +08:00 via iPad
    @hl 调整应用参数方面,你说的 mysql 的 2 个方面的内存使用,你是如何配置数值参数方面?能否给详细解释一下?那如果对于像 V2EX ,和 quora 这样的社区类型,请问,应该如何进行深度的调优呢?我安装的 centos7 , php-fpm 应该设置几个进程呢?如果根据用户的访问量又该如何设置?
    SgtDaJim
        8
    SgtDaJim  
       2017-02-26 17:44:32 +08:00
    @hl 谢谢!
    Antidictator
        9
    Antidictator  
       2017-02-26 17:48:29 +08:00 via Android
    @hl 学到了!!!
    binghe
        10
    binghe  
       2017-02-26 18:41:15 +08:00
    @uzumaki #4 什么面板?也参考一下
    qcloud
        11
    qcloud  
       2017-02-26 18:50:12 +08:00 via iPhone
    @binghe 应该是 vestacp , www.vestacp.com
    yun
        12
    yun  
       2017-02-26 18:52:27 +08:00
    400M 正常
    可以定时清除缓存

    $ crontab -e
    添加
    0 */2 * * * echo 3 > /proc/sys/vm/drop_caches 每两小时清除缓存
    1 */2 * * * service httpd restart 每两小时第一分钟重启 httpd
    2 */3 * * * service mysqld restart 每两小时第二分钟重启 mysql

    保存退出
    yun
        13
    yun  
       2017-02-26 18:56:39 +08:00
    @uzumaki 这纯属扯淡, 500M 能撑住 50 并发我跪服。
    skydiver
        14
    skydiver  
       2017-02-26 18:59:01 +08:00 via iPad
    @yun 没事儿闲的清楚缓存干嘛。。
    yun
        15
    yun  
       2017-02-26 19:03:34 +08:00
    @skydiver 恩,闲的
    uzumaki
        16
    uzumaki  
       2017-02-26 19:54:41 +08:00
    @yun http://www.servermom.org/vestacp-performance-openvz-vps/3649/
    @qcloud
    @binghe
    嗯 就说的这个 vestacp
    实际情况不知道
    uzumaki
        17
    uzumaki  
       2017-02-26 20:00:53 +08:00
    管他能不能实际达到 但是有参考价值 每天能接受 300 人访问 比现在楼主痛苦的要好吧 先解决现在楼主的问题 多余的时间在去慢慢优化 不是更好
    hl
        18
    hl  
       2017-02-26 21:26:00 +08:00   ❤️ 3
    @kmdd33


    1 调整应用参数方面,你说的 mysql 的 2 个方面的内存使用,你是如何配置数值参数方面?
    2 那如果对于像 V2EX ,和 quora 这样的社区类型,请问,应该如何进行深度的调优呢?
    3 我安装的 centos7 , php-fpm 应该设置几个进程呢?
    4 如果根据用户的访问量又该如何设置?


    .>>>>>>>>>>>>>>>>>
    问题 1:mysql 的 2 个方面的内存使用,你是如何配置数值参数方面?
    额,参数调整是一个看实际使用的情况调整的事情,如果硬要给几个标准,我就给个案例,把内存这块摘出来看
    >>>>>>>>>>>>>>>>>
    ===============================
    服务器配置:
    CPU 4 Core
    RAM 4 GB
    应用: Nodejs 写的 API 服务,用于后台账号订单处理,数据库全部采用 InnoDB 存储引擎

    全局共享内存部分:
    key_buffer_size = 6M
    innodb_buffer_pool_size = 2048M
    innodb_additional_mem_pool_size = 8M
    innodb_log_buffer_size = 32M
    query_cache_size = 4M

    线程独享内存部分:
    sort_buffer_size = 8M
    read_buffer_size = 8M
    read_rnd_buffer_size = 8M
    tmp_table_size = 128M
    ===============================

    同样的配置抄过去,可能性能反而很低,请谨慎使用,以下是这些参数怎么来的:

    这个账单系统是一个实时的用户按量扣费的账单系统 API ,
    数据库实时反映了对用户操作的扣量统计,后台管理员会频繁的排序,筛选,以及扣量费率阶梯调整.

    针对这个场景,数据库有频繁的 update, order by,group by 和带 where 的 select 查询

    key_buffer_size = 6M
    业务数据库压根不使用 MyISAM 引擎,只有少量的系统表在使用,该值是针对 MyISAM 的独特参数
    甚至可以设置的更低 2M

    innodb_buffer_pool_size = 2048M
    Innodb 主要的缓存池,决定了对 innodb 表操作的性能,通常占用到物理内存全部的 80%甚至更高 90%
    这里 4GB 内存,只设置到了 2048M ,是因为服务器上还有其他的服务在跑

    innodb_additional_mem_pool_size = 8M
    主要用来存放 InnoDB 存储引擎的字典信息以及一些 internal 的共享数据结构信息。
    所以其大小也与系统中所使用的 InnoDB 存储引擎表的数量有较大关系

    innodb_log_buffer_size = 32M
    innodb 事务日志的临时 buffer 空间,用来提升 mysql 写事务日志的性能,先写在内存,再 flush 到磁盘

    query_cache_size = 4M
    该值理论可以大大提升查询性能,用来缓存 select 的结果集,但对频繁更新的表并无太大助益
    业务逻辑决定了订单信息一直在变化,没次查询出来的结构都不尽相同,增大该值并无明显效果

    sort_buffer_size = 8M #排序操作 buffer
    read_buffer_size = 8M #顺序读 buffer 例如遇到一些 select 操作的全表扫描
    read_rnd_buffer_size = 8M # 随机读 buffer 例如用到索引的带条件 select 操作
    tmp_table_size = 128M #临时表用于 Order By , Group By
    订单系统频繁的排序,筛选,以及扣量费率阶梯调整,增大以上值会有帮助


    其实写到这里完全没有依据, 4 核 4GB 的服务器为什么 sort_buffer_size=8M , tmp_table_size =128M
    而实际情况是,我们一开始设置了 sort_buffer_size = 4M, tmp_table_size=8M
    后期数据达到快 300w 时,完全就不够用了,我们又调上来的。

    调优这种东西,没有哪个参数调整多少是对的, 10w 的量和 100w 和 1000w 参数都可能会不同。
    甚至是因为某次应用更新,数据库增加了巨多的字段或索引,参数就满足不了需要了,
    或者有时候数据量没有变化,并发连接多了,导致线程独享内存占用的多了,参数也需要调整了。

    所以正确的姿势还是需要了解 mysql 存储引擎的工作原理,和提供了哪些参数,每个参数都影响了什么
    对于常规应用部署,大部分配置都是根据以下标准计算:

    每个业务逻辑涉及到哪些类型的查询
    ==> 针对性的对 select,update, order by , group by 优化相应参数

    每个业务逻辑产生的数据库查询集中在哪些字段
    ==> 针对集中字段进行索引

    不同类型的查询字段平均预测数据长度在多少,推算业务逻辑一次查询出来产生了多少数据量的结果集
    ==> 提供对 sort_buffer, read_buffer, read_rnd_buffer 等等参数的设置标准

    不知第一个问题回答到这里,可以了不?

    >>>>>>>>>>>>>>>>>
    问题 2:对于像 V2EX ,和 quora 这样的社区类型,请问,应该如何进行深度的调优呢?
    >>>>>>>>>>>>>>>>>
    深度调优的概念其实很宽泛,大型社区会从社区规模,业务逻辑的复杂性来针对性的优化
    比如从运行环境,应用本身,网络线路与 CDN ,数据库, Cache 层,整体架构涉及等各个方面进行调整

    我非 V2EX 成员也非 quora 的员工,以下只是通过我所在的项目而言提供一些资料:

    简单业务逻辑的社区,可以针对性的只对运行环境,应用本身,数据页面等 Cache ,网络 CDN 等进行优化

    复杂业务逻辑涉及到较多的团队和整体架构涉及,比如:
    运行环境:
    Linux 操作系统的调优也是根据运行不同的应用来调整,大体调整以下几个方面:
    关闭不必要的后台服务
    选择合适的 IO 调度算法
    加大文件描述符上限
    加大可用端口数量
    禁用 numa
    优化文件系统挂载
    TCPIP 内核参数优化
    这么多的调整大部分通过所谓的内核参数进行调整,比如 Centos7 是在 /etc/sysctl.conf 中进行调整

    应用方面:
    应用级别的调优核心在软件工程师本身的代码质量和应用逻辑优化。
    我本身做服务端架构的,这个领域属于软件开发范畴,并不精于软件开发,提供不来太多信息
    但从架构角度来看,服务端需要满足方便横向扩展的原则,方便快速扩容

    网络方面:
    网络部分涉及到数据中心选择与线路 BGP 的支持,以及 CDN 加速的支持

    数据库方面:
    大型数据库应用涉及到不同类型的数据库使用比如 mysql 关系型数据库, mongodb 内存数据库, redis 缓存等
    在大型的业务中还涉及到分库,分表,分布式等

    综合以上各个方面设计整体架构,应用众多的负载均衡,请求分流,来提供一个稳定的集群

    >>>>>>>>>>>>>>>>>>
    问题 3:我安装的 centos7 , php-fpm 应该设置几个进程呢?
    问题 4:如果根据用户的访问量又该如何设置?
    >>>>>>>>>>>>>>>>

    php-fpm 的设置也是需要根据实际情况来看,进程数量可以根据 CPU 核心数量进行设置
    比如 4 核 CPU ,可以设置 3 个进程,预留一核给系统,也可以设置 8 个进程
    非要问有啥区别?区别的产生是应用带来的,不是 php 调了配置就有了区别。

    举个栗子:
    一个页面执行非常快,几 ms 就可以执行完,那你在 4 核 CPU 上设置 8 个进程完全没问题
    几个月跑的欢实,你能说 8 个进程设置的不对?

    再举个栗子
    一个页面执行非常快,几十毫秒就可以返回结果,在 4 核 CPU 的服务器上配置了 4 个进程
    我们希望理想状况下,每个进程能工作在每个 CPU 核心上。

    有 2000 个用户来访问,这 2000 个用户可能是一天产生的,也可能是一个小时之内产生的
    页面提供的服务良好。
    但有一天通过这个页面做了一个限时抢的活动,有 2000 个用户几乎在十几秒钟之内
    来访问这个页面,程序却慢了,这个时候考虑到十几秒内有上千用户访问
    产生的并发不是 4 个进程同时提供服务能满足的,可能产生了排队,排队代表有了拥塞,
    拥塞导致负载升高, CPU 调度慢了,任务处理不完就在内存,内存占用就多了
    那这种情况就能说开 4 个进程是对的嘛?


    四个问题都回答完了,企业项目中我们需要通过工具来收集数据,根据数据来估算提供多大配置,做哪些调优.
    很少有一步到位给出非常合理的配置的 。

    小规模的应用,博客类,我个人是常规配置 2 核 2G , 4 核 4G 都可以。 nginx 配置 2 个进程, php 配置 2 个进程
    先上去用着。

    用量越来越大就可以根据压力点去拆分, php 压力高,就拆分到单独的服务器中,还可以多增加服务器运行 php
    将多台 php 加入到 nginx 的负载均衡里去, php 压力下来,发现 mysql 压力高,可以审查下 sql 语句的性能等
    之后还可以做 mysql 的读写分离,把读取和写入压力分开,再者就是增加 memcache 或 redis 缓存
    akira
        19
    akira  
       2017-02-26 21:32:11 +08:00
    linux 内存使用情况,只要没有爆出什么问题,就随便他用就好。这个和 windows 不一样的。
    yun
        20
    yun  
       2017-02-26 22:07:08 +08:00
    @uzumaki 不行的,他机器 RAM : 2GB , 512MB VSWAP 是控制面板。
    我自己的机器 2GB ,没用 CDN,撑死 150 人在线,来再多一个就要排队,超时就打不开网页了。
    如果他说访问量,以前我测试过 512M 的 EC2 ,貌似不到 50 瞬发,只要不达到瞬发数,一天几十万当然可以,但是没有但是。
    zjq426
        21
    zjq426  
       2017-02-26 22:09:13 +08:00
    cpu 有几个核?根据核数使用固定数目的 php-fpm pool worker, 不要用 dynamic , nginx 同理,然后写日志的地方能关就关一些吧,如果不是并发高的日志直接写文件不用 buffer 。
    mingyun
        22
    mingyun  
       2017-02-26 23:29:15 +08:00
    @hl thks
    lan894734188
        23
    lan894734188  
       2017-02-27 00:09:41 +08:00 via Android
    首先你看清楚实际占用先
    kmdd33
        24
    kmdd33  
    OP
       2017-02-27 05:53:09 +08:00 via iPad
    @hl cool ,思路清楚了,非常感谢。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1757 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 16:29 · PVG 00:29 · LAX 08:29 · JFK 11:29
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.