經過前兩次的說明,相信你已經更加了解Redis的使用以及原理了。這次我要繼續透過Redis來介紹Cache。我們現在已經了解Cache就是用來分散對DB的壓力所產生的。那在現在分散式系統當道的情況下,你有沒有想過Cache到底在哪裡呢?
目前的Cache主要分為四大種類:
這個就是我們一般會常被使用到的快取,@Cache就屬於這類,原理是使用直接存放在本機記憶體的快取,做回應。
好處:簡單、速度快
壞處:萬一機器掛了就掛了。 If it falls, it falls.
假設一個情況,你在A主機中登入B系統後,填了一張很長的申請單,最後你因為要驗證身分而跳轉到外部網站,驗證成功後轉回伺服器,卻因為B系統的Load Balance作用而被導到C主機,而C主機沒有A主機的快取資料,也意味著你所有資料必須要重新填寫。
為了避免這名可悲的孩子大唱 “ fuck this shit I’m out. “,B系統的其中一種解決方案就是確保在A主機存放的快取資料要與C主機的快取資料同步,也就是說A C 會擁有同樣的快取資料。
好處:避免了本機快取導致取不到資料的失敗狀況。
壞處:同樣的快取資料要備份至不同主機、導致產生了需要在多點維護一致性的議題,不僅會比較慢,功能也會變得比較複雜,請試想你有超過10台以上的主機隨時都在互相同步。好傢伙,看來想唱 “fuck this shit I’m out” 的應該不是使用者而是你的主機。
前面我們提到了Global Cache會在多台主機重複存取同一份( 整體上來說可以這麼說 ) 快取,為了解決這個重複存取而耗費的空間,分散式快取就誕生了,它同樣有多台伺服器進行Cache,但每台存取的資料都是不一樣的,與本機快取的差異是,它會在一台伺服器中沒有找到的情況下前往下一台伺服器進行查找。
好處:方便水平擴展容量、加入一台新主機時不需要大量調整快取的資料。
壞處:失去Global Cache的備份功能,在這樣的結構下,壞了一台的快取可能會影響所有主機的快取 ( 因為是一個鍊狀結構去搜尋的 )
CDN 提供的是一個代理伺服器,一個具備CDN服務的網站是這樣的。假設我訪問Youtube看貓貓廢片,我在訪問Youtube之前會透過一個位於台灣的代理伺服器,在我看完貓貓後空翻之後,影片就會被儲存在台灣的代理伺服器中。接著下一個想要看貓貓廢片的用戶,Youtube就可以直接使用存在放台灣代理伺服器中的快取貓貓廢片給那名使用者。
另外,這些提供CDN服務的廠商大多都是小有規模的,也就是說成本可以交由外部處理,因此現在大多數人都想採用CDN服務。
但不管我們最後採用哪種方法,只要我們還是使用超過一台主機去處理外部請求,就會有一致性的議題,除了各地的Cache,與Database之間盡量維持一致性也是至關重要的。畢竟,若是資料庫與快取的資料不同,就和暈船一樣,就沒救了。
目前針對快取與資料庫維持一致性的方法有三種,三者也有各自的trade off:
當一筆資料存入時,同時既放入資料庫也放入快取,好處是可以保持兩者一致性。
trade off:一筆資料卻有兩次存入,寫入的延遲將會變高。
寫入資料時只寫入資料庫,之後再透過DB的設定去更新Cache。
trade off:cache無法確保為最新資料,資料的存取快,但讀取慢,可能資料快取沒有同步到、或是快取的資料並不是正確的,這些壓力最後會回到資料庫身上
資料庫先寫進快取,接著再利用排程將快取逐步寫進資料庫。
trade off:資料的一致性倚賴 in memory 服務,假設Redis炸了,你所有存放在Redis的資料就GG惹。fuck this shit I’m out. (假設你Redis沒有實作RDB這類的架構的話)
可想而知,這些選項往往都沒有最好的解決方案(如果其實有的話請跟我說),我的理解是最後我們只能夠選擇最適合我們使用情境的哪一種策略。
接受它的好處、並忍受它的壞處,僅次而已。怎麼變得好像在探討人生…算了。
今天的部分就到此為止了,我們明天見吧。