Memcached 實戰
來自: http://blog.csdn.net/wenniuwuren/article/details/50826656
零. 簡介
Memcached 是一款開源、 分布式內存對象緩存系統, 用于加快動態網站響應, 降低數據庫負載
Memcached 使用簡單, 支持多種語言的 API, 解決面對大量數據的緩存問題
一. 設計哲學
(1) 鍵值對存儲
服務器不關心數據是什么樣的。 存儲單元由 key、 過期時間、 可選的標記和數據組成。 它不懂數據結構, 傳輸數據前需要序列化。
(2)一半邏輯在客戶端, 另一半邏輯在服務端
客戶端知道如何選擇(哈希)哪個服務端去讀/寫存儲單元, 并且知道如何處理無法連到服務端的情況
服務端知道如何存儲和獲取數據單元, 并且它知道如何清除或者重用內存。
(3)服務端彼此之間不通信
即服務端之間沒有同步、 沒有多播、 沒有復制。 增加服務器就是增加可用內存。 但是正因為這個特性, Memcached 存在單點故障, 如果需要做高可用, 需要使用 Magent 這樣的代理服務軟件去實現高可用。
(4)時間復雜度 O(1)
所有的命令都被盡量實現為快速和對鎖友好,提供了近乎確定的查詢速度。 在慢的機器上查詢時間低于 1ms, 在高端服務器上可以達到百萬/s 的吞吐量
(5)遺忘是一種特性
刪除item對象時,不釋放內存,作刪除標記,指針方式 slot 回收插槽,下次分配的時候直接使用;
(6)緩存無效
客戶端通過 hash 直接告訴服務端緩存數據無效, 而不是多播讓所有服務器的該 item 緩存無效
二. Memcached 實戰
(1) 安裝 memcached 很簡單, 如果是 CentOS 或者 Red Hat 直接
yum install memcached
如果是 Ubuntu/Debian 則使用 apt-get
(2) 檢查 Memcached 是否安裝成功:可以查看到幫助信息說明安裝成功
memcached -h
(3) 啟動 Memcached (假設 138.138.138.11 是你的外網 ip, 在 CentOS7 上設置 11211 默認端口訪問不了, 查看也沒被占用, 很奇怪, 所以下面監聽 11222 端口)
memcached -d -u root -l 138.138.138.11 -p 11222 -vv
-d 以守護程序(daemon)方式運行
-u root 指定用戶,如果當前為 root ,需要此參數指定用戶
-P /tmp/a.pid 保存PID到指定文件
</div>
-m 默認 64,不包含memcached本身占用,單位為 MB
-M 內存不夠時禁止 LRU
-n 48 初始 chunk=key+suffix+value+32 結構體,默認 48 字節 -f 1.25 增長因子,默認1.25
-L 啟用大內存頁,可以降低內存浪費,改進性能
</div>
-l 監聽的 IP 地址, 服務器有兩個網卡一個對內一個對外, 如果設置為 127.0.0.1 則只能本地訪問 memcached, 設置外網 ip 則可以接受外來的訪問
-p 11211 TCP端口,默認為11211
-U 11211 UDP端口,默認為11211,0為關閉
</div>
-c 1024 最大并發連接數,默認1024,最好是200
-t 4 線程數,默認4
-R 20 每個event連接最大并發數,默認20 -C 禁用CAS命令(可以禁止版本計數,減少開銷)
-vv 打印交互式詳細信息, 可以看到連接進來的人正在做什么操作
(4) 檢查 Memcached 是否成功啟動:
</div>
ps -ef | grep memcached
(5) 遠程連接 Memcached: 連接成功顯示 Connected to 138.138.138.11. Escape character is '^]'.
telnet 138.138.138.11 11222
(6) 連接成功后輸入 stats 可以查看服務整體狀態
STAT pid 5013 memcache服務器的進程ID
STAT uptime 3524589 服務器已經運行的秒數
STAT time 1453720323 服務器當前的unix時間戳
STAT version 1.4.17 memcache版本
STAT libevent 2.0.16-stable
STAT pointer_size 64 當前操作系統的指針大小(32位系統一般是32bit)
STAT usage_user 20513.015760 進程的累計用戶時間
STAT rusage_system 45473.527888 進程的累計系統時間
STAT cur_connections 102 當前打開著的連接數
STAT total_connections 60437 從服務器啟動以后曾經打開過的連接數
STAT connection_structures 243 服務器分配的連接構造數
STAT reserved_fds 20
STAT cmd_get 474507075 get命令(獲取)總請求次數
STAT cmd_set 334776915 set命令(保存)總請求次數
STAT cmd_flush 97
STAT cmd_touch 0
STAT get_hits 301883351 總命中次數
STAT get_misses 172623724 總未命中次數
STAT delete_misses 208322
STAT delete_hits 35095518
STAT incr_misses 0
STAT incr_hits 0
STAT decr_misses 0
STAT decr_hits 0
STAT cas_misses 0
STAT cas_hits 0
STAT cas_badval 0
STAT touch_hits 0
STAT touch_misses 0
STAT auth_cmds 0
STAT auth_errors 0
STAT bytes_read 268709016022 總讀取字節數(請求字節數)
STAT bytes_written 754717253318 總發送字節數(結果字節數)
STAT limit_maxbytes 536870912 分配給memcache的內存大小(字節)
STAT accepting_conns 1
STAT listen_disabled_num 0
STAT threads 4 當前線程數
STAT conn_yields 17561
STAT hash_power_level 18
STAT hash_bytes 2097152
STAT hash_is_expanding 0
STAT malloc_fails 0
STAT bytes 473920740 當前服務器存儲items占用的字節數
STAT curr_items 265877 服務器當前存儲的items數量
STAT total_items 239409267 從服務器啟動以后存儲的items總數量
STAT expired_unfetched 49973876
STAT evicted_unfetched 23514857
STAT evictions 27383392 為獲取空閑內存而刪除的items數(分配給memcache的空間用滿后需要刪除舊的items來得到空間分配給新的items)
</div>
STAT reclaimed 52732799
三. 客戶端的選擇
客戶端有三種選擇: spymemcached、 java-memcached、 xmemcached
具體看 https://xmemcached.googlecode.com/svn/trunk/benchmark/benchmark.html 有性能對比圖, 當然因為是 xmemcached 自己的性能測試報告, 不一定和每個人使用的時候場景一樣, 具體可以自己測試后再作出選擇。
</div>
引入 xmemcached-1.3.6.jar 的包
測試代碼如下:
package com.wenniuwuren.memcached;import net.rubyeye.xmemcached.MemcachedClient; import net.rubyeye.xmemcached.XMemcachedClientBuilder; import net.rubyeye.xmemcached.utils.AddrUtil;
import java.util.HashMap; import java.util.Map;
/**
Created by wenniuwuren on 16/3/6. */ public class MemcachedTest {
public static void main(String[] args) {
try { //New a XMemcachedClient instance XMemcachedClientBuilder builder = new XMemcachedClientBuilder(AddrUtil.getAddresses("138.138.138.11:11222")); MemcachedClient client = builder.build(); Map map = new HashMap<>(); map.put("1", "2"); client.set("key", 3000, map); Map cachedMap = (Map)client.get("key"); System.out.println(cachedMap.get("1")); } catch (Exception e) { e.printStackTrace(); }
} }</pre>
四. Memcached 集群因為 Memcached 設計哲學的極簡, 所以集群不熟非常簡單, 服務端新啟動一個 Memcached 進程就行。 其他的交給客戶端完成。 如果客戶端使用普通的 Hash 算法,則新增 Memcached 會重新計算 Hash 值使舊的緩存失效。 如果客戶端使用一致性 Hash 算法, 則不會影響舊的緩存數據。
新加個端口為 11333 的 Memcached 進程, 可以看到兩個 Memcached 存儲內容不同, 證明上述 Memcached 服務間不互相通信。
五. Memcached 局限性(1)存儲格式單一, 就是 <String, Object>, 想使用復雜點的數據結構(list、 set、 hash)一般會選用 Redis(2)最大只能存儲 1M 的 item, 而(3)最大鍵長 250 字節(4)只存在緩存, 數據重啟丟失,而 Redis 支持持久化(但是也經常會丟數據), 并在此基礎上實現主從同步, 而 Memcached 存在單點故障(5) 數據一致性問題: Memcached 使用 CAS 保證。 而 Redis 使用事務, 保證一系列命令的原子性。
本文由用戶 gu043695 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!