那些年我們一起追過的緩存寫法(二)

上次主要討論緩存讀寫這塊各種代碼實現。本篇是就上次的問題接著來,繼續看那些年我們各種緩存用法。

一:緩存預熱

上次有同學問過。在第一次加載時,我們的緩存都為空,怎么進行預熱。

單機Web情況下,一般我們使用RunTimeCache。相對于這種情況下:

1:我們可以在啟動事件里面刷新

1
2
3
4
voidApplication_Start(object sender, EventArgs e)
{
       //刷新
}

2:單寫個刷新緩存頁面,上線后手動刷新下、或發布時自動調用刷新、或干脆由用戶自行觸發。

分布式緩存(Redis、memcached)情況下:

比如:在幾十臺服務器緩存時,單刷滿緩存都需要不少一段時間。

這種預熱就復雜一些,有的會單寫個應用程序去跑,也有的會單寫套框架機制去處理(更智能化)。

目的都是在上線之前:所有的緩存都預先加載完畢。

二:多級緩存

2.1 介紹

我們曉得在CPU和內存之間一般都配有一級緩存、二級緩存來增加交換速度。

這樣當CPU調用大量數據時,就可避開內存直接從CPU緩存中調用,加快讀取速度。

根據CPU緩存得出多級緩存的特點:

1:每一級緩存中儲存的是下一級緩存的一部分。

2:讀取速度按級別依次遞減,成本也依次遞減,容量依次遞增。

3:當前級別未命中時,才會去下一級尋找。

而在企業應用級開發中,使用多級緩存是同樣的目的及設計,只是粒度更粗,更靈活。

根據速度依次排列lv1-lv6的緩存類型圖:

那些年我們一起追過的緩存寫法(二)

3級緩存的命中流程圖例子:

那些年我們一起追過的緩存寫法(二)

2.2 線程緩存

Web應用是天生的多線程開發。對于一些公共資源我們必須考慮線程安全,為止我們不得不通過鎖來保證數據的完整性和正確性。

在實際當中,一臺web服務器至少也得處理成百上千的請求。想一想,在業務復雜的處理流程,函數每調用一次我們都得鎖一下。

對服務器也是個不小的浪費。而通過線程緩存,可以讓當前處理用戶請求的線程只拿自己需要的。

1
publicstaticThreadLocal<UserScore> localUserInfo =newThreadLocal<UserScore>();

借助Net提供的線程本地變量,我們可以在請求入口去拉取當前用戶的數據。

在之后線程整個生命周期里面,我們的業務邏輯可以毫無顧慮的使用這些數據,不需要考慮線程安全。

而且我們不用重新拿新數據,所以也不用擔心數據撕裂的問題。

因為當前線程周期里面的數據是完整無誤的,而只有用戶第二次發起請求才會重新去拿新數據。

這樣就能提高不少我們服務器吞吐量。注意要在線程出口銷毀數據。

2.3 內存緩存

無論是遠程數據庫讀取,還是緩存服務器讀取。避免不了要跨進程,跨網絡通信,有的還跨機房。

而應用程序頻繁讀寫,對Web、DB服務器都是個不小的消耗,速度相較內存也慢的多。

代碼上加鎖、異步,甚至加服務器在內,都不是一個很好的辦法。因為加載速度,對用戶體驗非常重要。


所以在有要求的項目中使用本地內存做二級緩存,是非常有必要的。目的就是1:抗并發,2:加快讀取速度。

有個著名的緩存五分鐘法則法則,就是說如果一個數據頻繁被訪問,那么就應該放內存中。

舉個例子:  有100并發過來,加鎖會導致前端99線程等候,這個99線程等候著,其實是一直在消耗Web服務器資源。不加就是緩存雪崩。

如果我們每分鐘拉取一份緩存,緩存到內存,這樣99線程等候時間極大縮短。

2.4 文件緩存

相對于內存,硬盤容量大,速度相較于走網絡還更快。

所以我們完全可以把一些不經常變更,放在內存又比較浪費的數據緩存到本地硬盤。

