Varnish

Varnish

Varnish是一款高性能的開源HTTP加速器,挪威最大的線上報紙 Verdens Gang 使用3台Varnish代替了原來的12台Squid,性能比以前更好。

簡介

Varnish 的作者Poul-Henning Kamp是FreeBSD的核心開發者之一,他認為現在的計算機比起1975年已經複雜許多。在1975年時,儲存媒介只有兩種:記憶體與硬碟。但現在計算機系統的記憶體除了主存外,還包括了CPU內的L1、L2,甚至有L3快取。硬碟上也有自己的快取裝置,因此Squid Cache自行處理物件替換的架構不可能得知這些情況而做到最佳化,但作業系統可以得知這些情況,所以這部份的工作應該交給作業系統處理,這就是 Varnish cache設計架構。

varnish項目是2006年發布的第一個版本0.9.距今已經有十多年了,此文檔之前也提過varnish還不穩定,那是2007年時候編寫的,經過varnish開發團隊和網友們的辛苦耕耘,現在的varnish已經很健壯。很多入口網站已經部署了varnish,並且反應都很好,甚至反應比squid還穩定,且效率更高,資源占用更少。相信在反向代理,web加速方面,varnish已經有足夠能力代替squid。

總體架構

2.1 總體流程

主進程 fork 子進程,主進程等待子進程的信號,子進程退出後,主進程重新啟動子進程

子進程生成若干執行緒。

Accept 執行緒:接受請求,將請求掛在 overflow佇列上

Work 執行緒: 多個,從對列上摘除請求,對請求進行處理,直到完成,然後處理下一個

請求

Epoll 執行緒: 一個請求處理稱作一個 session,在 session 周期內,處理完請求後,會交給

Epoll 處理,監聽是否還有事件發生。

Expire 執行緒:對於快取的對象,根據過期時間,組織成二叉堆,該執行緒周期檢查該堆的

根,處理過期的檔案。

執行緒之間的關係:

2.1.1 accept 執行緒

監聽連線埠,接受連線。

接受後組織成 struct ses(session 結構) ,看是否有空閒的工作執行緒,如果有,將請求給它,

pthread_cond_signal 信號通知它沒有空閒執行緒,如果 overflow過大,則放棄該請求。否則,

將其掛在 overflow 上(需要更多工作執行緒,發通知)。

繼續監聽 2.1.2 work 執行緒

從 overflow佇列上摘取請求(struct ses),進入狀態機處理,處理結束後,通過 pipe通信,

將 struct ses傳送給 epoll 執行緒。

2.1.3 Epoll 執行緒,得到傳過來的 struct ses,若還沒有過期,將 socket 放入 epoll 的事件中,事

件發生時,也會將其放入到 overflow中進行。

工作流程

Varnish與一般伺服器軟體類似,分為master(management)進程和child(worker,主要做cache的工作)進程。master進程讀入命令,進行一些初始化,然後fork並監控child進程。child進程分配若干執行緒進行工作,主要包括一些管理執行緒和很多woker執行緒。

針對檔案快取部分,master讀入存儲配置(-s file[,path[,size[,granularity]]] ),調用合適的存儲類型,然後創建/讀入相應大小的快取大檔案。接著,master初始化管理該存儲空間的結構體。這些變數都是全局變數,在fork以後會被child進程所繼承(包括檔案描述符)。

在child進程主執行緒初始化過程中,將前面打開的存儲大檔案整個mmap到記憶體中(如果超出系統的虛擬記憶體,mmap失敗,進程會減少原來的配置mmap大小,然後繼續mmap),此時創建並初始化空閒存儲結構體,掛到存儲管理結構體,以待分配。

接著,真正的工作開始,Varnish的某個負責接受新HTTP連線的執行緒開始等待用戶,如果有新的HTTP連線過來,它總負責接收,然後叫醒某個等待中的執行緒,並把具體的處理過程交給它。Worker執行緒讀入HTTP請求的URI,查找已有的object,如果命中則直接返回並回復用戶。如果沒有命中,則需要將所請求的內容,從後端伺服器中取過來,存到快取中,然後再回復。

