memcached學習總結

一.介紹
1.基於libevent的事件處理
  libevent是一套跨平臺的事件處理接口的封裝,可以兼容包括這些操做系統:Windows/Linux/BSD/Solaris 等操做系統的的事件處理。
包裝的接口包括:poll、select(Windows)、epoll(Linux)、kqueue(BSD)、/dev/pool(Solaris)
Memcached 使用libevent來進行網絡併發鏈接的處理,可以保持在很大併發狀況下,仍舊可以保持快速的響應能力。
libevent: http://www.monkey.org/~provos/libevent/html

2.內置內存存儲方式
  爲了提升性能,memcached中保存的數據都存儲在memcached內置的內存存儲空間中。因爲數據僅存在於內存中,所以重啓memcached、重啓操做系統會致使所有數據消失。另外,內容容量達到指定值以後,就基於LRU(Least Recently Used)算法自動刪除不使用的緩存。java

數據存儲方式:Slab Allocation
結構圖以下:
memcached
  Slab Allocator的基本原理是按照預先規定的大小,將分配的內存分割成特定長度的塊(chunk),並把尺寸相同的塊分紅組,以徹底解決內存碎片問題。但因爲分配的是特定長度的內存,所以沒法有效利用分配的內存。好比將100字節的數據緩存到128字節的chunk中,剩餘的28字節就浪費了。
  Page:分配給Slab的內存空間,默認是1MB。分配給Slab以後根據slab的大小切分紅chunk。
  Chunk:用於緩存記錄的內存空間。
  Slab Class:特定大小的chunk的組。
  memcached根據收到的數據的大小,選擇最適合數據大小的slab。
  memcached中保存着slab內空閒chunk的列表,根據該列表選擇chunk,而後將數據緩存於其中。linux

數據過時方式:Lazy Expiration + LRU
Lazy Expiration
  memcached內部不會監視記錄是否過時,而是在get時查看記錄的時間戳,檢查記錄是否過
期。這種技術被稱爲lazy(惰性)expiration。所以,memcached不會在過時監視上耗費CPU時間。
LRU
  memcached會優先使用已超時的記錄的空間,但即便如此,也會發生追加新記錄時空間不
足的狀況,此時就要使用名爲 Least Recently Used(LRU)機制來分配空間。當memcached的內存空間不足時(沒法從slab class 獲取到新的空間時),就從最近未被使用的記錄中搜索,並將其空間分配給新的記錄。redis

  http://www.ttlsa.com/memcache/memcached-description/算法

 

二.處理流程mongodb

  1. memcached採用事件驅動+狀態驅動的方式來進行整個業務的處理,針對每個tcp/udp鏈接,都有對應的狀態,狀態可能的取值爲:數據庫

/**
 * Possible states of a connection.
 */
