天天看點

《建構高可用Linux伺服器 第3版》—— 1.5 Linux伺服器的優化yum install ntp` !/bin/bash

本節書摘來自華章出版社《建構高可用linux伺服器 第3版》一 書中的第1章,第1.5節,作者:餘洪春 ,更多章節内容可以通路雲栖社群“華章計算機”公衆号檢視。

伺服器的優化是我們最小化安裝系統時應該做的事情。其實,在做這項工作之前,我們就應該根據實際應用需求來選購linux伺服器,然後有所偏重地選擇硬體,比如我們應該根據伺服器的應用來确定是需要raid 5,還是單塊硬碟等。

無論是租用還是托管都要面臨一個問題,那就是選擇伺服器的硬體配置,前面也說了,選購硬體配置時要根據我們的伺服器應用需求而定。因為你無法通過一台伺服器來滿足所有的需求,解決所有的問題。在項目實施或網站架構之前,我們應該從以下方面來考慮如何選購linux伺服器:

伺服器運作什麼應用?

需要支援多少使用者通路?

需要多大空間來存儲資料?

業務有多重要?

伺服器網卡方面的考慮。

安全方面的考慮。

機架合理化安排了沒?

伺服器的價格超出項目預算了沒?

下面分别來看一下。

1.伺服器運作什麼應用

這是首先需要考慮的問題,我們通常根據伺服器的應用類型(即用途)來決定伺服器的性能、容量和可靠性需求。下面将按照負載均衡、緩存伺服器、前端伺服器+應用程式伺服器+資料伺服器的常見基礎架構來讨論。

負載均衡端:它對伺服器的要求非常低,尤其是用來做lvs負載時,它會直接将所有的連接配接要求轉給後端的web應用。是以,在保證網卡性能的前提下(很多時候我用的是品牌伺服器自帶的百兆網卡),可以将性能相對較差的配置用作負載均衡。

緩存伺服器:主要是squid或varnish等,需要重點考慮兩方面的因素,即記憶體容量盡量大些,硬碟存取速度盡量快些,不要因為硬碟的i/o影響整體性能。

web前端:正常情況下,大多數web前端伺服器(front-end)對伺服器的要求不高,例如靜态web伺服器、動态伺服器、圖檔伺服器等,事實上現在很流行在一台性能卓越的伺服器上同時運作web前端+應用伺服器,比如nginx+fastcgi、nginx+tomcat或nginx+ resin。

應用伺服器:由于它承擔了計算和功能實作的重任,我們需要為基于web架構的應用程式伺服器選擇足夠快的伺服器,另外應用程式伺服器可能需要用到大量的記憶體,尤其是基于windows基礎架構的ruby、python、java伺服器,這一類伺服器至少需要使用單路至強的配置。至于可靠性的問題,如果你的架構中隻有一台應用伺服器,那肯定需要這台伺服器足夠可靠,raid是絕對不能忽視的選項。但如果有兩台或更多的應用伺服器,并設計了負載均衡機制,具有備援功能,那就不必過于擔心了。

特殊的應用:除了用于web架構中的應用程式之外,如果你的伺服器還要處理流媒體視訊編碼、伺服器虛拟化、媒體伺服器(asterisk之類),或者作為遊戲伺服器(邏輯、地圖、聊天)運作,那同樣會對cpu和記憶體的需求比較高,至少也要考慮單路至強的伺服器。其中,伺服器虛拟化對存儲可靠性的要求非常高,因為一個籃子裡有十幾個雞蛋,籃子一定要足夠牢靠才行。

公共服務:這裡指的是郵件伺服器、檔案伺服器、dns伺服器、域控伺服器等。通常我們會部署兩台dns伺服器互相備份,域控主伺服器也會擁有一台備份伺服器(專用的或非專用的),是以對于可靠性,無須過于苛刻。至于郵件伺服器,至少需要具備足夠的硬體可靠性和容量大小,這主要是對郵件資料負責,因為很多使用者沒有儲存和歸檔郵件資料的習慣,待其重裝系統後,就會習慣性地到伺服器上重新下載下傳相應的資料。至于性能問題,則應評估使用者數量後再決定。另外,考慮到它的重要性,建議還要盡量選擇穩定的伺服器系統,比如linux或bsd系列。

資料庫:這是我們最後讨論的應用,對伺服器的要求也是最高、最重要的。無論你使用的是mysql、sql server還是oralce,一般情況下,它都需要有足夠快的cpu、足夠大的記憶體、足夠穩定可靠的硬體。可直接采用dell poweredge r710或hp 580g5,cpu和記憶體方面也要盡可能最大化,如果預算充分,建議用固态硬碟做raid 1+0,因為資料庫伺服器對硬碟的i/o要求是最高的。

2.伺服器需要支援的使用者通路量

伺服器就是為了給使用者提供某種服務的,是以使用這些服務的使用者同樣是我們必須考慮的因素,我們可以從下面幾個具體的問題進行評估。

有多少注冊使用者?

正常情況下有多少使用者會同時線上通路?

每天同時線上通路的最高峰值大概是多少?

一般在項目實施之前,客戶方面會針對這些問題給出一個大緻的結果。但我們盡量要設計得比這更充分和具體。同時,我們還要對未來的使用者增長做一個盡可能準确的預測和規劃,因為你的伺服器可能會支援越來越多的使用者。是以在進行網站或系統架構時要讓機器能靈活擴充。

3.需要的存儲資料空間

關于這個問題需要從兩個方面來考慮,一方面是有哪些類别的資料,包括:作業系統本身占用的空間、安裝應用程式所需要的空間、應用程式所産生的資料、資料庫、日志檔案、郵件資料等,如果網站是web 2.0的,還要計算每個使用者的存儲空間;另一方面是從時間軸上來考慮,這些資料每天都在增長,你至少要為未來1年(我們建議考慮2~3年)的資料增長做個準确測算,這就需要軟體開發人員和業務人員一起提供足夠的資訊。最後你将計算出來的結果乘上1.5左右的系數,友善維護的時候做各種資料的備份和檔案轉移操作。

4.業務的重要性

關于這個問題就需要根據自身的業務領域來考慮相關要求了,下面舉幾個簡單的例子,幫助你了解這些伺服器對可靠性、資料完整性等方面的要求。

如果你的伺服器是用來運作一個wordpress部落格,與朋友們分享觀點的。那麼,一台酷睿伺服器,4gb的記憶體外加一塊500gb的硬碟就足夠了。就算伺服器出現了一點硬體故障,導緻幾個小時甚至一兩天不能提供通路,生活會照常繼續。

如果你的伺服器是用作測試平台的,那麼就不會如生産環境那樣對可靠性有極高的要求,你所需要的可能隻是做好例行的資料備份,若伺服器當機,隻要能在當天解決問題就沒問題了。

如果是一個電子商務公司的伺服器,運作着電子商務網站平台,當硬體發生故障而導緻當機時,你需要對以下“危言聳聽”的後果做好心理準備:投訴電話被打爆、顧客大量流失、顧客要求退款、市場推廣費用打水漂、員工無事可幹、公司營運陷入癱瘓狀态、資料丢失。事實上,電子商務網站一般是需要365×24小時不間斷監控的,而且要有專人輪流值守,并且要有足夠的備份裝置,每個天還要有專人檢查。

如果是大型廣告類或門戶類網站,那麼建議選擇cdn系統。由于它帶有提高網站響應速度、負載均衡、有效抵禦ddos攻擊等特點,相對而言,每個節點都會有大量的備援。是以,除了成本之外,cdn機器的硬碟問題不大。

這裡其實隻是簡單讨論了業務對伺服器硬體可靠性的要求。換言之,如果你覺得業務不能承擔硬碟損壞帶來的停機或資料丢失風險,那麼一定要選擇一個合适的raid卡。對于備援電源問題,道理是一樣的(要全面解決這個問題,不能隻考慮單台伺服器的硬體,還需要結合系統架構的規劃設計)。

在回答了以上問題後,接下來就可以決定下面這些具體選項了。

(1)選擇什麼cpu

回憶一下上面關于“伺服器運作什麼應用”和“需要支援多少使用者通路”兩個方面的考慮,這将幫助我們選擇合适的cpu。毫無疑問,cpu的主頻越高,其性能也就更高;兩個cpu要比一個cpu更好,至強肯定比酷睿性能更強大。但究竟怎樣的cpu才是合适的呢?下面提供了一些常見情況下的建議:

如果你的業務剛剛起步,預算不充足,建議你選擇一款經典的酷睿伺服器,這可以幫你節約大量成本。而且,以後你可以根據業務發展的情況,随時更新到更高配置的伺服器。

如果你需要在一台伺服器上同時運作多種應用服務,例如.net+exchange+sqlserver,那麼一個單核至強(例如x3330)或新一代的酷睿i5(雙核四線程)将是最佳的選擇。雖然從技術的角度來說,這不是一個好主意,但至少能夠幫你節約一大筆成本。

如果你的伺服器要運作sql server、mysql或oracle,而且目前有幾百個使用者同時線上,未來還會不斷增長,那麼你至少應該選擇安裝一台雙四核伺服器。

如果需要的是web應用伺服器,雙四核基本就可以滿足要求。

(2)需要多大的記憶體

同樣,“伺服器運作什麼應用”和“需要支援多少使用者通路”兩方面的考慮也将幫助我們選擇合适的記憶體容量。相比于cpu,我認為記憶體(ram)才是影響性能的最關鍵因素。因為在相當多正在運作的伺服器中,cpu的使用率一般都在10%~30%,甚至更低。但我們發現由于記憶體容量不夠而導緻伺服器運作緩慢的案例比比皆是,如果伺服器不能配置設定足夠的記憶體給應用程式,應用程式就需要通過硬碟接口緩慢地交換讀寫資料了,這将導緻網站慢得令人無法接受。記憶體的大小主要取決于伺服器的使用者數量,當然也和應用軟體對記憶體的最低需求和記憶體管理機制有關,是以,最好由你的程式員或軟體開發商給出最佳的記憶體配置建議。下面同樣給出了一些常見應用環境下的記憶體配置建議:

無論是windows下的iis還是linux下的apache,一般情況下web前端伺服器不需要配置特别高的記憶體,尤其是在叢集架構中,4gb的記憶體就已經足夠了。如果有幾千個并發使用者,而且他們同時運作動态腳本程式,我們才會考慮使用8gb或更高的記憶體。如果是單apache伺服器的線上環境,配置了16gb記憶體後,可以處理6000或者更高的并發量。

對于運作tomcat、resin、weblogic、websphere或.net的應用伺服器,4gb記憶體應該是基準配置,更準确的數字需要根據使用者數量和技術架構來确定。

資料庫伺服器的記憶體由資料庫執行個體的數量、表大小、索引、使用者數來決定,一般建議配置4gb以上的記憶體,我們在許多項目方案中使用了24~48gb的記憶體。

諸如postfix、notes、exchange這樣的郵件伺服器對記憶體的要求并不高,1~2gb就可以滿足要求。

還有一些特殊的伺服器,我們需要為之配置盡可能高的記憶體容量,包括squid、varnish、memcached的緩存伺服器。

對于一台檔案伺服器,1gb記憶體可能就足夠了。

事實上,由于記憶體技術在不斷進化和價格也在不斷降低,我們才得以近乎奢侈地讨論4gb、8gb、16gb這些曾經不可想象的記憶體容量。然而,除了花錢購買記憶體來滿足應用程式的“貪婪”之外,系統優化和資料庫優化仍然是我們需要重視的問題。

(3)需要怎樣的硬碟存儲系統

硬碟存儲系統的選擇和配置是整個伺服器系統裡最複雜的一部分,我們需要考慮硬碟的數量、容量、接口類型、轉速、緩存大小,以及是否需要raid卡、raid卡的型号和raid級别等問題。甚至在一些高可靠性高性能的應用環境中,我們還需要考慮使用怎樣的外部存儲系統(san、nas或das)。伺服器的硬碟raid卡的特點歸納如下:

如果用作緩存伺服器,比如squid、varnish及memcached,可以考慮用raid 0;

如果運作nginx+php5或tomcat、resin等應用,可以考慮用raid 1;

如果是内網開發伺服器或存放重要代碼的伺服器,可以考慮用raid 5;

如果運作mysql或oracle等資料庫應用,可以考慮用sas或者固态硬碟做raid 5或raid 1+0。

5.網卡性能與資料方面的考慮

如果你的基礎架構是多伺服器環境,而且伺服器之間有大量的資料交換,那麼建議為每台伺服器配置兩塊或更多的網卡,一塊用來對外提供服務,另一塊用來做内部資料交換。由于現在項目外端都置于防火牆内,是以許多時候單網卡就足夠了;而比如lvs+keepalived這種隻用公網位址的linux叢集架構,有時可能僅僅需要一塊網卡。目前,hp或dell這種品牌伺服器自帶的網卡已經足夠使用了。

另外,資料的備份也很重要。在實際工作中我們發現,rsync和scp這些linux下的備份工具同樣非常占帶寬,是以如果用scp,建議盡量用它的限速參數;而rsync則盡量選擇在非業務時間段執行。

6.伺服器安全方面的考慮

由于目前國内的ddos攻擊還比較普遍,建議給每個項目方案和自己的電子商務網站配備硬體防火牆,比如juniper、cisco或神盾等。當然,這個問題也是網站後期營運維護需要考慮的,這裡隻是想讓大家有個概念性的認識。有時為了資料的安全,我會讓所有機器用的都是raid 5,另外就是定期巡視機房,檢查伺服器的硬碟燈指向,一有異常就緊急處理。

7.根據機架數合理安排伺服器的數量

這個問題應該在項目實施前就準備好,選擇伺服器時應該明确1u、2u和4u到底有多少台,應該如何安排。在小項目中這個問題可能無關緊要,但在大型項目的實施過程中,這個問題就很突出了,我們應該根據現有或額定的機架數目确定到底應該選擇多少台伺服器。

8.成本考慮:伺服器的價格問題

無論是在替公司采購時,還是在項目實施過程中,這個問題都是重要的問題。我們的方案經常被退回,理由就是超出預算。尤其在一些小項目中,預算更吃緊。我做項目時經常面臨的需求是客戶做的是證券類資訊網站,隻要求周一至周五的九點至下午三點網站不出問題即可,并不想做複雜的負載均衡高可用。是以這時候,我會做成單nginx或haproxy,後面接兩台web應用,這種情況還好說,如果是做中大型電子商務網站,在伺服器成本上的控制就尤其重要。事實上,我們經常出現的問題是,客戶給出的成本預算有限,而我們的應用又需要更多的伺服器,這時候,我們不得不選擇centos 5.8下的免費虛拟化軟體,這将在後面的章節中重點講述。

以上8個方面是我們在采購伺服器時應該注意的因素,在選擇伺服器的元件時要有所偏重,然後根據系統或網站架構來決定伺服器的數量,盡量做到伺服器資源利用最大化。

添置了新伺服器以後,下一步就要安裝系統了。這裡推薦用centos 5.8 x86_64,大家在用伺服器時抱着一個原則:系統安裝的應用程式包越少,伺服器會越穩定,是以我們安裝系統時盡量選擇最小化安裝。至于伺服器的單機性能調優,本着穩定安全的原則,盡量不要改動系統原有的配置(centos自身的檔案和記憶體機制就很優秀)。

1.關閉不需要的服務

衆所周知服務越少,系統占用的資源就會越少,是以應關閉不需要的服務。

建議關閉不需要的服務,這樣做的好處是減少記憶體和cpu時間的占用。指令如下所示:

編輯/etc/crontab 檔案,在末尾加入一行:

01 01 * root /sbin/ntpdate ntp.api.bz >> /dev/null 2>&1

ntp.api.bz是一組ntp伺服器叢集,目前有6台伺服器,位于上海電信處。這項服務是api.bz繼sms.api.bz移動飛信免費短信發送接口之後的第二項免費api服務。

6.停止列印服務

如果不準備提供列印服務,可停止預設設定為自動啟動的列印服務,指令如下所示:

/etc/rc.d/init.d/cups stop ← 停止列印服務

stopping cups:    [ok]  ← 停止服務成功,出現“ok”

chkconfig cups off ← 禁止列印服務自動啟動

chkconfig –list cups ← 确認列印服務自啟動設定狀态

cups0:off 1:off 2:off 3:off 4:off 5:off 6:off ← 0~6都為off的狀态就可以了(目前列印服務禁止自啟動)

7.調整linux的最大檔案打開數

要調整linux的最大檔案打開數,否則squid在高負載時執行性能将會很低;另外,在linux下面部署應用時,有時候會遇上“socket/file:cant open so many files”這樣的問題,這個值也會影響伺服器的最大并發數,其實linux是有檔案句柄限制的,但預設不是很高,一般是1024,生産伺服器很容易就會達到這個值,是以需要改動此值。剛開始我采用vim/etc/security/limit.conf指令,在最後一行添加:

for pid in 'ps aux |grep nginx |grep -v grep|awk '{print$2}''

do

cat /proc/${pid}/limits |grep 'max open files'

done<code>`</code>

