• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
如何建立有效的快取
 

如何建立有效的快取

on

  • 3,666 views

由論壇系統為範例,如何實做快取系統。

由論壇系統為範例,如何實做快取系統。

Statistics

Views

Total Views
3,666
Views on SlideShare
2,697
Embed Views
969

Actions

Likes
6
Downloads
8
Comments
0

2 Embeds 969

http://ricky.ez2.us 965
http://webcache.googleusercontent.com 4

Accessibility

Categories

Upload Details

Uploaded via as OpenOffice

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    如何建立有效的快取 如何建立有效的快取 Presentation Transcript

    • 如何建立有效的快取
    • Who am I
        Ricky 是我
      • http://ricky.ez2.us/
      • [email_address]
      • http://www.plurk.com/rickysu
    • 系統隨著時間資料越來越多
    • 資料庫越跑越慢
    • 到了某天再起不能
    • 怎麼辦 ?
    • 放乖乖
    • 解決方法
      • 買台更強壯的機器。 很貴,而且老闆通常拿不出 $$ 。
      • 改用MySQL Replication。 得先改寫程式讓 sql 讀寫分離, 而且不易維護。 只有解決分流的問題,慢的查詢還是一樣慢。
      • 改用 NoSQL DB 取代 MySQL 。 只能說心臟很大顆,除非有強力後盾,否則別輕易嘗試。
    • 難道沒有其他方法 ?
    • 建立 Cache 吧
    • Cache必須滿足以下幾個條件
      • 快。 Cache 系統必須非常快,不然就失去意義了。
      • 是可有可無的。 在 Cache 失效的情況下,系統還是能正常運作。
      • Cache 必須易於擴展。 當 Cache 儲存空間滿了,可以透過增加 Server 的方式平行擴展。
    • 快取的儲存媒體
      • Memcached http://memcached.org/
      • Redis http://redis.io/
      • TokyoTyrant http://fallabs.com/tokyotyrant/
    • 讀取資料 是否存在快取中 傳回資料 由DB中取得資料 寫回快取
    • 寫入資料 刪除快取 回寫DB
    • 人生最厲害的就是這個 But
    • Key Value DB 在不知道 Key 的情況下如何刪除資料 !
    • 情境模擬
        使用者修改了一篇文章,得同步刪除相關的文章快取。
      • 刪除全部文章的快取。
      • 刪除分類文章的快取。
      • 刪除某天發表的文章快取。
    • 天阿,這得先統計出一堆 Key ,才能刪除快取。
    • 幫資料加上 Tag 吧
    • Ricky 的所有文章的第 2 頁分頁內容快取 key Article:ricky:All/Page:2/RowsPerPage:10 Value 快取內容 Tag Article:ricky:All -> 時間 (2011/10/03 13:10:43) 建立快取資料 Global Tag Article:ricky:All Key Tag:Article:ricky:All Value 2011/10/03 13:10:43 如果Global Tag 不存在時建立
    • 刪除快取
      • 更新文章時刪除Global Tag $Memcache->delete('Tag:Article:ricky:All');
    • 讀取資料 Ricky 的所有文章的第 2 頁分頁內容快取 key Article:ricky:All/Page:2/RowsPerPage:10 Value 快取內容 Tag Article:ricky:All -> 時間 (2011/10/03 13:10:43) Global Tag Article:ricky:All Key Tag:Article:ricky:All Value Not Exist 比對Tag的更新時間
    • 讀取快取 依序取出Tag 比對Global Tag 更新時間 快取失效 是否還有其他Tag 回傳快取資料
    • 原理是如此 Zend_Cache 已經實做 Tag 不要再做輪子了
    • 實際案例 討論區的快取建立
    • 資料結構
      • Board 討論版
      • Topic 討論主題
      • Message 文章內容
    • 將查詢介面統一 別讓 SQL 四散各地
    • 取得討論版的主題列表
      • Method: FindTopicsFromBoard Input: $BoardID , $Page , $RowsPerPage Return: $Topics
      • Key: FindTopicsFromBoard/BoardID: $BoardID /Page: $Pag e/RowsPerPage: $RowsPerPage
      • Tag: Tag:BoardTopics/BoardID: $BoardID
    • Example Code static public function FindTopicsFromBoard ( $BoardID , $Pages , $RowsPerPage ){ if( $Topics = $Cache -> get ( ''FindTopicsFromBoard/BoardID: $BoardID /Page: $Page /RowsPerPage: $RowsPerPage '' )){ reutrn $Topics ; } return self:: rebuildFindTopicsFromBoard ( $BoardID , $Pages , $RowsPerPage ); } static public function rebuildFindTopicsFromBoard ( $BoardID , $Pages , $RowsPerPage ){ // do db query $Cache->set( ''FindTopicsFromBoard/BoardID: $BoardID /Page: $Page /RowsPerPage: $RowsPerPage '' , $Topics , //Data array( ''Tag:BoardTopics/BoardID: $BoardID '' //Tag ) ); return $Topics ; }
    • 取得某個主題的訊息串
      • Method: FindMessagesFromTopic Input: $TopicID , $Page , $RowsPerPage Return: $Messages
      • Key: FindMessagesFromTopic/TopicID: $TopicID /Page: $Pag e/RowsPerPage: $RowsPerPage
      • Tag: Tag:TopicMessages/TopicID: $TopicID if $Page is LastPage Tag:TopicMessages/TopicID: $TopicID /LastPage
    • 發表新主題
      • DB動作 topics insert new row message insert new row
      • 刪除對應的Tag 更新討論版 Tag:BoardTopics/BoardID: $BoardID
    • 回覆主題
      • DB動作 message insert new row
      • 刪除對應的Tag 更新討論版 Tag:BoardTopics/BoardID: $BoardID 更新訊息串 Tag:TopicMessages/TopicID: $TopicID /LastPage
    • 編輯或刪除訊息
      • DB動作 update or delete message row
      • 刪除對應的Tag 更新訊息串 Tag:TopicMessages/TopicID: $TopicID
    • 刪除整個討論串
      • DB動作 delete topic row delete all message rows about topic
      • 刪除對應的Tag 更新討論版 Tag:BoardTopics/BoardID: $BoardID 更新訊息串 Tag:TopicMessages/TopicID: $TopicID
    • 善用 Key Value DB 的特性 透過多次的查尋取代 join
    • 情境模擬 連結到第一篇文章 主題發布者 分頁
    • 使用SQL查詢解決
      • 在主題列表中需要統計文章回覆數量,以及最後更新時間,甚至是分頁。
      • 解決方法 1. 在取得文章頁表時join message table,取得 回覆文章數量,以及最後更新的時間,和 最新回覆的使用者。 2.在topic table中建立快取欄位。當訊息回覆 時同步更新到topic table。
    • 使用快取解決
      • FindTopicsFromBoard 只回傳Topic ids。
      • 透過FindMessagesFromTopic取得每個Topic的詳細統計資料。 $Page=1取得第一頁,順便建立快取。 $Page=LastPage 取得最後一頁,也順便建立快取。
      • 主題發起人=>第一頁的第一篇文章
      • 最後回覆=> 最後一頁的最後一篇文章
      • 文章回覆數 => 由最後一頁的頁數就可以推算出來。
    • 使用快取解決的好處
      • 更新資料時只需刪除對應的Tag。
      • 減少寫入DB時必須同步更新快取欄位的問題。
      • 如果搭配template快取,效果更佳。
    • 導入快取前資料庫請先正規化
    • 如果遇到寫入頻繁的欄位怎麼辦
    • 利用延遲寫入的方式來解決
      • 在DB中建立一筆延遲寫入Log。
      • 將資料寫回快取中。
      • 每隔一段時間由Log中找出延遲寫入的紀錄,回寫DB,並刪除快取。
    • Thanks