比如使用sqlite一些文件數據庫,我們很容易做到。

2.5 分布式緩存

基于內存緩存的redis、memcached等。

基于文件nosql的Casssandra、mongodb等。

redis、memcached是主流的分布式內存緩存,也是應用和DB中間最大的緩存層。

nosql這類的其實不單單只是做緩存用了,完全用在一些非核心業務的DB層了。

2.6 DB緩存

這一層DB主要是緩存由原始數據計算出的結果。而避免由Web程序通過SQL或在使用中直接計算。

當然我們也可以把計算好的數據,存儲到redis做緩存。

那些年我們一起追過的緩存寫法(二)

三:多層緩存

多層緩存概念在很多地方都用到過:

1:上面我們說的多級緩存就是一種,把內容根據讀取頻率等級,分不同的層次存儲,頻率越高就越近。

2:還一種多層是緩存索引的做法,類B樹查找,這樣能提高檢索效率。

3:從架構上來說客戶端緩存,CDN緩存,反向代理緩存,服務端緩存,也是多層緩存。

四:總結

在使用上,大家根據實際場景,進行各種組合搭配。本篇談的比較理論些,很多內容細節沒展開。

比如分布式緩存使用,緩存置換策略及算法,緩存過期機制等。后面樓主會繼續補充下去。

原創文章,作者:stanley,如若轉載,請注明出處:http://www.www58058.com/686

(0)
stanleystanley
上一篇 2015-03-03
下一篇 2015-03-04

相關推薦

  • Apache配置壓縮優化時報錯——undefined symbol: inflateEnd

    原創作品,允許轉載,轉載時請務必以超鏈接形式標明文章 原始出處 、作者信息和本聲明。否則將追究法律責任。http://nolinux.blog.51cto.com/4824967/1345264    圣誕都過了,好久沒來51發博文了。最近一直在忙考試和其他一些私人事務,感覺長期不發博文,有點不好。不是不發,實在是最近…

    Linux干貨 2016-08-15
  • 計算機組成及Linux入門知識

    計算機的基本組成: 存儲器:     實現記憶功能的部件用來存放計算程序及參與運算的各種數據 運算器:     負責數據的算術運算和邏輯運算即數據的加工處理 控制器:     負責對程序規定的控制信息進行分析,控制并協調輸入,輸出操作或內存訪問 輸入設備:    實現計算程序和原始數據的輸入 輸出設備:    實現計算結果輸出 組成的聯系: 圖一 圖二 計算…

    Linux干貨 2016-09-16
  • Chrony

    RHEL7.4 192.168.100.1 作為時間服務器,其它主機到這臺來同步時間。 時間服務器安裝及配置:#yum install chrony –RHEL7默認已安裝chrony,而沒有安裝ntpd. #systemctl status chronyd –查看chronyd服務狀態#systemctl enable chrony…

    2018-01-06
  • ELK+RabbitMQ架構處理nginx及tomcat日志

    前言       查看日志的傳統方法是:登錄操作系統,使用命令工具如cat、tail、sed、awk、grep等等進行過濾輸出后分析,處理少量日志還好,日志量大處理效率就沒那么高了。而且很多情況下開發人員需要查看并分析日志進行排錯,但他們對Linux命令又不是太熟悉,而且有時候又不能賦予他們服務器權限,更多時…

    Linux干貨 2016-08-02
  • Linux入門知識之計算機基礎

    計算機基礎、linux發行版、命令幫助獲取

    2018-01-11
  • 系統自動化安裝和SELinux

    一、知識整理 1、anaconda系統安裝程序:默認圖形啟動; 使用光盤啟動,在選擇模式界面tab鍵在后面增加text或按下ESC鍵,輸入lnux text進入字符界面安裝。 2、創建kickstart文件: 直接手動編輯:依據模板修改,/root目錄下的anaconda.cfg 使用創建工具創建:system-config-kickstart,圖形化工具:…

    Linux干貨 2016-09-26
欧美性久久久久