8.啟動網卡

大家配置centos 5.5的網卡時,容易忽略的一項就是linux啟動時未啟動網卡,其後果很明顯,那就是你的linux機器永遠也沒有ip位址,下面是一台線上伺服器網卡檔案/etc/sysconfig/network-scripts/ifcfg-eth0的配置:

如果有多個小檔案(比如web伺服器的頁面上有多個小圖檔),通常就沒有必要記錄檔案的通路時間了,這樣可以減少寫磁盤的i/o,這要如何配置呢?

首先,修改檔案系統的配置檔案,我們用打開/etc/fstab檔案,然後,在包含大量小檔案的分區中使用noatime和nodiratime這兩個指令,指令如下所示:

/dev/sda5 /data/pics ext3 noatime,nodiratime 0 0

這樣通路檔案時就不會再産生寫磁盤的i/o了。

核心的優化跟伺服器的優化一樣,本着穩定安全的原則。下面以64位的centos 5.5下的squid伺服器為例來說明,待用戶端與伺服器端建立tcp/ip連接配接後就會關閉socket,伺服器端連接配接的端口狀态也就變為time_wait了。那是不是所有執行主動關閉的socket都會進入time_wait狀态呢?有沒有什麼情況使主動關閉的socket直接進入closed狀态呢?答案是主動關閉的一方在發送最後一個ack後就會進入time_wait狀态,并停留2msl(max segment lifetime)時間,這個是tcp/ip必不可少的,也就是“解決”不了的。

