閱讀642 返回首頁    go 搜狐 go 中電雲集


Squid 高級優化指南

很早以前就看過這個幾個有關Squid優化的文章,玩了這麼久,在回過來在看看,又有不同的感覺,還很深.非常不錯,值的所有的玩squid的人都好好讀讀.

學習CDN不得不讀之-Squid優化補遺

by kang[at]kangkang[dot]org , 轉載請保留.本文基本是一些方向性的指導,並不涉及像具體配置文件的細節,因此本文裏麵的內容大部分不能往配置文件裏麵 copy-paste。。

首先要明確一下,squid 能夠用來作什麼。很多人沒有搞明白 squid 的工作原理,隻是聽說 squid 性能不錯可以用來給網站提速,就直接在自己的 website 前麵套了一個 squid ,這基本沒有任何用處,即使你都是靜態頁麵,後麵apache上麵沒有開 mod_expires,一樣緩存不了,squid隻能起到一個連接管理的用處。

一般說來,網站用 squid 加速,目的有二種

1: squid 本身具有緩存功能,可以將webserver輸出的內容緩存起來,在緩存沒有過期之前來的訪問,都直接用緩存裏麵的內容,這樣可以有效減少 webserver 機器上麵的請求數量。這是 squid 的主要功用。

2: 網絡慢的用戶會長時間占用 webserver 的 TCP 連接,webserver 對每個連接占用的資源比較大,如果長時間不能釋放出來服務其他請求,性能會有比較大的影響。前麵放一個 squid, webserver 就可以迅速處理完邏輯以後,把數據快速發送給 squid, 然後去處理別的邏輯,而 squid 每個 TCP 連接占用的資源很少,不用擔心占用太多資源。這個用途也叫做連接管理,有一些網絡設備也可以做這個事情,價格都很貴。

下麵針對 squid 的兩種功用,來講述如何調整業務邏輯和 squid 參數

預操作

在搞 squid 之前,不管你用什麼編譯配置,需要什麼特殊選項,都請 –enable-snmp ,並配置好 mrtg 之類,可以圖形化的顯示 squid 狀態,例如 Request Hit Ratio(RHR), Byte Hit Ratio(BHR), 等等,反饋是做一切事情的基礎,優化也不例外。

緩存

A: 使用 Expires header 來控製緩存

squid在緩存webserver內容的時候,需要後端webserver輸出一些控製信息告訴他頁麵是不是可以被緩存,以及可以緩存多久。否則 squid 是不會自作主張給你緩存內容的。一個頁麵到底能不能緩存,隻有開發網站的人才知道,因此開發人員有責任在動態頁麵裏麵輸出 Expires 和 Cache-Control header。簡單舉一個 php 的例子以說明這兩個 header 的值是什麼含義,其中$expiretime 的單位是秒。

header(”Expires: ” . gmt_date_format(time()+$expiretime));

header(”Cache-Control: max-age=” . “$expiretime”);

對於靜態文件,有兩種方式來讓 squid 自動給靜態文件緩存,一種是使用 apache 的 mod_expires ,可以針對路徑或者針對文件類型/擴展名來自動輸出 cache 頭。詳細的請參考 mod_expires 的說明 。另一種是用 squid 的 refresh_pattern 來指定。詳細的還是請參考 squid 的配置文件。一般來說,如果後端不是配置很麻煩,建議還是在後端做,前端的配置修改大多數都是違背http協議的,如果出現問題,也比較難排查。

B 根據 squid 訪問的模式,進行業務拆分

進行了 Expires Header 的處理以後,squid 就真正可以起到加速的作用了,你可能也能感覺到,網站的訪問速度明顯加快。但是不要滿足於這點成績,查看 squid 的 snmp 統計圖,通常 hit ratio 並不會太高,有 50% 就了不起了。這就是我們需要進一步優化的,我們的目標是讓大部分 squid 都達到 9X% 的命中率。

為什麼 squid 命中這麼低呢,這大概有兩種原因。大多數的網站都是有一些頁麵不能夠被緩存的,例如登錄頁麵。這些頁麵請求也從 squid 走,成為分母的一部分,直接就降低了命中率,我們首先可以做的事情是,把這些不能夠緩存的頁麵請求,拆分到單獨一個 squid 上麵,或者訪問量不大的話,幹脆把 apache 暴露出來。這樣能夠緩存的那個 squid 命中率馬上上升一截。

有人可能會說,把不能緩存的頁麵分拆開去,就光為了讓能緩存的那個數字好看,這不是掩耳盜鈴麼?其實這麼做是有意義的,首先就是去掉了不能緩存頁麵 的幹 擾,使得我們進一步優化 squid 的依據更加準確。其次是不可緩存請求和可緩存請求之間的重要性通常是有差距的,分拆了以後,它們之間不容易互相搶占資源,不會因為下載圖片的連接太多把 squid 占滿,影響更重要的登錄請求。第三就是可緩存內容通常是圖片等頁麵元素, 瀏覽器在 load 它們的時候,對每個站點的並發連接會有控製,如果分開成不同的IP,可以多一些請求同時執行。提高少許顯示速度。

其實觀察 sohu, sina 之類的頁麵,你會發現它們的頁麵也是分拆的,可以看到頁麵裏麵的圖片都是指向 images.sohu.com 之類的地址,雖然它們可能和其他頁麵一樣後台都指向同一個 apache。