分配快取的過程是這樣的:它根據所讀到object的大小,創建相應大小的快取檔案。為了讀寫方便,程式會把每個object的大小變為最接近其大小的記憶體頁面倍數。然後從現有的空閒存儲結構體中查找,找到最合適的大小的空閒存儲塊,分配給它。如果空閒塊沒有用完,就把多餘的記憶體另外組成一個空閒存儲塊,掛到管理結構體上。如果快取已滿,就根據LRU機制,把最舊的object釋放掉。

釋放快取的過程是這樣的:有一個逾時執行緒,檢測快取中所有object的生存期,如果超初設定的TTL(Time To Live)沒有被訪問,就刪除之,並且釋放相應的結構體及存儲記憶體。注意釋放時會檢查該存儲記憶體塊前面或後面的空閒記憶體塊,如果前面或後面的空閒記憶體和該釋放記憶體是連續的,就將它們合併成更大一塊記憶體。

整個檔案快取的管理,沒有考慮檔案與記憶體的關係,實際上是將所有的object都考慮是在記憶體中,如果系統記憶體不足,系統會自動將其換到swap空間,而不需要varnish程式去控制。

安裝配置

wget -c http://repo.varnish-cache.org/source/varnish-3.0.1.tar.gz

tar xzvf varnish-3.0.1.tar.gz

cd varnish-3.0.1

./configure --prefix=/usr/local/varnish

make

make install

groupadd varnish

useradd -d /var/lib/varnish -g varnish -s /sbin/nologin varnish

ln -s /usr/local/varnish/sbin/varnishd /usr/sbin/varnishd

啟動varnish:

varnishd -f /usr/local/varnish/etc/varnish/default.vcl -s malloc,1G -g varnish -u varnish -T 127.0.0.1:2000

關閉varnish:

pkill varnish

啟動參數介紹:

-f /usr/local/etc/varnish/default.vcl

這個 –f 選項指定varnishd使用哪個配置檔案。

-s malloc,1G

這個 –s 選項用來確定varnish使用的存儲類型和存儲容量,我使用的是malloc類型(malloc是一個C函式,用於分配記憶體空間), 1G 定義多少記憶體被malloced,1G = 1gigabyte。

-T 127.0.0.1:2000

Varnish有一個基於文本的管理接口,啟動它的話可以在不停止varnish的情況下來管理varnish。您可以指定管理軟體監聽哪個接口。當然您不能讓全世界的人都能訪問您的varnish管理接口,因為他們可以很輕鬆的通過訪問varnish管理接口來獲得您的root訪問許可權。我推薦只讓它監聽本機連線埠。如果您的系統里有您不完全信任的用戶,您可以通過防火牆規則來限制他訪問varnish的管理連線埠。

-a 0.0.0.0:8080

這一句的意思是制定varnish監聽所有IP發給8080連線埠的http請求,如果在生產環境下,您應該讓varnish監聽80,這也是默認的。

vcl配置檔案的介紹請執行如何命令查看:

man /usr/local/varnish/share/man/man7/vcl.7

版本發布

2011年08月24日,Varnish 3.0.1 RC1 發布,HTTP加速器。

2011年08月30日,Varnish 3.0.1 正式版發布了,與 3.0 版本比較,改進包括:

對象以優雅和保持設定被錯誤地視為候選的短暫存儲,但不會迅速清理,這表現為如果有一個記憶體泄漏。現在這是固定的。

當多個客戶正在等待一個對象,所有客戶端會醒來當一個物體變得可用,從而導致卡執行緒。這已經被修正

一個bug在XML實體是如何處理應急服務國際公司已經固定

文檔目睹了大量的更新

varnishncsa現在更加穩定和支持顯示任意請求和回響欄位。

2011年10月26日,Varnish Cache 3.0.2 發布。

2012年08月20日,Varnish Cache 3.0.3 發布。

2013年06月17日,Varnish Cache 3.0.4 發布,為目前最新版本。

***

最新版為2018-04-15更新,地址於參考資料。

相關詞條

相關搜尋

熱門詞條

聯絡我們