剛剛開始研究memcache,覺得memcache key的設計其實是十分重要的,搜了搜,感覺資料不是很多,下面這些資料主要是從官網上獲得的,有些地方可能不太精确,僅供參考。
初始化memcache client
某些用戶端的實作可能允許重複添加同一個server,但最好每個server是有一個執行個體,而且也要注意他們的順序最好不要經常變化,防止key的重新映射;在初始化memcacheclient的時候要注意執行個體化的次數,不要太過頻繁的執行個體化,最好通過連接配接池來管理。
封裝一個sql作為key
memcache在減輕資料庫負載方面發揮着重要的作用,我們最常使用的場景也是用它來減少資料庫查詢次數,下面這個例子就是通過cache緩存查詢資料庫結果的場景,把sql+userid作為一個key,相同使用者第二次查詢時就可以從緩存中直接提取:
注意:在通過set方法緩存資料時,我們可以指定資料過期時間,上面例子中設定的是5分鐘,這樣的話,五分鐘内使用者看到的都是同樣的資訊,即5分鐘内的資料變化使用者是感覺不到的,在開發時一定要注意根據實際情況對過期時間進行合理設定。
封裝多個查詢sql作為key
有些處理過程是複雜的,可能會用到多個sql,如果我們能把這些複雜的處理最後封裝成一個key,這是最理想的結果。比如下面這個例子,我們把sql1+sql2+userid作為一個key,這樣,我們兩次查詢的結果便封裝成了一個cacheitem:
緩存object類型的資料
某些語言比如java可以把對象進行序列化,進行序列化的對象就可以像普通字元串資料一樣進行緩存了,但要注意的是,序列化和反序列化會耗費cpu時間,在緩存時僅僅序列化需要緩存對象會提高系統效率。
緩存一個片段(網頁)
memcache不僅僅可以用來減少資料庫查詢,任何可以提高我們應用速度的地方我們都可以用它來解決,比如下面這個例子,加載一個使用者模闆是非常耗時的,但是我們可以把一個封裝好的模闆(甚至是整個網頁)緩存起來:
key = 'frag-bio:' . user_id
在某些情況下,我們希望一系列的key隻存儲到一台伺服器緩存中,比如我們在顯示一個使用者首頁的時候,需要緩存他的姓名、年齡、履歷、好友、日志等資訊,而通常情況下用戶端hash算法會把它們的key映射到叢集中的每一台機器的緩存中,如果這樣的話,我們在查詢一個人的首頁時會從多台機器上取資料,會耗掉很多網絡傳輸、hash映射等時間,這是完全沒有必要的,我們需要一種機制,在用戶端内部把這些key組成一個group-key(可以是userid)。
其它需要注意的地方
資料有效性:某些時候我們需要保證對cache中的資料進行同步,不要讓使用者感覺到自己用到的是過期的髒資料。
資料過期:我們可以設定緩存中的資料過期時間,最大過期時間是30天,如果參數值為0,則表示永不過期(lru算法會自動删除需要删除的資料)。
删除cache中資料:最直接的讓cache資料過期的辦法就是delete。
key的值越短越好:key的大小被限制在250個位元組(将來可能達到6k),key的長度會影響hash算法尋找value值的效率,也會浪費更多記憶體空間(期間有對key的copy)。
使用僞命名空間
memcache并不支援命名空間(其設計哲學就是簡單高效),但是我們可以模拟實作它。比如,我們可以把一個使用者的所有key都歸檔在一個命名空間下,比如可以把字首設計為:user_namespace+userid。
緩存set 或 list
存儲集合到緩存的意思是把一個集合的所有資料作為一個cacheitem儲存到緩存中,當然,具體的實作方式有多種。不過需要注意一點的是,memcache的每個item有不能超過1mb的限制,那麼,我們該如何存儲一個超大資料量的集合呢?
方案一:分二個階段把資料緩存到cache
第一個階段存取的不是所有集合的資料,而是集合資料每一項的id,然後第二階段再把每個id對應的資料對象存到緩存中。當然,當一個集合特别大的時候,所有的資料的id有可能也會超過1mb的限制,那麼我們在第一階段存儲時指定每個集合的數量即可。這麼做還有個好處就是當我們在更新一個資料條目的時候僅更新指定id的項目即可。
方案二:一個階段分批次把資料存取到cache
比如有30000條資料,我們可以每批次100條分300批次緩存到cache。