2016-07-07 32 views
2

我有一個休息api,它將一個記錄插入數據庫,其ID爲entityId。我有一個HashMap,它保存了entityId和實體對象,它在這裏作爲一個緩存。訪問被用作緩存的HashMap

只是在插入實體並更新緩存(HashMap)時,當我查找時,它有時無法從緩存中找到該ID。

注: - 我正在運行在一個循環的REST API,並做了負載測試,以驗證對象總是存在於高速緩存

在這方面的任何幫助,高度讚賞。什麼可能是無法從緩存中找到id的原因。

+1

請問編碼 – Chinni

+0

是不是ConcurrentHashMap?課程的範圍是什麼?更新緩存之後你正在做日誌記錄嗎?如果是,你可以看到ID? – HRgiger

+0

是的,當我做一個日誌記錄時,我發現最新值出現在地圖中。但我嘗試使用ma.getValues()方法獲取值,新添加的值沒有反映出來。 – VKR

回答

0

這取決於您的負載測試正在運行的方式以及後續寫入和讀取請求之間的時間間隔。

雖然更重要的是你的Cache/Hashmap被更新的方式。

Are you updating the HashMap BEFORE inserting into the Database 


Are you updating the HashMap AFTER inserting into the Database. 

如果你這樣做插入寫入到數據庫後,就會有可能會存在滯後之前HashMap中得到更新,這意味着,當讀取後續請求進入HashMap中尚未更新然而。

在將請求添加到HM的時間點以及讀取請求進入時間的日誌中,可能值得在日誌中添加。這可能會讓您對HashMap實際上是否已實現是否更新。

+0

爲什麼HashMap在插入數據庫後得到更新會有滯後? – VKR

+0

這取決於將記錄插入數據庫需要多長時間,以及您的連接如何設置到數據庫。但是如果你在數據庫插入後更新HashMap,它可能意味着在HashMap更新之前的幾百毫秒。而且由於您提到您正在循環執行此操作,因此可能意味着即使在此更新之前,您讀取的REST API也會被觸發。我不是說這可能是問題,我只是暗示它可能是一個潛在的原因。 –

0

的HashMap不是線程安全的,看到the API documentation

注意,此實現不是同步的。如果多個線程同時訪問哈希映射,並且至少有一個線程在結構上修改了映射,則它必須在外部同步。 (結構修改是指添加或刪除一個或多個映射的任何操作;僅更改與實例已包含的鍵相關聯的值不是結構修改。)這通常通過同步某個自然封裝映射的對象來實現。如果不存在這樣的對象,則應使用Collections.synchronizedMap方法「映射」該映射。這最好在創建時完成,以防止對映射進行意外的不同步訪問:

Map m = Collections.synchronizedMap(new HashMap(...)); 

的插入到你正在描述只能算作一個結構修改地圖。

改爲使用ConcurrentHashMap,更新不會像上述代碼與synchronizedMap一樣鎖定整個數據結構。

如果問題是新值在其他線程不需要使用它之前就沒有進入緩存,只是因爲線程正在快速連續訪問相同的代碼,所以使用緩存可能會更好錯過比引入瓶頸。最好不要在插入時緩存結果,而是等待第一個選擇查詢(在提交插入之後的新事務中),這樣可以避免將條目添加到緩存然後事務回滾的情況,在緩存中留下無效數據。

此外還有使用大量內存存儲條目未使用的危險。您可以讓工作線程定期檢查過期的項目。

緩存是比看起來更難的東西之一。考慮使用ehcache作爲在此處滾動您自己的解決方案的替代方案。