Memcached 實戰

gu043695 8年前發布 | 33K 次閱讀 緩存服務器 memcached

來自: http://blog.csdn.net/wenniuwuren/article/details/50826656


零. 簡介

Memcached 是一款開源、 分布式內存對象緩存系統, 用于加快動態網站響應, 降低數據庫負載


Memcached 使用簡單, 支持多種語言的 API, 解決面對大量數據的緩存問題



一. 設計哲學

(1) 鍵值對存儲

服務器不關心數據是什么樣的。 存儲單元由 key、 過期時間、 可選的標記和數據組成。 它不懂數據結構, 傳輸數據前需要序列化。


(2)一半邏輯在客戶端, 另一半邏輯在服務端

客戶端知道如何選擇(哈希)哪個服務端去讀/寫存儲單元, 并且知道如何處理無法連到服務端的情況

服務端知道如何存儲和獲取數據單元, 并且它知道如何清除或者重用內存。


(3)服務端彼此之間不通信

即服務端之間沒有同步、 沒有多播、 沒有復制。 增加服務器就是增加可用內存。 但是正因為這個特性, Memcached 存在單點故障, 如果需要做高可用, 需要使用 Magent 這樣的代理服務軟件去實現高可用。


(4)時間復雜度 O(1)

所有的命令都被盡量實現為快速和對鎖友好,提供了近乎確定的查詢速度。 在慢的機器上查詢時間低于 1ms, 在高端服務器上可以達到百萬/s 的吞吐量


(5)遺忘是一種特性

Lazy Expiration + LRU :不檢測 item 對象是否超時,get 時檢查 item 對象是否應該刪除;
</div>

刪除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 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!