今天我想特別介紹這一套 Ruby library: Moneta
它提供了 key-value stores 標準共通的使用介面,讓你可以用相同的程式,但是可以輕易轉換底層實際使用的儲存庫,包括:
- Basic File Store
- BerkeleyDB
- CouchDB
- DataMapper
- File store for xattr
- In-memory store
- Memcache store
- Redis
- S3
- SDBM
- Tokyo
- Xattrs in a file system
它的用法其實跟 Hash API 差不多,非常容易使用。我認為最實際的用途是用在撰寫快取程式了。
因為不同環境可以輕易切換 store 的這個好處,我在 local 的 development 環境中,可以使用 In-memory store 或 File Store (前者重開 server 快取資料就會消失,後者則會留著),不需要多裝東西就可以寫快取。更重要的是,團隊中其他人也不需要費心設定 (叫每個人都去裝 Memcached 也太辛苦了)。而在 production 正式環境中,則可以輕易設定成使用 Memcached。
我自己也用了 Moneta 介面寫了一個小程式 Headcache,提供了 get_and_set 功能:
data = Handcache.get_and_set("data-123", :expires_in => 60 ) do
"cached-foobar"
end
如果快取存在,就回傳快取資料;如果不存在,就執行 code block,並將最後的運算值回傳並快取起來。
如果是在 View 中搭配 partial 使用也非常簡單:
<%= Handcache.get_and_set( dom_id(@post), :expires_in => 60 ) do
render :partial => "post"
end %>
設定的方法則可以是:
# config/environments/development.rb
begin
# for developer has tokyo cabinet
Handcache = Moneta::Tyrant.new( :host => 'localhost', :port => 1978 )
rescue
# for developer has not tokyo cabinet
Handcache = Moneta::BasicFile.new( :path => "tmp" )
end
關於快取這件事情的學問,可以參考我之前的 Memcached 文章:一是如何清除過期的快取資料(expire),二是注意快取 Key 的命名。