tcp/ip設計者如此設計,主要原因有兩個:

防止上一次連接配接中的包迷路後重新出現,影響新的連接配接(經過2msl時間後,上一次連接配接中所有重複的包都會消失)。

為了可靠地關閉tcp連接配接。主動關閉方發送的最後一個ack(fin)有可能會丢失,如果丢失,被動方會重新發fin,這時如果主動方處于closed狀态,就會響應rst而不是ack。是以主動方要處于time_wait狀态,而不能是closed狀态。另外,time_wait并不會占用很大的資源,除非受到攻擊。

在squid伺服器中可輸入檢視目前連接配接統計數的指令,如下所示:

netstat -n | awk '/^tcp/ {++s[$nf]} end {for(a in s) print a, s[a]}'

指令顯示結果如下所示:

last_ack 14

syn_recv 348

established 70

fin_wait1 229

fin_wait2 30

closing 33

time_wait 18122

指令中的含義分别如下所示:

closed:無連接配接是活動的或正在進行中。

listen:伺服器在等待進入呼叫。

syn_recv:一個連接配接請求已經到達,等待确認。

syn_sent:應用已經開始,打開一個連接配接。

established:正常資料傳輸狀态。

fin_wait1:應用說它已經完成。

fin_wait2:另一邊已同意釋放。

