數據庫緩存的幾種方式
引入緩存可以提高性能,但是數據會存在兩份,一份在數據庫中,一份在緩存中,如果更新其中任何一份會引起數據的不一致,數據的完整性被破壞了,因此,同步數據庫和緩存的這兩份數據就非常重要。本文介紹常見的緩存更新的同步策略。
預留緩存Cache-aside
應用代碼能夠手工管理數據庫和緩存中數據,應用邏輯會在訪問數據庫之前檢查緩存,在數據庫更新以后再更新緩存:
上圖中Cache update緩存更新時,通過手工編碼分別對數據庫save(entity)和緩存(put(key,entity))做更新,將這種瑣碎的緩存管理和更新夾雜在應用邏輯中並不是一種好方式,可以采取AOP面向方面攔截器等方式實現緩存操作,減輕緩存操作泄漏到應用代碼中,同時確保數據庫和緩存都能正確同步。
Read-through
相比上面同時管理數據庫和緩存,我們可以簡單委托數據庫同步給一個緩存提供者,所有數據交互通過這個緩存抽象層完成。
圖中CacheStore是我們的緩存抽象層,當我們應用通過其抓取一個緩存數據時,這個緩存提供者確認緩存中是否有該數據,如果沒有,從數據庫加載,然后放入緩存,下次以后再訪問就可以直接從緩存中獲得。
Write-through
類似於Read-through的數據抓取策略,緩存能夠在其中數據變化時自動更新底層數據庫。
盡管數據庫和緩存同步更新了,但是我們也可以按照我們自己的業務要求選擇事務的邊界:
- 如果需要強一致性,,並且緩存提供者提供了XAResource ,這樣我們可以在一個全局事務中完成緩存和數據庫的更新,這樣數據庫和緩存更新是在一個原子單元:single atomic unit-of-work
- 如果只需要弱一致性,我們可以先后更新緩存和數據庫,不必使用全局事務,這會讓我們提升快速響應性與性能,通常緩存首先被更新,如果數據庫更新失敗,緩存可以通過補償動作實現回滾當前事務所做的改變。
Write-behind
如果強一致性不是必須的,我們可以簡單將緩存的更新放在隊列中,然后定期批量地去更新數據庫。
這種策略雖然打破了事務保證,但是性能要遠遠超過write-through,因為數據庫能夠快速批量更新,事務機制不再需要。