架構師日記——Varnish的效能調優
Varnish的效能調優分成兩個部分
1.一個是硬體、作業系統和網路部分的優化
2.另外一個,也是最重要的一個,就是VCL的調優。
要進行硬體、作業系統和網路部分的優化,瞭解Varnish的程序和執行緒架構是有必要的,他們能幫助你更好的去調整優化,以及整合應用系統。
Varnish的程序架構圖
- 管理程序(The management process)
Varnish主要有兩個程序,管理程序和子程序,管理程序負責:管理配置的變更(包括VCL和引數)、編譯VCL、監控Varnish執行、初始化Varnish,以及提供命令列介面等。管理程序會每隔幾秒鐘檢查一下子程序,如果發現子程序掛了,會kill掉然後重新啟動一個。這些操作都會記錄在日誌裡面,以利於你檢查錯誤。 - 子程序(The child process)
子程序包括幾個不同型別的執行緒,包括但不限於:
1:Acceptor執行緒:接受新的連線並代表它們
2:Worker執行緒:一個會話一個執行緒,通常會使用數百個Worker執行緒
3:Expiry執行緒:負責從快取中清除舊的內容 - 工作區(Workspace)
Varnish使用Workspace來減少多個執行緒間對於記憶體的競爭。Varnish有多個工作區,最重
要的是session workspace,它通常用來操作會話資料。比如:修改www.example.com到example.com,以減少重複快取。
就算你的Session工作區有5G,使用了1000個執行緒,但實際使用的記憶體容量不會這麼多,虛擬記憶體會是5個G,但是實際的記憶體是根據你實際的使用來的,記憶體控制器和作業系統會幫你管理記憶體,這個不用擔心 - 和系統的通訊,子程序會使用共享記憶體日誌訪問檔案系統,這意味著,如果一個執行緒需要記錄日誌,它只需要獲得鎖,然後寫入記憶體,然後釋放鎖就可以了。另外每個執行緒都有一份日誌資料的快取,以減少鎖的競爭
- 日誌資料通常為80M,分成兩個部分,第一個部分是計數器,第二個部分是請求資料。你可以使用日誌工具來檢視共享記憶體日誌,因為日誌記錄並不會是原始的格式。
- 對於儲存型別,如果不需要永久保持快取的話,建議使用malloc,如果要永久儲存,或者是要快取的內容超過了實體記憶體的大小,那麼使用file。
另外一個要注意:快取物件會有額外的開銷,以保持對快取的追蹤,大概一個物件需要1k的額外開銷,這也意味著,最終使用的記憶體會比你通過-s指定的記憶體大小要大一些。 - 通常對硬體、作業系統和網路部分的優化,主要就是相關引數的優化。引數調優的方法:
通常是在CLI介面去調整,然後測試,如果ok的話,就把它們配置到配置檔案裡面去
執行緒模式
子程序是Varnish真正產生奇蹟的地方,它包含一系列的執行緒來執行不同的任務,下面羅列幾個常見的:
1.cache-worker:每個連線一個,負責處理請求
2.cache-main:一個,負責啟動
3.ban lurker:一個,負責禁用的處理
4.acceptor:一個,負責接受新的連線
5.epoll/kqueue:可配置,預設是2個,管理執行緒池
6.expire:一個,負責刪除過期內容
7.backend poll:一個backend poll一個執行緒,用於健康檢查
通常我們只需要配置cache-worker執行緒數,其他的執行緒可以不用管。
調整Varnish的時候,需要考慮預期的流量,執行緒模型允許你使用多個執行緒池,但時間和經驗表明,只要你有2個執行緒池就夠了,加入更多也不會提高效能。一些舊的資料會建議你一個cpu核執行一個執行緒池,這個已經過時了,現在只要2個就夠了。
執行緒池相關的引數,前面已經都講過了,最重要的是thread_pool_min和thread_pool_max。通常保持最少在500-1000個執行緒都是合適的,具體的可以根據varnishstat來檢視n_wrk_queued,根據具體情況來配置
執行緒growth時間
Varnish能支援數千個執行緒同時執行,但並不是所有的作業系統核心都能支撐,因此使用thread_pool_add_delay來保證每個執行緒間有一點延遲,現在已經不重要了,作業系統都比較成熟了,一般從20ms到2s
系統級引數
隨著Varnish越來越成熟,越來越少的引數需要調整了。sess_workspace是一個要調整的重要引數,它設定的是從客戶端傳入的Http 頭的workspace大小:
1:通常這個值從預設的65536位元組到10M
2:要注意,它是虛擬的記憶體,不是實際使用的記憶體
另外一些可調優的引數就是各種時間,如:
connect_timeout、first_byte_timeout、between_bytes_timeout、send_timeout、sess_timeout、cli_timeout
通常情況下,預設的數值能滿足大多數應用的需要,但你還是需要結合實際的應用進行調整。比如connect_timeout,預設是0.7秒,如果Varnish和backend是通過遠端來連線和訪問,這個時間可能就需要延長。