Linux 內(nèi)存不是用的越少越好异旧, Centos7 版本以前莽使,通炒斩看到的內(nèi)存 used 比較多是因為包含了 buffer 和 cache 占用
Centos7 版本以后腥椒,內(nèi)存 used 顯示數(shù)值不包含 buffer 和 cache
Linux 中內(nèi)存不用白不用,會盡可能的 cache 和 buffer 一些數(shù)據(jù)敌蚜,以方便下次使用忙灼。
但實際上這些內(nèi)存大部分也是在應(yīng)用需要的時候可以釋放出來供應(yīng)用使用。
大部分人在對 linux 做內(nèi)存優(yōu)化钝侠,都是簡單的關(guān)閉不使用的服務(wù),調(diào)整自己應(yīng)用的參數(shù)來減少內(nèi)存的占用
因此我也僅通過最簡單的方式來介紹下如何調(diào)整
關(guān)閉服務(wù)
=======
Centos7 版本以前可以通過 chkconfig --list 來查看服務(wù)列表
找到當(dāng)前 runlevel 下自啟動的服務(wù)名酸舍,然后通過 chkconfig --level 3 service_name off 關(guān)閉指定 RUNLEVEL 下自啟動服務(wù)
重啟后生效或者通過 /etc/init.d/servicce_name stop 的方式來實時生效帅韧。
Centos7 以后的版本需要通過 systemctl list-unit-files --type=service --state=enabled 查看自啟動服務(wù)
通過 systemctl disable service_name 關(guān)閉啟動
通過 systemctl stop service_name 停止服務(wù)運行
調(diào)整應(yīng)用參數(shù)
==========
這個部分需要了解自己啟動的服務(wù)軟件簡單的工作原理和配置方法
VPS 中安裝的 LNMP 環(huán)境主要包含三個套件: Nginx, MySQL, php
Nginx
======
工作進(jìn)程數(shù)量直接決定了 Nginx 對內(nèi)存的占用,平均一個工作進(jìn)程占用 10~40m 不等
可通過配置文件中 worker_processes 指定
MySQL
======
MySQL 比較復(fù)雜啃勉,大致可以從全局共享內(nèi)存使用和線程獨享內(nèi)存使用兩個方向入手
全局共享內(nèi)存可理解為 MySQL 啟動的時候就需要分配的全局內(nèi)存使用
比較明顯的是可以調(diào)整以下幾個參數(shù)(但不完全就是以下幾個)
key_buffer_size
innodb_buffer_pool_size
innodb_additional_memory_pool_size
innodb_log_buffer_size
query_cache_size
線程獨享內(nèi)存使用可以理解為每個到 MySQL 的鏈接都會分配一部分內(nèi)存
read_buffer_size
sort_buffer_size
read_rnd_buffer_size
tmp_table_size
除此之外 MySQL 還有灰常多的參數(shù)可以調(diào)整影響到內(nèi)存的使用忽舟,可以參考官方文檔了
以上列出的參數(shù),也并不是調(diào)整了就有效果淮阐,因為 MySQL 還有一個重要的東西就是存儲引擎
常用的比如 InnoDB 叮阅, MyISAM 很多參數(shù)都是針對存儲引擎的,比如你只使用 InnoDB,卻調(diào)整了 MyISAM 的參數(shù)
那也是沒有效果的
php
====
由于本人沒有搞過 php 所以具體也不清楚詳細(xì)的調(diào)整
php 沒有運行在 nginx 下的 module 泣特,所以大部分通過 php-fpm 的方式啟動
php-fpm 提供 fastcgi 的協(xié)議訪問浩姥, nginx 再通過 fastcgi 反代到 php-fpm
所以這里的 php-fpm 也是一個多進(jìn)程應(yīng)用,也可以通過調(diào)整 php-fpm 的啟動進(jìn)程數(shù)量來達(dá)到控制內(nèi)存占用的效果
以上這些都是從簡單的方面來優(yōu)化的状您,但還是那句話勒叠,一切看你時機的使用情況兜挨,這些參數(shù)不是越低越好
比如 nginx 只給 1 個進(jìn)程。 php-fpm 只給一個進(jìn)程眯分,在你狂刷瀏覽器時就會發(fā)現(xiàn)你經(jīng)常會遇到 502 , 503 錯誤
鑒于在題主是在放在 vps 中的小博客,實在不需要搞到太深度的調(diào)優(yōu)榨惰。如果想了解仍可去搜索一些相關(guān)的資料:
linux 內(nèi)核參數(shù)調(diào)優(yōu)
linux io 隊列調(diào)優(yōu)
nginx 如何通過編譯安裝精簡模塊
php 編譯安裝 精簡不必要模塊
mysql 編譯安裝精簡存儲引擎
“
1 調(diào)整應(yīng)用參數(shù)方面擅威,你說的 mysql 的 2 個方面的內(nèi)存使用,你是如何配置數(shù)值參數(shù)方面飘诗?
2 那如果對于像 V2EX 与倡,和 quora 這樣的社區(qū)類型,請問疚察,應(yīng)該如何進(jìn)行深度的調(diào)優(yōu)呢蒸走?
3 我安裝的 centos7 , php-fpm 應(yīng)該設(shè)置幾個進(jìn)程呢貌嫡?
4 如果根據(jù)用戶的訪問量又該如何設(shè)置比驻?
”
.>>>>>>>>>>>>>>>>>
問題 1:mysql 的 2 個方面的內(nèi)存使用,你是如何配置數(shù)值參數(shù)方面岛抄?
額别惦,參數(shù)調(diào)整是一個看實際使用的情況調(diào)整的事情,如果硬要給幾個標(biāo)準(zhǔn)夫椭,我就給個案例掸掸,把內(nèi)存這塊摘出來看
>>>>>>>>>>>>>>>>>
===============================
服務(wù)器配置:
CPU 4 Core
RAM 4 GB
應(yīng)用: Nodejs 寫的 API 服務(wù),用于后臺賬號訂單處理蹭秋,數(shù)據(jù)庫全部采用 InnoDB 存儲引擎
全局共享內(nèi)存部分:
key_buffer_size = 6M
innodb_buffer_pool_size = 2048M
innodb_additional_mem_pool_size = 8M
innodb_log_buffer_size = 32M
query_cache_size = 4M
線程獨享內(nèi)存部分:
sort_buffer_size = 8M
read_buffer_size = 8M
read_rnd_buffer_size = 8M
tmp_table_size = 128M
===============================
同樣的配置抄過去扰付,可能性能反而很低,請謹(jǐn)慎使用仁讨,以下是這些參數(shù)怎么來的:
這個賬單系統(tǒng)是一個實時的用戶按量扣費的賬單系統(tǒng) API 羽莺,
數(shù)據(jù)庫實時反映了對用戶操作的扣量統(tǒng)計,后臺管理員會頻繁的排序洞豁,篩選盐固,以及扣量費率階梯調(diào)整.
針對這個場景,數(shù)據(jù)庫有頻繁的 update, order by,group by 和帶 where 的 select 查詢
key_buffer_size = 6M
業(yè)務(wù)數(shù)據(jù)庫壓根不使用 MyISAM 引擎丈挟,只有少量的系統(tǒng)表在使用刁卜,該值是針對 MyISAM 的獨特參數(shù)
甚至可以設(shè)置的更低 2M
innodb_buffer_pool_size = 2048M
Innodb 主要的緩存池,決定了對 innodb 表操作的性能曙咽,通常占用到物理內(nèi)存全部的 80%甚至更高 90%
這里 4GB 內(nèi)存蛔趴,只設(shè)置到了 2048M ,是因為服務(wù)器上還有其他的服務(wù)在跑
innodb_additional_mem_pool_size = 8M
主要用來存放 InnoDB 存儲引擎的字典信息以及一些 internal 的共享數(shù)據(jù)結(jié)構(gòu)信息例朱。
所以其大小也與系統(tǒng)中所使用的 InnoDB 存儲引擎表的數(shù)量有較大關(guān)系
innodb_log_buffer_size = 32M
innodb 事務(wù)日志的臨時 buffer 空間夺脾,用來提升 mysql 寫事務(wù)日志的性能之拨,先寫在內(nèi)存,再 flush 到磁盤
query_cache_size = 4M
該值理論可以大大提升查詢性能咧叭,用來緩存 select 的結(jié)果集蚀乔,但對頻繁更新的表并無太大助益
業(yè)務(wù)邏輯決定了訂單信息一直在變化,沒次查詢出來的結(jié)構(gòu)都不盡相同菲茬,增大該值并無明顯效果
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
訂單系統(tǒng)頻繁的排序,篩選婉弹,以及扣量費率階梯調(diào)整睬魂,增大以上值會有幫助
其實寫到這里完全沒有依據(jù), 4 核 4GB 的服務(wù)器為什么 sort_buffer_size=8M 镀赌, tmp_table_size =128M
而實際情況是氯哮,我們一開始設(shè)置了 sort_buffer_size = 4M, tmp_table_size=8M
后期數(shù)據(jù)達(dá)到快 300w 時,完全就不夠用了商佛,我們又調(diào)上來的喉钢。
調(diào)優(yōu)這種東西,沒有哪個參數(shù)調(diào)整多少是對的良姆, 10w 的量和 100w 和 1000w 參數(shù)都可能會不同肠虽。
甚至是因為某次應(yīng)用更新,數(shù)據(jù)庫增加了巨多的字段或索引玛追,參數(shù)就滿足不了需要了税课,
或者有時候數(shù)據(jù)量沒有變化,并發(fā)連接多了痊剖,導(dǎo)致線程獨享內(nèi)存占用的多了韩玩,參數(shù)也需要調(diào)整了。
所以正確的姿勢還是需要了解 mysql 存儲引擎的工作原理陆馁,和提供了哪些參數(shù)找颓,每個參數(shù)都影響了什么
對于常規(guī)應(yīng)用部署,大部分配置都是根據(jù)以下標(biāo)準(zhǔn)計算:
每個業(yè)務(wù)邏輯涉及到哪些類型的查詢
==> 針對性的對 select,update, order by , group by 優(yōu)化相應(yīng)參數(shù)
每個業(yè)務(wù)邏輯產(chǎn)生的數(shù)據(jù)庫查詢集中在哪些字段
==> 針對集中字段進(jìn)行索引
不同類型的查詢字段平均預(yù)測數(shù)據(jù)長度在多少氮惯,推算業(yè)務(wù)邏輯一次查詢出來產(chǎn)生了多少數(shù)據(jù)量的結(jié)果集
==> 提供對 sort_buffer, read_buffer, read_rnd_buffer 等等參數(shù)的設(shè)置標(biāo)準(zhǔn)
不知第一個問題回答到這里,可以了不想暗?
>>>>>>>>>>>>>>>>>
問題 2:對于像 V2EX 妇汗,和 quora 這樣的社區(qū)類型,請問说莫,應(yīng)該如何進(jìn)行深度的調(diào)優(yōu)呢杨箭?
>>>>>>>>>>>>>>>>>
深度調(diào)優(yōu)的概念其實很寬泛,大型社區(qū)會從社區(qū)規(guī)模储狭,業(yè)務(wù)邏輯的復(fù)雜性來針對性的優(yōu)化
比如從運行環(huán)境互婿,應(yīng)用本身捣郊,網(wǎng)絡(luò)線路與 CDN ,數(shù)據(jù)庫慈参, Cache 層呛牲,整體架構(gòu)涉及等各個方面進(jìn)行調(diào)整
我非 V2EX 成員也非 quora 的員工,以下只是通過我所在的項目而言提供一些資料:
簡單業(yè)務(wù)邏輯的社區(qū)驮配,可以針對性的只對運行環(huán)境娘扩,應(yīng)用本身,數(shù)據(jù)頁面等 Cache 壮锻,網(wǎng)絡(luò) CDN 等進(jìn)行優(yōu)化
復(fù)雜業(yè)務(wù)邏輯涉及到較多的團(tuán)隊和整體架構(gòu)涉及琐旁,比如:
運行環(huán)境:
Linux 操作系統(tǒng)的調(diào)優(yōu)也是根據(jù)運行不同的應(yīng)用來調(diào)整,大體調(diào)整以下幾個方面:
關(guān)閉不必要的后臺服務(wù)
選擇合適的 IO 調(diào)度算法
加大文件描述符上限
加大可用端口數(shù)量
禁用 numa
優(yōu)化文件系統(tǒng)掛載
TCPIP 內(nèi)核參數(shù)優(yōu)化
這么多的調(diào)整大部分通過所謂的內(nèi)核參數(shù)進(jìn)行調(diào)整猜绣,比如 Centos7 是在 /etc/sysctl.conf 中進(jìn)行調(diào)整
應(yīng)用方面:
應(yīng)用級別的調(diào)優(yōu)核心在軟件工程師本身的代碼質(zhì)量和應(yīng)用邏輯優(yōu)化灰殴。
我本身做服務(wù)端架構(gòu)的,這個領(lǐng)域?qū)儆谲浖_發(fā)范疇掰邢,并不精于軟件開發(fā)牺陶,提供不來太多信息
但從架構(gòu)角度來看,服務(wù)端需要滿足方便橫向擴(kuò)展的原則尸变,方便快速擴(kuò)容
網(wǎng)絡(luò)方面:
網(wǎng)絡(luò)部分涉及到數(shù)據(jù)中心選擇與線路 BGP 的支持义图,以及 CDN 加速的支持
數(shù)據(jù)庫方面:
大型數(shù)據(jù)庫應(yīng)用涉及到不同類型的數(shù)據(jù)庫使用比如 mysql 關(guān)系型數(shù)據(jù)庫, mongodb 內(nèi)存數(shù)據(jù)庫召烂, redis 緩存等
在大型的業(yè)務(wù)中還涉及到分庫碱工,分表,分布式等
綜合以上各個方面設(shè)計整體架構(gòu)奏夫,應(yīng)用眾多的負(fù)載均衡怕篷,請求分流,來提供一個穩(wěn)定的集群
>>>>>>>>>>>>>>>>>>
問題 3:我安裝的 centos7 酗昼, php-fpm 應(yīng)該設(shè)置幾個進(jìn)程呢廊谓?
問題 4:如果根據(jù)用戶的訪問量又該如何設(shè)置?
>>>>>>>>>>>>>>>>
php-fpm 的設(shè)置也是需要根據(jù)實際情況來看麻削,進(jìn)程數(shù)量可以根據(jù) CPU 核心數(shù)量進(jìn)行設(shè)置
比如 4 核 CPU 蒸痹,可以設(shè)置 3 個進(jìn)程,預(yù)留一核給系統(tǒng)呛哟,也可以設(shè)置 8 個進(jìn)程
非要問有啥區(qū)別叠荠?區(qū)別的產(chǎn)生是應(yīng)用帶來的,不是 php 調(diào)了配置就有了區(qū)別扫责。
舉個栗子:
一個頁面執(zhí)行非抽欢Γ快,幾 ms 就可以執(zhí)行完,那你在 4 核 CPU 上設(shè)置 8 個進(jìn)程完全沒問題
幾個月跑的歡實者娱,你能說 8 個進(jìn)程設(shè)置的不對抡笼?
再舉個栗子
一個頁面執(zhí)行非常快黄鳍,幾十毫秒就可以返回結(jié)果推姻,在 4 核 CPU 的服務(wù)器上配置了 4 個進(jìn)程
我們希望理想狀況下,每個進(jìn)程能工作在每個 CPU 核心上际起。
有 2000 個用戶來訪問拾碌,這 2000 個用戶可能是一天產(chǎn)生的,也可能是一個小時之內(nèi)產(chǎn)生的
頁面提供的服務(wù)良好街望。
但有一天通過這個頁面做了一個限時搶的活動校翔,有 2000 個用戶幾乎在十幾秒鐘之內(nèi)
來訪問這個頁面,程序卻慢了灾前,這個時候考慮到十幾秒內(nèi)有上千用戶訪問
產(chǎn)生的并發(fā)不是 4 個進(jìn)程同時提供服務(wù)能滿足的防症,可能產(chǎn)生了排隊,排隊代表有了擁塞哎甲,
擁塞導(dǎo)致負(fù)載升高蔫敲, CPU 調(diào)度慢了,任務(wù)處理不完就在內(nèi)存炭玫,內(nèi)存占用就多了
那這種情況就能說開 4 個進(jìn)程是對的嘛奈嘿?
四個問題都回答完了,企業(yè)項目中我們需要通過工具來收集數(shù)據(jù)吞加,根據(jù)數(shù)據(jù)來估算提供多大配置裙犹,做哪些調(diào)優(yōu).
很少有一步到位給出非常合理的配置的 。
小規(guī)模的應(yīng)用衔憨,博客類叶圃,我個人是常規(guī)配置 2 核 2G , 4 核 4G 都可以践图。 nginx 配置 2 個進(jìn)程掺冠, php 配置 2 個進(jìn)程
先上去用著。
用量越來越大就可以根據(jù)壓力點去拆分码党, php 壓力高德崭,就拆分到單獨的服務(wù)器中,還可以多增加服務(wù)器運行 php
將多臺 php 加入到 nginx 的負(fù)載均衡里去揖盘, php 壓力下來眉厨,發(fā)現(xiàn) mysql 壓力高,可以審查下 sql 語句的性能等
之后還可以做 mysql 的讀寫分離扣讼,把讀取和寫入壓力分開缺猛,再者就是增加 memcache 或 redis 緩存