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 编译安装精简存储引擎
“
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 缓存