itmed_wait:等待所有分組死掉。

closing:兩邊同時嘗試關閉。

time_wait:另一邊已初始化一個釋放。

last_ack:等待所有分組死掉。

也就是說,這個指令可以把目前系統的網絡連接配接狀态分類彙總。

在linux下高并發的squid伺服器中,tcp time_wait套接字數量經常可達兩三萬,伺服器很容易就會被拖死。不過,我們可以通過修改linux核心參數來減少squid伺服器的time_wait套接字數量,指令如下所示:

vim /etc/sysctl.conf

然後,增加以下參數:

net.ipv4.tcp_fin_timeout = 30

net.ipv4.tcp_keepalive_time = 1200

net.ipv4.tcp_syncookies = 1

net.ipv4.tcp_tw_reuse = 1

net.ipv4.tcp_tw_recycle = 1

net.ipv4.ip_local_port_range = 1024 65000

net.ipv4.tcp_max_syn_backlog = 8192

net.ipv4.tcp_max_tw_buckets = 5000

其中:

net.ipv4.tcp_syncookies=1表示開啟syn cookies。當出現syn等待隊列溢出時,啟用cookie來處理,可防範少量的syn攻擊,預設為0,表示關閉。

net.ipv4.tcp_tw_reuse=1表示開啟重用。允許将time_wait socket重新用于新的tcp連接配接,預設為0,表示關閉。

