日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

深入探讨Varnish缓存命中率

發(fā)布時間:2023/11/27 生活经验 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 深入探讨Varnish缓存命中率 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

也許你還在為剛才動態(tài)內(nèi)容獲得7336.76 reqs/s的吞吐率感到振奮,等等,理想和現(xiàn)實是有差距的,你要忍受現(xiàn)實的殘酷,別忘了,我們壓力測試中的動態(tài)內(nèi)容都處于全緩存情況下,也就是每次請求都命中緩存,這在現(xiàn)實中往往是不可能的。
首先,緩存區(qū)空間大小是有限的,而我們的站點可能有大量的內(nèi)容需要被緩存,而不像前邊壓力測試時只有一個內(nèi)容。一旦緩存區(qū)被裝滿,那么緩存管理器便會淘汰一些它認(rèn)為不再需要的緩存內(nèi)容,比如通過LRU(最近最少使用算法)將使用頻率較低的緩存內(nèi)容淘汰出去,但是,這里判斷“不常使用”的標(biāo)準(zhǔn)是不嚴(yán)格的,也許被淘汰的內(nèi)容就是你將要訪問的下一個內(nèi)容,這便影響了它的命中率。
其次,緩存的過期時間也影響到它的命中率,假如有效期很短,為10秒,那么最少10秒便會有一次無法命中。
還有,有些內(nèi)容可能根本沒有被代理服務(wù)器緩存,比如這些內(nèi)容包含了set-cookie等不可緩存的HTTP頭信息,導(dǎo)致反向代理不會緩存它們,并且在瀏覽器請求它們的時候也不會去緩存區(qū)查找。這是影響命中率的一個重要因素,但往往被我們所忽略。
幸運的是,這些問題我們都可以輕松的解決,前提是,我們需要了解反向代理緩存的實時工作狀態(tài),比如Varnish便提供了一個命令行的狀態(tài)監(jiān)控程序varnishstat,我們打開它,便看到了當(dāng)前時刻的狀態(tài),如下:

client_conn           9908723        94.05 Client connections accepted
client_drop                 0         0.00 Connection dropped, no sess/wrk
client_req           16433490       155.99 Client requests received
cache_hit             8751732        83.07 Cache hits
cache_hitpass           42592         0.40 Cache hits for pass
cache_miss            7573389        71.89 Cache misses
backend_conn          3889845        36.92 Backend conn. success
backend_unhealthy          220         0.00 Backend conn. not attempted
backend_busy                0         0.00 Backend conn. too many
backend_fail             4536         0.04 Backend conn. failures
backend_reuse         3780212        35.88 Backend conn. reuses
backend_toolate       3866687        36.70 Backend conn. was closed
backend_recycle       7646677        72.58 Backend conn. recycles
backend_unused              0         0.00 Backend conn. unused
fetch_head                 57         0.00 Fetch head
fetch_length           155097         1.47 Fetch with Length
fetch_chunked         7508522        71.27 Fetch chunked
fetch_eof                   0         0.00 Fetch EOF
fetch_bad                   0         0.00 Fetch had bad headers
fetch_close              3982         0.04 Fetch wanted close
fetch_oldhttp               0         0.00 Fetch pre HTTP/1.1 closed
fetch_zero                  0         0.00 Fetch zero len
fetch_failed                0         0.00 Fetch failed
n_sess_mem               1033          .   N struct sess_mem
n_sess                    633          .   N struct sess
n_object              1016443          .   N struct object
n_vampireobject             0          .   N unresurrected objects
n_objectcore          1017564          .   N struct objectcore
n_objecthead           982903          .   N struct objecthead
n_smf                 2647421          .   N struct smf
n_smf_frag             622470          .   N small free smf
n_smf_large                 3          .   N large free smf
n_vbe_conn                 12          .   N struct vbe_conn
n_wrk                    8000          .   N worker threads
n_wrk_create             8000         0.08 N worker threads created
n_wrk_failed                0         0.00 N worker threads not created
n_wrk_max               11021         0.10 N worker threads limited
n_wrk_queue                 0         0.00 N queued work requests
n_wrk_overflow           2441         0.02 N overflowed work requests
n_wrk_drop                  0         0.00 N dropped work requests
n_backend                   4          .   N backends
n_expired             6344546          .   N expired objects
n_lru_nuked            183957          .   N LRU nuked objects
n_lru_saved                 0          .   N LRU saved objects
n_lru_moved           3692170          .   N LRU moved objects
n_deathrow                  0          .   N objects on deathrow
losthdr                    84         0.00 HTTP header overflows
n_objsendfile               0         0.00 Objects sent with sendfile
n_objwrite           15466812       146.81 Objects sent with write
n_objoverflow               0         0.00 Objects overflowing workspace
s_sess                9906155        94.03 Total Sessions
s_req                16433490       155.99 Total Requests
s_pipe                     37         0.00 Total pipe
s_pass                 108252         1.03 Total pass
s_fetch               7667658        72.78 Total fetch
s_hdrbytes         7187255662     68221.35 Total header bytes
s_bodybytes      111592032839   1059230.32 Total body bytes
sess_closed           1905544        18.09 Session Closed
sess_pipeline               0         0.00 Session Pipeline
sess_readahead              0         0.00 Session Read Ahead
sess_linger          15277717       145.02 Session Linger
sess_herd            13547370       128.59 Session herd
shm_records        1028855796      9765.89 SHM records
shm_writes           77957008       739.97 SHM writes
shm_flushes            131005         1.24 SHM flushes due to overflow
shm_cont               144281         1.37 SHM MTX contention
shm_cycles                427         0.00 SHM cycles through buffer
sm_nreq              15306717       145.29 allocator requests
sm_nobj               2024948          .   outstanding allocations
sm_balloc         13595295744          .   bytes allocated
sm_bfree          40091795456          .   bytes free
sma_nreq                    0         0.00 SMA allocator requests
sma_nobj                    0          .   SMA outstanding allocations
sma_nbytes                  0          .   SMA outstanding bytes
sma_balloc                  0          .   SMA bytes allocated
sma_bfree                   0          .   SMA bytes free
sms_nreq                14062         0.13 SMS allocator requests
sms_nobj                    0          .   SMS outstanding allocations
sms_nbytes                487          .   SMS outstanding bytes
sms_balloc            6844837          .   SMS bytes allocated
sms_bfree             6846298          .   SMS bytes freed
backend_req           7668789        72.79 Backend requests made
n_vcl                       1         0.00 N vcl total
n_vcl_avail                 1         0.00 N vcl available
n_vcl_discard               0         0.00 N vcl discarded
n_purge                740577          .   N total active purges
n_purge_add            905392         8.59 N new purges added
n_purge_retire         164815         1.56 N old purges deleted
n_purge_obj_test     13397373       127.17 N objects tested
n_purge_re_test  131875330367   1251759.15 N regexps tested against
n_purge_dups           240655         2.28 N duplicate purges removed
hcb_nolock                  0         0.00 HCB Lookups without lock
hcb_lock                    0         0.00 HCB Lookups with lock
hcb_insert                  0         0.00 HCB Inserts
esi_parse                   0         0.00 Objects ESI parsed (unlock)
esi_errors                  0         0.00 ESI parse errors (unlock)
accept_fail              2553         0.02 Accept failures
client_drop_late            0         0.00 Connection dropped late
uptime                 105352         1.00 Client uptime