這樣做完,緩存命中率大概能上升到 70%-80% 了,運氣好的時候完全可以上 90%。

另一種導致 squid 命中低的原因和這個比較類似,同樣都是可緩存的內容,有的可能是軟件下載站上麵的大文件,有的是新聞站點上麵的小圖片,如果同一個 squid 對這樣差別巨大的文件加速的話,會嚴重幹擾 squid 的緩存策略,兩者不能兼顧,要不就是大文件占據了 cache ,把小文件都擠出了 cache, 要不就是小文件特別多,大文件無法進入 cache, 導致大文件經常 miss 。這個比不能緩存的頁麵還要惡心,因此即使在服務器資源有限的情況下,也要優先拆分這兩類型訪問。一般來說,文件大小分界線定在 1M 左右就可以了,如果是有軟件下載這樣特別大的文件,可以在 4M – 10M 左右再拆分一次。對於不同訪問類型的 squid, 其係統優化參數也會有所不同,這個我們後麵還會講到。

隻要悉心按照訪問模式來拆分業務,大部分起緩存作用的 squid 都可以達到很高的命中率,至少都可以到達 9X%。

C 根據不同的需求,調整參數優化緩存

完成 A 和 B 兩步優化以後, squid 的命中率經常可以達到 9x%, 可以說我們已經給 squid 創造了非常優秀的外部環境,下麵我們就要從 squid 本身入手,通過調整它的緩存參數和緩存策略,甚至係統的參數,來讓 squid 發揮出更好的性能。

在 B 步驟中,我們把 squid 劃分成了三種用途,緩存大文件,緩存小文件,不緩存文件,這其中最後一種用途情況下麵 squid 不起到緩存效果,隻用來做連接管理,因此我們把它放到後麵的連接管理裏麵敘述,這裏隻討論和緩存相關的 squid 參數。

squid 有內存緩存和磁盤緩存兩級緩存, 通常來說, 隻要是專門給 squid 用的機器, 內存緩存都建議開得比較大, 大內存緩存總是有好處的嘛, 但是注意不要使得係統開始吃 swap ,像Linux這樣一開始吃 swap 性能就下降比較嚴重的係統尤其要注意. 這個程度需要自己試驗確定.

通常 1G 內存的Linux機器用來跑 squid ,內存緩存可以開到 512M.

有些libc比較差的平台, 例如比較老的 freebsd 係統, 其 malloc 函數的質量不高,可能會造成比較多的內存碎片,導致 squid 運行一段時間以後分配不出來內存掛掉. 這時候推薦在編譯時候使用 dlmalloc package. 即使如此, 仍然要再縮小 squid 的內存緩存,以防不幸發生.

磁盤緩存的情況比較複雜, squid 有 ufs, aufs, coss, diskd, null 五種存儲後端, 其中 ufs, aufs, diskd 都是在文件係統上麵保存很多小文件, coss 是 squid 自己實現了一個簡單的文件係統,可以使用一個大文件或者一個磁盤設備來存儲. null 則是給不想要磁盤緩存的情況準備的. coss 看起來好像比較拽, 但是以前試驗並不足夠穩定,因此並不推薦使用. 剩下的三種存儲方式,具體選擇哪種需要根據操作係統的特性來進行.

ufs 是最傳統的存儲方式, 我們知道, squid 是一個單進程的程序, 它使用 ufs 存儲後端時, 直接在進程裏麵讀寫文件. 這是一種很簡單的方式, 缺點是當讀寫磁盤被阻塞的時候, squid 不能夠處理請求, 會造成服務質量波動比較大. 因此出現了 aufs 和 diskd 兩種存儲後端, 原理都是 squid 主服務循環不負責讀寫文件, 而是通過消息隊列或者tcp/pipe連接將數據傳送給其他的線程(aufs)/進程(diskd), 然後其他線程/進程進行讀寫. 很顯然,這兩種存儲方式有一定的通信開銷, 因此不一定就比 ufs 好, 需要具體問題具體分析

前麵說到, ufs/aufs/diskd都是在文件係統上麵存儲很多小文件,因此文件係統本身的特性嚴重影響了squid緩存的性能,對於 Linux ,強烈推薦用 reiserfs 等適合處理小文件的文件係統, bsd 則至少要打開 softupdate, 以及 dirhash 等一切對很多小文件有好處的選項. 在比較新的係統上麵, reiserfs 等文件係統的性能已經足夠優越, 通常 ufs 就已經可以應付需要. 對於一些老係統,使用 aufs 或者 diskd 是比較好的選擇,如果係統的線程庫比較好(如Linux,Solaris),那麼使用 aufs, 否則 diskd.

也有一些例外情況, 比如多 cpu 的 Linux 2.6 係統, 線程庫很優秀, 雖然 ufs 本身已經比較快了,但是 squid 單進程無法利用另外的 cpu , 不如使用 aufs , 讓另外的 cpu 也可以起到一些作用, aufs 在編譯的時候可以選擇使用幾個讀寫線程. 這個個人覺得稍微超過 cpu 個數就可以了.但是並沒有實際測試過.

磁盤緩存開多大? 這個問題沒有固定答案. 需要經過試驗來確定, 一般來說開大一些沒有太大問題. 隻要你的硬盤足夠

最後更新:2017-01-04 22:34:34

  上一篇:go 批處理查域名解析ping
  下一篇:go mysql在線修複數據庫命令