net.ipv4.tcp_tw_recycle=1表示開啟tcp連接配接中time_wait socket的快速回收,預設為0,表示關閉。

net.ipv4.tcp_fin_timeout=30表示如果套接字由本端要求關閉,這個參數決定了它保持在fin-wait-2狀态的時間。

net.ipv4.tcp_keepalive_time=1200表示當keepalived啟用時,tcp發送keepalived消息的頻度。預設是2小時,改為20分鐘。

net.ipv4.ip_local_port_range=1024 65000表示向外連接配接的端口範圍。預設值很小:32768~61000,改為1024~65000。

net.ipv4.tcp_max_syn_backlog=8192表示syn隊列的長度,預設為1024,加大隊列長度為8192,可以容納更多等待連接配接的網絡連接配接數。

net.ipv4.tcp_max_tw_buckets=5000表示系統同時保持time_wait套接字的最大數量,如果超過這個數字,time_wait套接字将立刻被清除并輸出警告資訊。預設為180000,改為5000。對于apache、nginx等伺服器,前面介紹的幾個參數已經可以很好地減少time_wait套接字數量,但是對于squid來說,效果卻不大。有了此參數就可以控制time_wait套接字的最大數量,避免squid伺服器被大量的time_wait套接字拖死。

執行以下指令使核心配置立馬生效:

/sbin/sysctl –p

如果使用apache或nginx等web伺服器,則隻需要更改以下幾項即可:

net.ipv4.tcp_syncookies=1

net.ipv4.tcp_tw_reuse=1

如果使用postfix郵件伺服器,則建議核心方案如下:

net.ipv4.tcp_keepalive_time = 300

net.ipv4.ip_local_port_range = 5000 65000

kernel.shmmax = 134217728

當然這些都隻是最基本的更改,大家還可以根據自己的需求來更改核心的設定,同樣也要本着伺服器穩定為最高原則,如果伺服器不穩定,一切工作和努力都會白費。如果以上優化仍無法滿足你的要求,你有可能需要定制你的伺服器核心或更新伺服器硬體。至于服務的配置優化,超出了本章的内容,大家可根據自己的需求有針對性地更改。

在本節中,我們從伺服器的硬體選擇、安裝及核心等方面對單機伺服器的性能進行了優化,不過對于網站和系統來說,單機優化對整體性能提升的作用畢竟有限,它們的優化其實是靠伺服器的高可用和高擴充性來實作的,這部分内容我在後面的章節中再來說明。