看起來很強大,的確,它幫我們獲得了很多重要的信息,包括了三個重要的統(tǒng)計項:

N struct object

當(dāng)前被cache的條目

Client requests received

代表到目前為止,瀏覽器向反向代理服務(wù)器發(fā)送的HTTP請求累積次數(shù),由于可能使用長連接,所以它可能會大于上邊的Client connections accepted。

Cache hits

代表在這些請求中,反向代理服務(wù)器在緩存區(qū)中查找并且命中緩存的次數(shù)。

Cache misses

代表在這些請求中,反向代理服務(wù)器在緩存區(qū)中查找但是沒有命中緩存的次數(shù)。

N expired objects

代表過期的緩存內(nèi)容個數(shù)

N LRU nuked objects

由于cache空間滿而不得不扔掉的cache條目,如果這個數(shù)字是0,就沒必要增加cache的大小了。

N LRU moved objects

代表被淘汰的緩存內(nèi)容個數(shù)

Total header bytes

代表緩存區(qū)中所有緩存內(nèi)容的HTTP頭信息長度

Total body bytes

代表緩存區(qū)中所有緩存內(nèi)容的正文長度
通過以上這些統(tǒng)計項,我們還可以知道更多,比如Cache hits和Cache misses的總和代表了反向代理服務(wù)器在緩存區(qū)中查找內(nèi)容的總次數(shù);而用Client requests received減去這個總次數(shù),便大概等于沒有查找緩存的請求數(shù);Total body bytes和Total body bytes的總和則代表了緩存區(qū)當(dāng)前的空間使用量。
了解了這些后,我們回頭看前邊的三個問題,都很容易分析和解決。
對于緩存區(qū)空間大小的問題,我們可以通過監(jiān)視它的使用量以及緩存淘汰個數(shù),在必要的時候分配更多的緩存區(qū)空間,但是這可能需要重新啟動反向代理服務(wù)器。當(dāng)然,我們應(yīng)該首先根據(jù)站點的規(guī)模,來估算出大概的緩存區(qū)空間,并且分配出大約為它5倍以上的緩存區(qū)空間,以適應(yīng)一段時期內(nèi)的內(nèi)容數(shù)量增長。
其次,是緩存有效期取值的問題,但這本身不是一個問題,它取決于后端Web服務(wù)器的承受能力,以及你對站點內(nèi)容實時性的要求,我們在前邊介紹動態(tài)內(nèi)容緩存的章節(jié)中曾經(jīng)探討過緩存有效期的取值,實質(zhì)上是一個尋找“過”與“不及”之間平衡的長期過程,但在動態(tài)程序?qū)崿F(xiàn)的內(nèi)容緩存機制中,我們還可以通過主動刪除緩存的方法來實現(xiàn)緩存到期之前的更新,而基于HTTP協(xié)議的反向代理緩存機制則不容易做到這一點,后端的動態(tài)程序無法主動刪除某個緩存內(nèi)容,除非我們清空反向代理服務(wù)器上的緩存區(qū)。
在尋找平衡的過程中,有時候?qū)崟r性需求可能要向緩存有效期適當(dāng)讓步,當(dāng)我們的站點面臨較大的壓力時,我們不得不暫時以犧牲實時性作為代價,適當(dāng)?shù)难娱L緩存有效期,直到我們有了成熟的性能擴展方案。
在初步評估緩存有效期的時候,我們可以通過一些量化的計算來得出理論數(shù)值,舉個例子,假如我們的站點有60000個動態(tài)內(nèi)容處于頻繁訪問的狀態(tài),我們通過Cache-Control將它們在反向代理服務(wù)器上的緩存有效期都設(shè)置為60秒,這樣一樣來,后端服務(wù)器將必須承受最多每秒處理1000個動態(tài)內(nèi)容的工作量,如果這些動態(tài)內(nèi)容都進行完整的計算,比如訪問數(shù)據(jù)庫,那么顯然后端服務(wù)器是無法承受的,這時候我們可以將緩存有效期延長到300秒,即5分鐘,這使得后端服務(wù)器只需要每秒處理200個動態(tài)內(nèi)容,大大減少了工作量。
那么,如果從緩存命中率的角度來分析緩存有效期取值的時候,有一點需要明白,當(dāng)我們看到緩存的命中率非常低時,有時并不代表我們需要馬上延長緩存有效期,這時候還要觀察當(dāng)前的站點實際吞吐率,舉個極端的例子,假如你發(fā)現(xiàn)你的站點1個小時內(nèi)只有1次訪問,而緩存有效期為半個小時,那緩存命中率必然會非常低,但即便是每次緩存都不命中,也不會對后端帶來什么壓力,實際上如果你的站點只有一臺Web服務(wù)器,并且站點的實際吞吐率遠遠低于它的處理能力時,完全沒有必要使用反向代理服務(wù)器。
最后關(guān)于內(nèi)容沒有被緩存的問題,我們也可以在Varnish的狀態(tài)監(jiān)視中找到線索,比如有一個用Varnish加速第三方應(yīng)用wordpress的例子,得到的Varnish狀態(tài)如下:

