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 原理解說

  1. 先將tags裡的tag產生 'tag:'.$name.':key' 這樣子的key,搭配uniqid() 以forever的方式存在Cache中給每個tag都有個id
     
  2. 在我們真正要存入Cache時  Larave 就會將我們要儲存的key以陣列的方式與上述的tag id以陣列的方式存入Cache,當你使用多個tag時就會把你的Key存入各自Tag的陣列中
     
  3. 最後在用一般的方式存入將你的key/value存入Cache
     
  4. 我們要刪除快取時,反過來他會將上述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