ScalingRails 16 Mar 2009 09:00 am

推到 Twitter!
推到 Plurk!


Scaling Rails - 第八章 Memcached



什麼時候要用上 Memcached?

以 Blog 為例好了,也許 Cache 最直覺的作法就是用 Page Caching。但當站越來越大,比如說你設計了一個功能叫做「Friends」,這一頁會把你所有好友的 Recent Post 拉出來 render 成一頁。

也許想想,Page Caching 還是可行啊,但是這樣就會造成一個很蠢的結果。以 LiveJournal 為例,如果還是使用 Page Caching 的策略,就會製造出 17.5 million 的 firneds pages,因為 LievJournal 上就有 17.5 million 的使用者,簡直是令人無語。

vlcsnap-110145-crop

不過這樣似乎還是 doable 的。但是,當再繼續檢視下去呢,每一篇 Post 的 Display 是會去檢查 Security Level ( Public / Private / Group ) 的。每個人看到的頁面會依據權限的不同,產生不同的結果。因此會有 17.5 milliaon versions of 17.5 million friends pages,瘋了!

看起來使用 Action Caching 沒望,也不能指望 Action Caching 或 Fragment Caching 了。那還剩什麼解法呢?

但此時我們還有一種作法可解,把結果的 Array Cache 起來,丟進 memcache!

vlcsnap-115859

如果已經 cache 了,就直接把結果丟回去。如果還沒,就從 database 裡撈。

那麼什麼是 Memcached 呢?這裡是比較冗長的版本:

vlcsnap-116527-crop

簡短的版本: {} (Hash) in Memory!

vlcsnap-117529-crop

如何在 Rails 裡使用 memcache 呢?在 config 裡指定:

RUBY:
  1. confug.cache_store = :mem_cache_store

有兩種用法:

1. Object Store ( Like LiveJournal)
2. Fragment Cache Store ( Action & Fragment Caching)

vlcsnap-118211-crop

vlcsnap-119778-crop

開 script/console 看會比較清楚怎麼操作讀寫:

vlcsnap-120505-crop

除了一般字串外,也可丟 ActiveRecord Object

vlcsnap-121155-crop

可用 fetch 的方式

vlcsnap-121322-crop

避免處理 Cache Expiration,可以用 :expires_in 的方式作。

vlcsnap-121740

除了在 Model 內做外,也可以在 View 裡面這樣作。這樣每三十分鐘才需要重新 query 一次。

vlcsnap-124717

第二種 避免 Cache Expiration 的方式是用 Intelligen keys 。 但在講述此章節之前,要先深入理解一下 memcache 運作的方式。

運行 memcached -m 2000 時,memcached 會叫起 2 G 的記憶體供使用,當用滿的時候,memcached 夠聰明的會 pop stack ..。使用 memcached ,We can push data we never plan to expired。

vlcsnap-126239

看看這個使用 Fragment Caching 的 view。其實可用加上 updated_at 的 timestamp 配合 memcached 弄出更好的作法。就可以省掉煩惱 Cache Expiration ...

vlcsnap-129840

但每個需要 Fragment Caching 的 view 都需要這樣手寫 key 自己惡搞嗎?不,其實 Rails 已經內建了更方便的用法...

vlcsnap-131651-crop

但如果遇到以下這種需要拉大量有關於 Post 與 User 的狀況呢?其實是可以丟 Array 的,會自動產生這種型態的 key。還可指定用途,如 for sidebar 使用。

vlcsnap-133430-crop

接下來就用 Flickr 來舉例吧。在 Fickr 上每單張的相片右下角都有一塊 "Additional Information",當作者修改照片敘述或權限過後,才會需要更新。這種資訊就蠻適合這樣做的:

vlcsnap-134817-crop

又如相片下的 comment,又要怎麼實做 Cache 呢?作法:配合 comment 數量作 key:

vlcsnap-136941

我們以上討論了怎麼實做,那麼什麼時候是適合用此法的時機:

1. 當使用 Action Caching 或 Fragment Caching 時。
2. 想減少 db hits 時。

vlcsnap-138512-crop

下一章是 EngineYard 的 Staff :Taylor Weibley 的 Interview。

Creative Commons License

2 Responses to “Scaling Rails - 第八章 Memcached”


  1. on 02 Dec 2009 at 9:27 pm 1.燃魂纵宇 said …

    多谢。

    confug.cache_store = :mem_cache_store
    =>
    config.cache_store = :mem_cache_store

  2. on 28 Feb 2010 at 5:14 pm 2.Blog.XDite.net » Scaling Rails Site:Reading Material # 3 said …

    [...] 另外,Rails 有 API 可支援直接對 Cache ( memcache )的讀寫操作。請閱讀:Scaling Rails - 第八章 Memcached [...]

Trackback This Post | Subscribe to the comments through RSS Feed

Leave a Reply