正確理解memcached,才能更好的使用
基於memcached官方wiki,寫了幾篇 memcached 內部機制的文章,比如記憶體分配、LRU的工作原理。接下來從應用的角度說說memcached,只有從正確的角度理解,才能更好的應用,否則就會出現很多誤解,比如有時候比較memcached和redis是毫無意義的。
1:記憶體、記憶體、記憶體
memcached是完全基於記憶體操作的,是一個快取系統,從本質它不是一個資料庫系統,也不支援持久化。
既然是記憶體,在使用之前問自己,memcached快取的資料如果丟失,會影響你的業務嗎?
2:分散式系統
memcached本身是一個非常輕量級的服務,不支援主輔同步,也沒有叢集的概念。但為了可擴充套件性,memcached 伺服器端和 memcached 客戶端結合起來可以構成一個分散式系統。
在memcached分散式系統中,各個 memcached 節點之間無須通訊,所以擴充套件性非常好。
3:不支援複雜的操作
和 redis 不一樣的是,memcached 沒有複雜的資料結構(比如佇列、集合),它只能儲存字串型別,也不關心具體儲存什麼,這是它的一個優勢:簡單。但很多人用的時候可能就不爽了,說它比 redis 弱爆了,其實雙方的應用場景不一樣。
當然也可以基於基本命令模擬一些資料結構,這是允許的,但這和memcached無關。
4:原子操作
memcached 所有操作都是 O(1) ,都是原子操作,同一時間操作多個 set 不會有任何的影響。
5:效能
memcached 效能高的原因主要在於 libevent 事件機制、多執行緒、全記憶體操作、模型簡單(比如 O(1),儘量避免鎖機制)。
配置相對較高的伺服器,每秒可以處理 200,000+ 的請求,即使在很慢的機器上,每秒處理幾百次也毫無壓力。
memcached 所有的操作都是 O(1),set/get 操作不應該出現滯後,一個請求正常情況下不到 1ms 就能返回,如果遇到 Hang,那可能是連線數過多、產生了 swap、遇到了網路問題。
6:不推薦儲存 session 資料
現在很多業務都用 memcached 儲存 session 資料,在使用之前一定要評估風險,因為 memcached 是基於記憶體的,如果儲存的 session 丟失了,會話使用者就掉線了。
7:不支援名稱空間
memcached 一般針對某個key進行操作,不支援 namespace 功能,原因在於為了實現namespace,會讓系統實現複雜化(比如為了實現過期設定功能)。
但名稱空間的作用卻非常大,比如以下需求:
希望批次刪除某些 key。
如果獲取相關聯資料(比如有多個key),但 memcached 節點非常多,如果這些key根據 Hash 演算法分散儲存到多個節點,那麼獲取的時候效能就會下降。
但很多客戶端模擬實現了namespace功能 ,比如 PHP memcached 擴充套件就有相應的函式,比如 addByKey(),getAllKeys() 等函式,這些後續我再說。
8:Failure or Failover
如果你的應用沒有使用一致性hash演算法或其他的hash演算法,連線某一個memcache節點的時候,如果網路連線超時,或某個節點不能通訊(比如網線被拔了),那麼客戶端呼叫只能選擇 Failure,遇到這樣的情況,可能就要去後端讀取資料了。
如果你的應用使用一致性hash演算法,那麼應該選擇 Failure or Failover?
這裡有一個誤區,一致性 hash 演算法是減少上線或下線伺服器帶來的快取失效問題,本質上不是為了讓客戶端隨時隨地都能獲取到資料。
如果網路連線超時,或某個節點不能通訊(比如網線被拔了),儘量不要選擇自動 Failover,比如三個節點,本來某個 key 對應第一個節點,如果客戶端發現第一個節點不可用,就自動儲存到第二個節點,原因就在於如果第一個節點恢復了,可能獲取到舊的資料(在 Failover 的時候新資料更新到第二個節點)。
根據這一原則,PHP memcached 擴充套件預設是不做 Failover 的,這也是正確的應用方式,如果你實在要 Failover,可以使用下面的程式碼。
$memcache = new Memcached; $memcache->setOption(Memcached::OPT_DISTRIBUTION,Memcached::DISTRIBUTION_CONSISTENT); $memcache->setOption(Memcached::OPT_SERVER_FAILURE_LIMIT, 1); $memcache->setOption(Memcached::OPT_AUTO_EJECT_HOSTS,true); $memcache->addServer('localhost', 11212); $memcache->addServer('localhost', 11213); $memcache->set("abc",1);echo $memcache->get("abc"); print_r($memcache->getResultMessage());
9:能不能list所有的keys
不能,memcached 本身不支援,它就是一個 key-value 系統,但如果實在想實現list,可以透過兩個辦法:
推薦在啟動的時候配置 -vvv,這樣能夠將所有set的key列印出來,而且是排查問題非常好的方法。
執行 stats cachedump 命令,不過不推薦使用,因為操作比較慢,而且只能拿到區域性的資料。
10:memcached 應用場景?
能快取任何資料,有效減少後端的壓力並提升響應能力。
計算器,比如利用 incr 命令。
Rate limiting,非常有用,比如登陸系統可以使用它限制非法登陸。
雖然 memcached 不支援佇列和堆疊,但 append/prepend 命令還是有一定作用的,比如可以實現排行榜。
作者:虞大膽的嘰嘰喳喳
連結:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/4686/viewspace-2821290/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 如何理解並正確使用 MySQL 索引MySql索引
- LongTree的正確分析理解
- 理解並正確使用synchronized和volatilesynchronized
- 正確理解和使用JAVA中的字串常量池Java字串
- 正確理解ThreadLocalthread
- 正確理解 PHP 的過載PHP
- 正確理解CAP理論
- background-position的正確理解方式
- 沒有政治正確,遊戲世界會更好嗎?遊戲
- 我理解的關於Vue.nextTick()的正確使用Vue
- 如何正確理解棧和堆?
- 怎樣正確理解volatile?
- 正確理解Hibernate Inverse (轉)
- 正確理解BI(商業智慧)
- 談如何正確理解 IP 資料的覆蓋率,兼談正確率~
- PHP Opcache 的正確使用PHPopcache
- 【恩墨學院】如何理解並正確使用MySql索引MySql索引
- CDN應用進階 | 正確使用CDN 讓你更好規避安全風險
- 正確理解 PHP 錯誤資訊(轉)PHP
- Redis的正確使用姿勢Redis
- 使用正確的工具(轉載)
- 正確高效使用 GoogleGo
- 正確使用rman crosscheckROS
- 正確理解tnsnames.ora中的service_name
- 如何正確理解「指標」和「標籤」指標
- 使用正規表示式編寫更好的 SQLSQL
- 使用正規表示式編寫更好的SQLSQL
- Android中Handler的正確使用Android
- laravel 使用 es 的正確姿勢Laravel
- ThreadLocal的正確使用與原理thread
- 使用快取的正確姿勢快取
- 十個正確使用 Redis 的技巧Redis
- 如何正確使用 Slim 框架框架
- Postman 正確使用姿勢Postman
- 正確使用Java事件通知Java事件
- 轉:正確使用rman crosscheckROS
- 編寫高質量的js之正確理解正規表示式回溯JS
- 正確理解PHP程式編譯時的錯誤資訊PHP編譯