Cache重構說明
目前Cache處理的方式
-
利用getKey產生一個有規則前置字串(prefix)
例:version:v1:FundController:paginate
-
清除時搜尋Redis前置字串相同或正規表示對Redis進行快取清除的動作

產生的問題
- 管理困難:因為資料在不同的地方產生不同的Cache如Controller版本會不同或快取的地方不同造成Key不一樣難以管理
-
Cache清除死角:容易沒清除到相關資料或關連資料,或是在要寫清除相關快取時取要先組出prefix 才可清除相關的快取
- 清除Cache廢時:目前有許多要清除相關Cache時都必需要跑Queue,因為我們必需要去用正規表示法Match Redis中的Key並刪除,這是一件很累的事
預計改善的方式
- 使用Laravel 原生的Tags將所有的快取貼上標籤,改善目前Tags雜亂難以管理的問題
- 重構Foundation\Cache 改為 Foundation\Cache\CacheService.php 統一管理四散的Cache處理程式及Const,並集中管理Tag
- 雙軌制逐步改善目前程式碼使用快取的方式
-
移除CacheDeleteJob的方式,背景刪除快取,盡量使用Event Listener的方式清除快取,或即時清除
-
新增單一指令取代 Commands\CachePurge 下所有指令,改用Tags群組方式清除快取
-
移除Services\CacheDeleteService.php的使用
預計改善後的優點
-
可及時同步資料正確性,及延長快取時間
-
增加系統對快取的掌握度更高,讓快取有統一的群組規則可遵循
-
及對目前清除快取的方式進行程式減肥計畫
- 最好的快取生命週期是快取一直存在直到他預期的資料變動為止
改善後可能面臨的問題
-
因為清除快取時是清除整個群組清除,所有有可能會導致,非該筆更新資料的快取被清除的可能性
- 配套:所以在進行Tag時要盡量範圍小及明確,才可以控制清除快取所影響到的範圍,並在交叉使用資料時使用複數個Tag
例如:基金資料的快取的Tag包含的原始資料來源有,
基金資料本身 FUND
基金公司 FUND_COMPANY
基金投資地區 FUND_INVESTMENT
基金群組 FUND_GROUP
那他的Tags就應該包含上述這四項Tags來確保快取清除時可一併更新清除
單元測試的影響
- 所有未來預計調整到的快取都將會影響到單元測試的Mock
- 故取代舊寫法時,預計移除defaultMockCache,更嚴格的測試快取的使用
CacheService說明

使用實例

清除快取

Laravel Tag 原理解說
-
先將tags裡的tag產生 'tag:'.$name.':key' 這樣子的key,搭配uniqid() 以forever的方式存在Cache中給每個tag都有個id
-
在我們真正要存入Cache時 Larave 就會將我們要儲存的key以陣列的方式與上述的tag id以陣列的方式存入Cache,當你使用多個tag時就會把你的Key存入各自Tag的陣列中
- 最後在用一般的方式存入將你的key/value存入Cache
- 我們要刪除快取時,反過來他會將上述2中Cache中tag與key關聯的值以loop的方式將快取清除後,並重新產生一組tag id
Laravel Tag 清除舉例
基金列表
(?minutes)
Fund
FundCompany
FundCategory
FundInvestment
FundNavHistory
FundCompany(CMS)
FundCategory(CMS)
Funds(1 Days)
FundInvestmentArea(CMS)
FundNavHistory (15minutes)
Cache::tags('YOUR_TAG')->flush();
Laravel Tag 清除舉例
單一基金
Tags
SingleFund
FundCompany(CMS)
FundCategory(CMS)
Funds(1 Days)
FundInvestmentArea(CMS)
FundNavHistory (15minutes)
Cache::tags('YOUR_TAG')->forget('YOUR_KEY');
Laravel Tag 總結
1. Tags可用來取代有關係的資料快取,方便清除
2. 當然單一資料也可以單獨清除,適用小範圍
Q & A
deck
By Seta Chuang
deck
- 716