enum conn_states {
    conn_listening,  /**< the socket which listens for connections */
    conn_new_cmd,    /**< Prepare connection for next command */
    conn_waiting,    /**< waiting for a readable socket */
    conn_read,       /**< reading in a command line */
    conn_parse_cmd,  /**< try to parse a command from the input buffer */
    conn_write,      /**< writing out a simple response */
    conn_nread,      /**< reading in a fixed number of bytes */
    conn_swallow,    /**< swallowing unnecessary bytes w/o storing */
    conn_closing,    /**< closing this connection */
    conn_mwrite,     /**< writing out many items sequentially */
    conn_closed,     /**< connection is closed */
    conn_max_state   /**< Max state value (used for assertion) */
};

  2.針對客戶端的命令,鏈接的狀態爲設置爲conn_parse_cmd,這樣就能夠對客戶端的命令進行解析處理,支持的命令以下:windows

 /**
     * Definition of the different command opcodes.
     * See section 3.3 Command Opcodes
     */
    typedef enum {
        PROTOCOL_BINARY_CMD_GET = 0x00,
        PROTOCOL_BINARY_CMD_SET = 0x01,
        PROTOCOL_BINARY_CMD_ADD = 0x02,
        PROTOCOL_BINARY_CMD_REPLACE = 0x03,
        PROTOCOL_BINARY_CMD_DELETE = 0x04,
        PROTOCOL_BINARY_CMD_INCREMENT = 0x05,
        PROTOCOL_BINARY_CMD_DECREMENT = 0x06,
        PROTOCOL_BINARY_CMD_QUIT = 0x07,
        PROTOCOL_BINARY_CMD_FLUSH = 0x08,
        PROTOCOL_BINARY_CMD_GETQ = 0x09,
        PROTOCOL_BINARY_CMD_NOOP = 0x0a,
        PROTOCOL_BINARY_CMD_VERSION = 0x0b,
        PROTOCOL_BINARY_CMD_GETK = 0x0c,
        PROTOCOL_BINARY_CMD_GETKQ = 0x0d,
        PROTOCOL_BINARY_CMD_APPEND = 0x0e,
        PROTOCOL_BINARY_CMD_PREPEND = 0x0f,
        PROTOCOL_BINARY_CMD_STAT = 0x10,
        PROTOCOL_BINARY_CMD_SETQ = 0x11,
        PROTOCOL_BINARY_CMD_ADDQ = 0x12,
        PROTOCOL_BINARY_CMD_REPLACEQ = 0x13,
        PROTOCOL_BINARY_CMD_DELETEQ = 0x14,
        PROTOCOL_BINARY_CMD_INCREMENTQ = 0x15,
        PROTOCOL_BINARY_CMD_DECREMENTQ = 0x16,
        PROTOCOL_BINARY_CMD_QUITQ = 0x17,
        PROTOCOL_BINARY_CMD_FLUSHQ = 0x18,
        PROTOCOL_BINARY_CMD_APPENDQ = 0x19,
        PROTOCOL_BINARY_CMD_PREPENDQ = 0x1a,
        PROTOCOL_BINARY_CMD_TOUCH = 0x1c,
        PROTOCOL_BINARY_CMD_GAT = 0x1d,
        PROTOCOL_BINARY_CMD_GATQ = 0x1e,
        PROTOCOL_BINARY_CMD_GATK = 0x23,
        PROTOCOL_BINARY_CMD_GATKQ = 0x24,

        PROTOCOL_BINARY_CMD_SASL_LIST_MECHS = 0x20,
        PROTOCOL_BINARY_CMD_SASL_AUTH = 0x21,
        PROTOCOL_BINARY_CMD_SASL_STEP = 0x22,

        /* These commands are used for range operations and exist within
         * this header for use in other projects.  Range operations are
         * not expected to be implemented in the memcached server itself.
         */
        PROTOCOL_BINARY_CMD_RGET      = 0x30,
        PROTOCOL_BINARY_CMD_RSET      = 0x31,
        PROTOCOL_BINARY_CMD_RSETQ     = 0x32,
        PROTOCOL_BINARY_CMD_RAPPEND   = 0x33,
        PROTOCOL_BINARY_CMD_RAPPENDQ  = 0x34,
        PROTOCOL_BINARY_CMD_RPREPEND  = 0x35,
        PROTOCOL_BINARY_CMD_RPREPENDQ = 0x36,
        PROTOCOL_BINARY_CMD_RDELETE   = 0x37,
        PROTOCOL_BINARY_CMD_RDELETEQ  = 0x38,
        PROTOCOL_BINARY_CMD_RINCR     = 0x39,
        PROTOCOL_BINARY_CMD_RINCRQ    = 0x3a,
        PROTOCOL_BINARY_CMD_RDECR     = 0x3b,
        PROTOCOL_BINARY_CMD_RDECRQ    = 0x3c
        /* End Range operations */

    } protocol_binary_command;

  3.memcached處理框架示意圖:緩存

三.redis、memcached、mongoDB 對比網絡

1)性能
都比較高,性能對咱們來講應該都不是瓶頸
整體來說,TPS方面redis和memcache差很少,要大於mongodb

2)操做的便利性
memcache數據結構單一
redis豐富一些,數據操做方面,redis更好一些,較少的網絡IO次數
mongodb支持豐富的數據表達,索引,最相似關係型數據庫,支持的查詢語言很是豐富

3)內存空間的大小和數據量的大小
redis在2.0版本後增長了本身的VM特性,突破物理內存的限制;能夠對key value設置過時時間(相似memcache)
memcache能夠修改最大可用內存,採用LRU算法
mongoDB適合大數據量的存儲,依賴操做系統VM作內存管理,吃內存也比較厲害,服務不要和別的服務在一塊兒

4)可用性(單點問題)
對於單點問題,
redis,依賴客戶端來實現分佈式讀寫;主從複製時,每次從節點從新鏈接主節點都要依賴整個快照,無增量複製,因性能和效率問題,
因此單點問題比較複雜;不支持自動sharding,須要依賴程序設定一致hash 機制。
一種替代方案是,不用redis自己的複製機制,採用本身作主動複製(多份存儲),或者改爲增量複製的方式(須要本身實現),一致性問題和性能的權衡

Memcache自己沒有數據冗餘機制,也不必;對於故障預防,採用依賴成熟的hash或者環狀的算法,解決單點故障引發的抖動問題。

mongoDB支持master-slave,replicaset(內部採用paxos選舉算法,自動故障恢復),auto sharding機制,對客戶端屏蔽了故障轉移和切分機制。

5)可靠性(持久化)

對於數據持久化和數據恢復:
redis支持(快照、AOF):依賴快照進行持久化,aof加強了可靠性的同時,對性能有所影響
memcache不支持,一般用在作緩存,提高性能;
MongoDB從1.8版本開始採用binlog方式支持持久化的可靠性

6)數據一致性(事務支持)
Memcache 在併發場景下,用cas保證一致性
redis事務支持比較弱,只能保證事務中的每一個操做連續執行
mongoDB不支持事務

7)數據分析
mongoDB內置了數據分析的功能(mapreduce),其餘不支持

8)應用場景
redis:數據量較小的更性能操做和運算上
memcache:用於在動態系統中減小數據庫負載,提高性能;作緩存,提升性能(適合讀多寫少,對於數據量比較大,能夠採用sharding)
MongoDB:主要解決海量數據的訪問效率問題

    http://www.blogjava.net/paulwong/archive/2013/09/06/403746.html 

相關文章
相關標籤/搜索