同時使用Redis緩存和Google Guava本地緩存注意事項(深拷貝和淺拷貝)


[TOC]

1、問題場景及說明

系統中同時使用 Redis 緩存和 Guava本地緩存。用 Guava 緩存將 Redis 緩存包了一層。可以提升效率,但是也會引出一些問題。

問題:同一個本地緩存Map,獲取到的值有時會不一致。 不同機器可能不一致,同一機器也可能不一致。很神奇,但是數據庫里都是對的。

后來發現,因為有一個請求會對該緩存進行remove操作,導致緩存改變。 如果這個請求到某個機器上,該台機器上的緩存就會被修改。 同時緩存過期時間為一分鍾,過期之后獲取到的緩存是正常的。如果該台機器沒有再次接收到請求,那么緩存就正常;如果再次接收到,緩存就異常了。

2、Redis 緩存是深拷貝

從 Redis 中獲取緩存時,系統中的數據對象是 Redis 緩存的副本。 對該對象的任何操作都不會影響 Redis 中的緩存,后續再次獲取還是修改之前的數據。 除非執行Redis的更新操作。

3、Guava本地緩存直接獲取則是淺拷貝

以獲取一個MAP為例:如果直接從緩存中取,則是淺拷貝。 對緩存數據的任何操作都會同時修改緩存中的數據,下次從緩存中獲取則是修改之后的數據。

一般不會修改從緩存中獲取到的數據,但如果要修改,則需注意Redis和Guava的不同。

4、如何實現Guava獲取本地緩存是深拷貝?

**方法:**可將Guava的get方法封裝一層,將緩存中獲取到的數據包裝為一個新對象返回,以后直接使用封裝后的方法。

**注意:**這會影響Guava的性能,畢竟每次都需要構建一個新對象返回。

**建議:**本地緩存適合直接獲取的場景,沒必要包裝通用get方法。 如果要修改獲取到的數據,在修改的地方深拷貝一份操作即可。 即可利用Guava的優越性,又可實現需要修改數據的邏輯。 只是要注意,修改時不能直接操作原始對象,需操作深拷貝之后的對象。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM