一種數(shù)據(jù)緩存方法
【專利摘要】本發(fā)明公開了一種數(shù)據(jù)緩存方法。該方法包括:將放入緩存的數(shù)據(jù)進(jìn)行序列化處理;將緩存分為兩個(gè)區(qū)域,稱為冷區(qū)和熱區(qū),冷區(qū)和熱區(qū)都采用雙向鏈表結(jié)構(gòu);將數(shù)據(jù)插入到緩存時(shí),先將數(shù)據(jù)放到冷區(qū);當(dāng)緩存中的數(shù)據(jù)被命中時(shí),如果該數(shù)據(jù)是冷區(qū)數(shù)據(jù),判斷該數(shù)據(jù)是否已命中了預(yù)設(shè)次數(shù),是則將其轉(zhuǎn)移到熱區(qū)的尾部,否則將其轉(zhuǎn)移到冷區(qū)鏈表的首部,如果該數(shù)據(jù)是熱區(qū)數(shù)據(jù),將其轉(zhuǎn)移熱區(qū)鏈表的首部。本發(fā)明的技術(shù)方案有效提高了對(duì)熱數(shù)據(jù)的緩存效率。
【專利說明】一種數(shù)據(jù)緩存方法
【技術(shù)領(lǐng)域】
[0001]本發(fā)明涉及網(wǎng)絡(luò)通信【技術(shù)領(lǐng)域】,特別涉及一種數(shù)據(jù)緩存方法。
【背景技術(shù)】
[0002]隨著即時(shí)通訊產(chǎn)品用戶數(shù)量的增長(zhǎng)和用戶活躍度的提升,即時(shí)通訊產(chǎn)品的好友數(shù)量成幾何倍數(shù)的增長(zhǎng),系統(tǒng)對(duì)數(shù)據(jù)訪問的壓力必然越來越大,而其中的對(duì)數(shù)據(jù)庫(kù)大量并發(fā)隨機(jī)訪問通常是系統(tǒng)的瓶頸,因?yàn)橛脩臬@取其所有好友的相關(guān)數(shù)據(jù)是一種很隨機(jī)的訪問,數(shù)據(jù)庫(kù)對(duì)磁盤的隨機(jī)IO讀取能力受到磁盤本身隨機(jī)讀寫能力的限制。
[0003]因此只有想辦法確定熱數(shù)據(jù),并緩存盡可能多的熱數(shù)據(jù)(熱數(shù)據(jù)是指被訪問次數(shù)較多的數(shù)據(jù),也可以稱為活躍數(shù)據(jù),相對(duì)地,非活躍數(shù)據(jù)稱為冷數(shù)據(jù)),才可以減少業(yè)務(wù)對(duì)數(shù)據(jù)庫(kù)的訪問。
【發(fā)明內(nèi)容】
[0004]有鑒于此,本發(fā)明提供了一種數(shù)據(jù)緩存方法,該方法提高了對(duì)熱數(shù)據(jù)的緩存效率。
[0005]為達(dá)到上述目的,本發(fā)明的技術(shù)方案是這樣實(shí)現(xiàn)的:
[0006]本發(fā)明公開了一種數(shù)據(jù)緩存方法,該方法包括:
[0007]將放入緩存的數(shù)據(jù)進(jìn)行序列化處理;
[0008]在緩存中劃分出兩個(gè)區(qū)域,稱為冷區(qū)和熱區(qū),冷區(qū)和熱區(qū)都采用雙向鏈表結(jié)構(gòu);
[0009]將數(shù)據(jù)插入到緩存時(shí),先將數(shù)據(jù)放到冷區(qū);
[0010]當(dāng)緩存中的數(shù)據(jù)被命中時(shí),如果該數(shù)據(jù)是冷區(qū)數(shù)據(jù),判斷該數(shù)據(jù)是否已命中了預(yù)設(shè)次數(shù),是則將其轉(zhuǎn)移到熱區(qū)的尾部,否則將其轉(zhuǎn)移到冷區(qū)鏈表的首部,如果該數(shù)據(jù)是熱區(qū)數(shù)據(jù),將其轉(zhuǎn)移熱區(qū)鏈表的首部。
[0011]該方法進(jìn)一步包括:
[0012]當(dāng)冷區(qū)滿時(shí),先判斷熱區(qū)是否有一定的空閑區(qū)域,是則將從冷區(qū)鏈表首部起不大于該空閑區(qū)域的一定量的數(shù)據(jù)轉(zhuǎn)移到熱區(qū)的尾部,否則刪除從冷區(qū)鏈表尾部起的一定量的數(shù)據(jù);
[0013]當(dāng)熱區(qū)滿時(shí),先判斷冷區(qū)是否有一定的空閑區(qū)域,是則將從熱區(qū)鏈表尾部起不大于該空閑區(qū)域的一定量的數(shù)據(jù)轉(zhuǎn)移到冷區(qū)的首部,否則刪除從熱區(qū)鏈表尾部起的一定量的數(shù)據(jù)。
[0014]在上述方法中,熱區(qū)/冷區(qū)存儲(chǔ)數(shù)據(jù)的引用,數(shù)據(jù)的實(shí)際緩存內(nèi)容存儲(chǔ)到一個(gè)字典中;
[0015]則上述刪除從熱區(qū)/冷區(qū)鏈表尾部起的一定量的數(shù)據(jù)具體包括:
[0016]刪除該數(shù)據(jù)在熱區(qū)/冷區(qū)中的引用,并刪除該數(shù)據(jù)在所述字典中的對(duì)應(yīng)內(nèi)容。
[0017]所述將放入緩存的數(shù)據(jù)的進(jìn)行序列化處理包括:
[0018]對(duì)于字符串?dāng)?shù)據(jù),如果都是ASCII字符,每個(gè)字符占一個(gè)字節(jié),如果包含除ASCII以外的字符,則用UNICODE編碼;[0019]對(duì)于長(zhǎng)整型數(shù)據(jù),如果長(zhǎng)度不夠8個(gè)字節(jié),則保留其實(shí)際數(shù)字需要的字節(jié)數(shù)。
[0020]所述將放入緩存的數(shù)據(jù)的進(jìn)行序列化處理還包括:將緩存對(duì)象的元數(shù)據(jù)全部剔除,只保留對(duì)象字段的編號(hào)。
[0021]該方法進(jìn)一步包括:
[0022]每隔設(shè)定時(shí)間將熱區(qū)中的數(shù)據(jù)持久化到磁盤中,然后將熱區(qū)數(shù)據(jù)的更新情況記錄到日志文件中;
[0023]當(dāng)緩存數(shù)據(jù)丟失時(shí),用所述磁盤中的數(shù)據(jù)恢復(fù)熱區(qū)數(shù)據(jù),并讀取日志文件內(nèi)容,從恢復(fù)的熱區(qū)數(shù)據(jù)中刪除日志文件中所記錄的發(fā)生更新的數(shù)據(jù)。
[0024]所述將熱區(qū)中的數(shù)據(jù)持久化到磁盤中,將熱區(qū)數(shù)據(jù)的更新情況記錄到日志文件中包括:
[0025]將熱區(qū)數(shù)據(jù)的引用讀到一個(gè)熱區(qū)數(shù)據(jù)列表中;
[0026]將熱區(qū)數(shù)據(jù)列表中的引用所對(duì)應(yīng)的數(shù)據(jù)寫到磁盤文件中,將這期間的熱區(qū)數(shù)據(jù)的更新情況記錄在第一哈希表中;
[0027]將第一哈希表中內(nèi)容寫到日志文件中,并將熱區(qū)數(shù)據(jù)的后續(xù)更新情況記錄到日志文件。
[0028]所述將熱區(qū)數(shù)據(jù)列表中的引用所對(duì)應(yīng)的數(shù)據(jù)寫到磁盤文件包括:將熱區(qū)數(shù)據(jù)列表中的引用所對(duì)應(yīng)的數(shù)據(jù)先寫到第二磁盤文件中,寫入完成后將第二磁盤文件和第一磁盤文件的文件名互換;
[0029]當(dāng)緩存數(shù)據(jù)丟失時(shí),用當(dāng)前第一磁盤文件中的數(shù)據(jù)恢復(fù)熱區(qū)數(shù)據(jù)。
[0030]所述將熱區(qū)數(shù)據(jù)的引用讀到一個(gè)熱區(qū)數(shù)據(jù)列表中包括:對(duì)熱區(qū)加鎖,然后將熱區(qū)數(shù)據(jù)的引用讀到一個(gè)熱區(qū)數(shù)據(jù)列表中;
[0031]該方法進(jìn)一步包括:在將熱區(qū)數(shù)據(jù)的引用讀到一個(gè)熱區(qū)數(shù)據(jù)列表期間,用一個(gè)標(biāo)記使得對(duì)熱區(qū)數(shù)據(jù)的讀訪問返回空數(shù)據(jù),而對(duì)熱區(qū)數(shù)據(jù)的寫訪問則將所訪問的數(shù)據(jù)的標(biāo)識(shí)記錄到第二哈希表中;
[0032]在將熱區(qū)數(shù)據(jù)列表中的引用所對(duì)應(yīng)的數(shù)據(jù)寫到磁盤文件中之前,遍歷第二哈希表,將其中所記錄的數(shù)據(jù)從熱區(qū)數(shù)據(jù)列表中刪除。
[0033]由上述可見,本發(fā)明這種,將放入緩存的數(shù)據(jù)進(jìn)行序列化處理;將緩存分為兩個(gè)區(qū)域,稱為冷區(qū)和熱區(qū),冷區(qū)和熱區(qū)都采用雙向鏈表結(jié)構(gòu);將數(shù)據(jù)插入到緩存時(shí),先將數(shù)據(jù)放到冷區(qū);當(dāng)緩存中的數(shù)據(jù)被命中時(shí),如果是冷區(qū)數(shù)據(jù),判斷該數(shù)據(jù)是否已命中了預(yù)設(shè)次數(shù),是則將其轉(zhuǎn)移到熱區(qū)的尾部,否則將其轉(zhuǎn)移到冷區(qū)鏈表的首部,如果是熱區(qū)數(shù)據(jù),將其轉(zhuǎn)移熱區(qū)鏈表的首部的技術(shù)方案,由于將放入緩存的數(shù)據(jù)進(jìn)行了序列化處理,減少了數(shù)據(jù)對(duì)緩存的占用,提高了緩存的存儲(chǔ)能力,并且實(shí)現(xiàn)了冷熱數(shù)據(jù)的分離,避免了由于大量的隨機(jī)訪問使得熱數(shù)據(jù)被淘汰。
【專利附圖】
【附圖說明】
[0034]圖1是本發(fā)明實(shí)施例中的應(yīng)用訪問數(shù)據(jù)的流程示意圖;
[0035]圖2是本發(fā)明實(shí)施例中的雙向鏈表結(jié)構(gòu)的示意圖;
[0036]圖3是本發(fā)明實(shí)施例中的持久化的一個(gè)流程示意圖;
[0037]圖4是本發(fā)明實(shí)施例中服務(wù)重啟時(shí)熱區(qū)數(shù)據(jù)的恢復(fù)流程圖?!揪唧w實(shí)施方式】
[0038]本發(fā)明的核心思想是:將放入緩存的數(shù)據(jù)進(jìn)行序列化處理,減少占用的內(nèi)存,以盡可能多地緩存數(shù)據(jù),并采用一種新的緩存管理方法實(shí)現(xiàn)冷熱數(shù)據(jù)的分離,避免由于大量的隨機(jī)訪問使得熱數(shù)據(jù)被淘汰。
[0039]此外,數(shù)據(jù)緩存后,由于服務(wù)異常啟動(dòng)后,內(nèi)存緩存丟失,大量的業(yè)務(wù)訪問會(huì)“穿透”緩存直接訪問數(shù)據(jù)庫(kù)。
[0040]對(duì)此,本發(fā)明中進(jìn)一步定期將緩存的熱數(shù)據(jù)持久化到磁盤形成一個(gè)dmp文件,然后將緩存的更新情況記錄到日志(log)文件中。如果服務(wù)重啟,則用dmp文件恢復(fù)緩存中的熱區(qū)數(shù)據(jù),并讀取log文件(記錄了持久化后對(duì)緩存的修改),將log文件中對(duì)應(yīng)的修改記錄從恢復(fù)后的緩存中刪除,即可保證緩存的正確性。
[0041]為使本發(fā)明的目的、技術(shù)方案和優(yōu)點(diǎn)更加清楚,下面將結(jié)合附圖對(duì)本發(fā)明實(shí)施方式作進(jìn)一步地詳細(xì)描述。
[0042]1、將緩存數(shù)據(jù)序列化
[0043]將緩存數(shù)據(jù)按字段序列化到字節(jié)數(shù)據(jù)中,具體有如下特點(diǎn):
[0044]對(duì)于字符串(string)數(shù)據(jù),如果都是ASCII字符,每個(gè)字符占一個(gè)字節(jié),如果包含除ASCII以外的字符,如中文等特殊字符,則用UNICODE編碼,而不是UTF-8編碼,因?yàn)閁NICODE對(duì)中文編碼是2字節(jié),UTF-8通常是3字節(jié);
[0045]對(duì)于長(zhǎng)整型(long)數(shù)據(jù),如果長(zhǎng)度不夠8個(gè)字節(jié),則保留其實(shí)際數(shù)字需要的字節(jié)數(shù)。
[0046]這樣即可高效地完成序列化,將緩存對(duì)象的元數(shù)據(jù)全部剔除,只保留對(duì)象字段的編號(hào),占1-2字節(jié),并且序列化后的字節(jié)數(shù)據(jù)會(huì)相當(dāng)小。
[0047]圖1是本發(fā)明實(shí)施例中的應(yīng)用訪問數(shù)據(jù)的流程示意圖。如圖1所示,當(dāng)應(yīng)用從緩存獲取不到數(shù)據(jù)時(shí)訪問數(shù)據(jù)庫(kù)獲取數(shù)據(jù),同時(shí)該數(shù)據(jù)被序列化(緩存可以通過調(diào)用外部工具生成的緩存類對(duì)數(shù)據(jù)進(jìn)行序列化)后插入到緩存中,當(dāng)應(yīng)用再次獲取同一數(shù)據(jù)時(shí),從緩存中獲取該數(shù)據(jù)的序列化緩存,反序列化后返回給應(yīng)用。
[0048]2、新的緩存管理方法
[0049]本發(fā)明中給出了一種近似的最近最少使用(LRU, Least Recently Used)算法,因?yàn)榻^對(duì)的LRU算法實(shí)現(xiàn)代價(jià)太大,不適合在實(shí)際環(huán)境使用。本發(fā)明中的近似LRU算法的為:
[0050]在緩存中劃分出兩個(gè)區(qū)域,稱為冷區(qū)和熱區(qū)(例如冷區(qū)占總緩存的1/3,熱區(qū)占總緩存的2/3),冷區(qū)和熱區(qū)都采用雙向鏈表結(jié)構(gòu),包括多個(gè)節(jié)點(diǎn),圖2是本發(fā)明實(shí)施例中的雙向鏈表結(jié)構(gòu)的示意圖;將數(shù)據(jù)插入到緩存時(shí),先將數(shù)據(jù)放到冷區(qū);當(dāng)緩存中的數(shù)據(jù)被命中時(shí),如果是冷區(qū)數(shù)據(jù),判斷該數(shù)據(jù)是否已命中了預(yù)設(shè)次數(shù)(如3次),是則將其轉(zhuǎn)移到熱區(qū)的尾部,否則將其轉(zhuǎn)移到冷區(qū)鏈表的首部(具體來說將該數(shù)據(jù)從原冷區(qū)鏈表位置刪除,將其轉(zhuǎn)移到冷區(qū)鏈表的首部,相應(yīng)修改各個(gè)相關(guān)數(shù)據(jù)中的鏈表指針),如果是熱區(qū)數(shù)據(jù),將其轉(zhuǎn)移到熱區(qū)鏈表的首部(具體來說將數(shù)據(jù)從原冷區(qū)鏈表位置刪除,將其轉(zhuǎn)移到熱區(qū)鏈表的首部,相應(yīng)修改各個(gè)相關(guān)數(shù)據(jù)中的鏈表指針);
[0051]當(dāng)冷區(qū)滿時(shí),先判斷熱區(qū)是否有一定的空閑區(qū)域(例如500個(gè)空閑節(jié)點(diǎn)),是則將從冷區(qū)鏈表首部起不大于該空閑區(qū)域的一定量(例如300個(gè))的數(shù)據(jù)轉(zhuǎn)移到熱區(qū)的尾部,否則刪除從冷區(qū)鏈表尾部的一定量(例如300個(gè))的數(shù)據(jù);
[0052]當(dāng)熱區(qū)滿時(shí),先判斷冷區(qū)是否有一定的空閑區(qū)域,是則將從熱區(qū)鏈表尾部起不大于該空閑區(qū)域的一定量的數(shù)據(jù)轉(zhuǎn)移到冷區(qū)的首部,否則刪除從熱區(qū)鏈表尾部起的一定量的數(shù)據(jù)。
[0053]這種做法,使得經(jīng)常被訪問的數(shù)據(jù)被放到熱區(qū)或冷區(qū)靠近首部的位置,不易被淘汰。
[0054]在本發(fā)明的一個(gè)實(shí)施例中,熱區(qū)/冷區(qū)只存儲(chǔ)數(shù)據(jù)的引用,數(shù)據(jù)的實(shí)際緩存內(nèi)容存儲(chǔ)到一個(gè)字典中,即數(shù)據(jù)的實(shí)際內(nèi)容存儲(chǔ)在緩存中的一個(gè)字典中;因此,刪除從熱區(qū)/冷區(qū)鏈表尾部起的一定量的數(shù)據(jù)時(shí),除了刪除該數(shù)據(jù)在熱區(qū)/冷區(qū)中的引用,還要?jiǎng)h除其在所述字典中的對(duì)應(yīng)內(nèi)容。
[0055]3、持久化方法
[0056]每隔設(shè)定時(shí)間(例如I小時(shí))將熱區(qū)中的數(shù)據(jù)持久化到磁盤中,然后將熱區(qū)數(shù)據(jù)的更新情況記錄到日志文件中;當(dāng)緩存數(shù)據(jù)丟失時(shí),用磁盤中的數(shù)據(jù)恢復(fù)熱區(qū)數(shù)據(jù),并讀取日志文件內(nèi)容,從恢復(fù)的熱區(qū)數(shù)據(jù)中刪除日志文件中所記錄的發(fā)生更新的數(shù)據(jù)。
[0057]其中,將熱區(qū)中的數(shù)據(jù)持久化到磁盤中,將熱區(qū)數(shù)據(jù)的更新情況記錄到日志文件中具體為:
[0058]將熱區(qū)數(shù)據(jù)的引用讀到一個(gè)熱區(qū)數(shù)據(jù)列表中;
[0059]將熱區(qū)數(shù)據(jù)列表中的引用所對(duì)應(yīng)的數(shù)據(jù)寫到磁盤文件中,將這期間的熱區(qū)數(shù)據(jù)的更新情況記錄在第一哈希表中;
[0060]將第一哈希表中內(nèi)容寫到日志文件中,并將熱區(qū)數(shù)據(jù)的后續(xù)更新情況記錄到日志文件。
[0061]將熱區(qū)數(shù)據(jù)列表中的引用所對(duì)應(yīng)的數(shù)據(jù)寫到磁盤文件具體為:將熱區(qū)數(shù)據(jù)列表中的引用所對(duì)應(yīng)的數(shù)據(jù)先寫到第二磁盤文件中,寫入完成后將第二磁盤文件和第一磁盤文件的文件名互換,即將第二磁盤文件重命名為第一磁盤文件,而將原第一磁盤文件重命名為第二磁盤文件;
[0062]當(dāng)緩存數(shù)據(jù)丟失時(shí),用當(dāng)前第一磁盤文件中的數(shù)據(jù)恢復(fù)熱區(qū)數(shù)據(jù)。
[0063]將熱區(qū)數(shù)據(jù)的引用讀到一個(gè)熱區(qū)數(shù)據(jù)列表中包括:對(duì)熱區(qū)加鎖,然后將熱區(qū)數(shù)據(jù)的引用讀到一個(gè)熱區(qū)數(shù)據(jù)列表中;
[0064]進(jìn)一步地,在將熱區(qū)數(shù)據(jù)的引用讀到一個(gè)熱區(qū)數(shù)據(jù)列表期間,用一個(gè)標(biāo)記使得對(duì)熱區(qū)數(shù)據(jù)的讀訪問返回空數(shù)據(jù),而對(duì)熱區(qū)數(shù)據(jù)的寫訪問則將所訪問的數(shù)據(jù)的標(biāo)識(shí)記錄到第二哈希表中;在將熱區(qū)數(shù)據(jù)列表中的引用所對(duì)應(yīng)的數(shù)據(jù)寫到磁盤文件中之前,遍歷第二哈希表,將其中所記錄的數(shù)據(jù)從熱區(qū)數(shù)據(jù)列表中刪除。
[0065]圖3是本發(fā)明實(shí)施例中的持久化的一個(gè)流程示意圖。本例中以緩存的數(shù)據(jù)為即時(shí)通訊用戶的數(shù)據(jù),熱區(qū)和冷區(qū)只緩存數(shù)據(jù)的引用(這里為用戶的Id),數(shù)據(jù)的實(shí)際內(nèi)容緩存到一個(gè)字典中為例,下面參考圖3對(duì)本發(fā)明中的持久化方案舉例說明:
[0066]定期將緩存的熱區(qū)數(shù)據(jù)持久化到磁盤,持久化的過程包括如下步驟:
[0067]S11,對(duì)緩存中的熱區(qū)數(shù)據(jù)引用加鎖;
[0068]S12,將加鎖的熱區(qū)數(shù)據(jù)引用讀到熱區(qū)數(shù)據(jù)列表HotList中,在該過程中,用一個(gè)標(biāo)記使得對(duì)熱區(qū)數(shù)據(jù)的讀訪問返回空數(shù)據(jù),而對(duì)熱區(qū)數(shù)據(jù)的寫訪問則將對(duì)應(yīng)的用戶Id記錄到第二 Hash表中。將加鎖的熱區(qū)數(shù)據(jù)引用讀到熱區(qū)數(shù)據(jù)列表的這個(gè)過程非??欤呛撩爰?jí)別的,但是為了防止期間有數(shù)據(jù)讀取或修改可能會(huì)鎖爭(zhēng)用(毫秒級(jí)別也可能產(chǎn)生數(shù)十個(gè)業(yè)務(wù)訪問),用一個(gè)標(biāo)記,使得這些讀的業(yè)務(wù)直接返回空數(shù)據(jù),即沒有查到緩存,寫的訪問則將對(duì)應(yīng)的用戶Id記錄到內(nèi)存的一個(gè)第二 Hash表中(保證Id不重復(fù),以減少后續(xù)操作)。
[0069]S13,遍歷第二 Hash表,并將其中所記錄用戶Id從HotList中刪除。
[0070]S14,將HotList中的用戶Id所指示的字典中的數(shù)據(jù)寫到磁盤文件UserCacheBak.dmp,并將期間對(duì)緩存的修改記錄到第一 Hash表中。
[0071]S15,寫完UserCacheBak.dmp文件后,將其重命名為UserCache.dmp,而將原UserCache.dmp重命名為UserCacheBak.dmp。這個(gè)UserCache.dmp即作為最終的持久化文件。因?yàn)榭赡軙?huì)遇到寫UserCacheBak.dmp文件時(shí),服務(wù)維護(hù)性重啟或異常重啟的極少數(shù)情況,這樣緩存文件就會(huì)不完整,所以要待其寫好后再以重命名文件的方式形成最終的持久化文件。
[0072]S16,重寫日志文件,即先清空日志文件,然后把第一 Hash表中記錄的(寫UserCacheBak.dmp過程中產(chǎn)生的修改記錄的)用戶Id寫到日志文件,之后后臺(tái)線程會(huì)記錄相應(yīng)修改的用戶Id到日志文件,這樣可以使日志保持最小化的情況下,確保緩存的正確性。
[0073]服務(wù)重啟時(shí),熱區(qū)數(shù)據(jù)的恢復(fù)如圖4所示。
[0074]圖4是本發(fā)明實(shí)施例中服務(wù)重啟時(shí)熱區(qū)數(shù)據(jù)的恢復(fù)流程圖。如圖4所示,包括如下步驟:
[0075]S21,在磁盤中檢查是否存在UserCache.dmp文件;
[0076]S22,若存在,則使用UserCache.dmp恢復(fù)熱區(qū)數(shù)據(jù);
[0077]S23,讀取日志文件,將日志文件中記錄的用戶Id對(duì)應(yīng)的修改記錄從恢復(fù)的熱區(qū)數(shù)據(jù)中刪除??捎肬serCache.dmp將上一次Dump時(shí)緩存的熱區(qū)數(shù)據(jù)恢復(fù),并讀取日志文件(記錄了持久化后對(duì)緩存的修改),把其中記錄的用戶Id對(duì)應(yīng)的修改記錄從恢復(fù)后的緩存刪除,即可保證緩存的正確性。當(dāng)服務(wù)重啟時(shí),所有的熱區(qū)數(shù)據(jù)基本都會(huì)恢復(fù),即可保證大量的業(yè)務(wù)訪問能夠命中緩存。
[0078]綜上所述,本發(fā)明的技術(shù)方案提高了緩存的數(shù)量及命中率,有效降低了 MySQL數(shù)據(jù)庫(kù)一半以上的CPU占用;并且實(shí)現(xiàn)了緩存的持久化功能,可以保證在緩存服務(wù)在異常重啟后緩存中的熱區(qū)數(shù)據(jù)不會(huì)丟失,從而不會(huì)使得大量業(yè)務(wù)訪問直接“穿透”緩存到數(shù)據(jù)庫(kù)
[0079]以上所述僅為本發(fā)明的較佳實(shí)施例而已,并非用于限定本發(fā)明的保護(hù)范圍。凡在本發(fā)明的精神和原則之內(nèi)所作的任何修改、等同替換、改進(jìn)等,均包含在本發(fā)明的保護(hù)范圍內(nèi)。
【權(quán)利要求】
1.一種數(shù)據(jù)緩存方法,其特征在于,該方法包括: 將放入緩存的數(shù)據(jù)進(jìn)行序列化處理; 在緩存中劃分出兩個(gè)區(qū)域,稱為冷區(qū)和熱區(qū),冷區(qū)和熱區(qū)都采用雙向鏈表結(jié)構(gòu); 將數(shù)據(jù)插入到緩存時(shí),先將數(shù)據(jù)放到冷區(qū); 當(dāng)緩存中的數(shù)據(jù)被命中時(shí),如果該數(shù)據(jù)是冷區(qū)數(shù)據(jù),判斷該數(shù)據(jù)是否已命中了預(yù)設(shè)次數(shù),是則將其轉(zhuǎn)移到熱區(qū)的尾部,否則將其轉(zhuǎn)移到冷區(qū)鏈表的首部,如果該數(shù)據(jù)是熱區(qū)數(shù)據(jù),將其轉(zhuǎn)移熱區(qū)鏈表的首部。
2.根據(jù)權(quán)利要求1所述的方法,其特征在于,該方法進(jìn)一步包括: 當(dāng)冷區(qū)滿時(shí),先判斷熱區(qū)是否有一定的空閑區(qū)域,是則將從冷區(qū)鏈表首部起不大于該空閑區(qū)域的一定量的數(shù)據(jù)轉(zhuǎn)移到熱區(qū)的尾部,否則刪除從冷區(qū)鏈表尾部起的一定量的數(shù)據(jù); 當(dāng)熱區(qū)滿時(shí),先判斷冷區(qū)是否有一定的空閑區(qū)域,是則將從熱區(qū)鏈表尾部起不大于該空閑區(qū)域的一定量的數(shù)據(jù)轉(zhuǎn)移到冷區(qū)的首部,否則刪除從熱區(qū)鏈表尾部起的一定量的數(shù)據(jù)。
3.根據(jù)權(quán)利要求2所述的方法,其特征在于, 熱區(qū)/冷區(qū)存儲(chǔ)數(shù)據(jù)的引用,數(shù)據(jù)的實(shí)際緩存內(nèi)容存儲(chǔ)到一個(gè)字典中; 則上述刪除從熱區(qū)/冷區(qū)鏈表尾部起的一定量的數(shù)據(jù)具體包括: 刪除該數(shù)據(jù)在熱區(qū)/冷區(qū)中的引用,并刪除該數(shù)據(jù)在所述字典中的對(duì)應(yīng)內(nèi)容。
4.根據(jù)權(quán)利要求1所述的方法,其特征在于,所述將放入緩存的數(shù)據(jù)的進(jìn)行序列化處理包括: 對(duì)于字符串?dāng)?shù)據(jù),如果都是ASCII字符,每個(gè)字符占一個(gè)字節(jié),如果包含除ASCII以外的字符,則用UNICODE編碼; 對(duì)于長(zhǎng)整型數(shù)據(jù),如果長(zhǎng)度不夠8個(gè)字節(jié),則保留其實(shí)際數(shù)字需要的字節(jié)數(shù)。
5.根據(jù)權(quán)利要求1至4中任一項(xiàng)所述的方法,其特征在于,該方法進(jìn)一步包括: 每隔設(shè)定時(shí)間將熱區(qū)中的數(shù)據(jù)持久化到磁盤中,然后將熱區(qū)數(shù)據(jù)的更新情況記錄到日志文件中; 當(dāng)緩存數(shù)據(jù)丟失時(shí),用所述磁盤中的數(shù)據(jù)恢復(fù)熱區(qū)數(shù)據(jù),并讀取日志文件內(nèi)容,從恢復(fù)的熱區(qū)數(shù)據(jù)中刪除日志文件中所記錄的發(fā)生更新的數(shù)據(jù)。
6.根據(jù)權(quán)利要求5所述的方法,其特征在于,所述將熱區(qū)中的數(shù)據(jù)持久化到磁盤中,將熱區(qū)數(shù)據(jù)的更新情況記錄到日志文件中包括: 將熱區(qū)數(shù)據(jù)的引用讀到一個(gè)熱區(qū)數(shù)據(jù)列表中; 將熱區(qū)數(shù)據(jù)列表中的引用所對(duì)應(yīng)的數(shù)據(jù)寫到磁盤文件中,將這期間的熱區(qū)數(shù)據(jù)的更新情況記錄在第一哈希表中; 將第一哈希表中內(nèi)容寫到日志文件中,并將熱區(qū)數(shù)據(jù)的后續(xù)更新情況記錄到日志文件。
7.根據(jù)權(quán)利要求6所述的方法,其特征在于, 所述將熱區(qū)數(shù)據(jù)列表中的引用所對(duì)應(yīng)的數(shù)據(jù)寫到磁盤文件包括:將熱區(qū)數(shù)據(jù)列表中的引用所對(duì)應(yīng)的數(shù)據(jù)先寫到第二磁盤文件中,寫入完成后將第二磁盤文件和第一磁盤文件的文件名互換;當(dāng)緩存數(shù)據(jù)丟失時(shí),用當(dāng)前第一磁盤文件中的數(shù)據(jù)恢復(fù)熱區(qū)數(shù)據(jù)。
8.根據(jù)權(quán)利要求6所述的方法,其特征在于,所述將熱區(qū)數(shù)據(jù)的引用讀到一個(gè)熱區(qū)數(shù)據(jù)列表中包括:對(duì)熱區(qū)加鎖,然后將熱區(qū)數(shù)據(jù)的引用讀到一個(gè)熱區(qū)數(shù)據(jù)列表中; 該方法進(jìn)一步包括:在將熱區(qū)數(shù)據(jù)的引用讀到一個(gè)熱區(qū)數(shù)據(jù)列表期間,用一個(gè)標(biāo)記使得對(duì)熱區(qū)數(shù)據(jù)的讀訪問返回空數(shù)據(jù),而對(duì)熱區(qū)數(shù)據(jù)的寫訪問則將所訪問的數(shù)據(jù)的標(biāo)識(shí)記錄到第二哈希表中; 在將熱區(qū)數(shù)據(jù)列表中的引用所對(duì)應(yīng)的數(shù)據(jù)寫到磁盤文件中之前,遍歷第二哈希表,將其中所記錄的數(shù)據(jù)從熱區(qū)數(shù)據(jù)列表中刪除。
【文檔編號(hào)】G06F12/08GK103514106SQ201210209630
【公開日】2014年1月15日 申請(qǐng)日期:2012年6月20日 優(yōu)先權(quán)日:2012年6月20日
【發(fā)明者】王洪澤 申請(qǐng)人:北京神州泰岳軟件股份有限公司