4+10:37:44
my.server.com
Hitrate ratio: 1 1 1
Hitrate avg: 0.0364 0.0364 0.0364
2324 0.00 0.01 Client connections accepted
6191 0.00 0.02 Client requests received
12 0.00 0.00 Cache hits
7 0.00 0.00 Cache hits for pass
318 0.00 0.00 Cache misses
6179 0.00 0.02 Backend connections success
0 0.00 0.00 Backend connections not
attempted
0 0.00 0.00 Backend connections too many
0 0.00 0.00 Backend connections failures
4057 0.00 0.01 Backend connections reuses
6151 0.00 0.02 Backend connections recycles
...

我們看到,Varnish一共處理了來自瀏覽器的6191個請求,其中命中緩存的有12個,真是太少了,而沒有命中緩存的有318個,奇怪,剩下的那么多請求根本就沒有去緩存區(qū)檢查,也就是說,Varnish認(rèn)為那些內(nèi)容不能被緩存。不能被緩存總是有原因的,你需要根據(jù)反向代理緩存的規(guī)則,來進一步的檢查。而我們這個例子中,都是cookies惹得禍,因為在wordpress中由于我們會安裝一些各種各樣的插件,有些插件會使得wordpress的每個頁面都帶有寫入cookies的set-cookie標(biāo)記,而我們前邊在vcl_fetch函數(shù)中禁止了這類內(nèi)容的緩存,問題就在這里了,我們希望將這些多余的cookie關(guān)閉掉,但是,wordpress自身的登錄和管理頁面是需要cookies才可以正常工作的,所以我們還需要讓反向代理不緩存這些頁面,我們使用以下VCL配置:

sub vcl_recv
{
if (!(req.url ~ "wp-(login|admin)"))
{
unset req.http.cookie;
}
}
sub vcl_fetch
{
if (!(req.url ~ "wp-(login|admin)"))
{
unset obj.http.set-cookie;
}
}

可以看到,除了wordpress自身的登錄和管理頁面以外,我們將其它內(nèi)容的HTTP頭信息中有關(guān)cookie的標(biāo)記全部都清除掉,這使得Varnish可以將大部分內(nèi)容緩存起來,提高緩存命中率,同時不影響我們登錄和管理wordpress。
這個例子給了我們一些啟示,對于我們自己的站點,如果從長遠考慮,那么在規(guī)劃的時候就要費點心思,我們可以根據(jù)內(nèi)容是否可以緩存在反向代理服務(wù)器上,將它們置于不同的主機,這樣便可以在必要的時候?qū)⒖梢跃彺娴膬?nèi)容快速與反向代理服務(wù)器對接,獲得較好的加速效果。

總結(jié)

以上是生活随笔為你收集整理的深入探讨Varnish缓存命中率的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。