<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Chan Chen Coding...

    Memcached實現內存緩存(一)

    Memcached是danga.com(運營LiveJournal的技術團隊)開發的一套分布式內存對象緩存系統,用于在動態系統中減少數據庫負載,提升性能。LJ每秒動態頁面訪問量幾千次,用戶700萬。Memcached將數據庫負載大幅度降低,更好的分配資源,更快速訪問。

        關于這個東西,相信很多人都用過,本文意在通過對memcached的實現及代碼分析,獲得對這個出色的開源軟件更深入的了解,并可以根據我們的需要對其進行更進一步的優化。末了將通過對BSM_Memcache擴展的分析,加深對 memcached的使用方式理解。。

    1.Memcached是什么

    在闡述這個問題之前,我們首先要清楚它“不是什么”。很多人把它當作和SharedMemory那種形式的存儲載體來使用,雖然memcached使用了同樣的“Key=>Value”方式組織數據,但是它和共享內存、APC等本地緩存有非常大的區別。Memcached是分布式的,也就是說它不是本地的。它基于網絡連接(當然它也可以使用localhost)方式完成服務,本身它是一個獨立于應用的程序或守護進程(Daemon方式)。即Memcached是高性能的,分布式的內存對象緩存系統,用于在動態應用中減少數據庫負載,提升訪問速度。

    Memcached 使用libevent庫實現網絡連接服務,理論上可以處理無限多的連接,但是它和Apache不同,它更多的時候是面向穩定的持續連接的,所以它實際的并發能力是有限制的。在保守情況下memcached的最大同時連接數為200,這和Linux線程能力有關系,這個數值是可以調整的。關于 libevent可以參考相關文檔。 Memcached內存使用方式也和APC不同。APC是基于共享內存和MMAP的,memcachd有自己的內存分配算法和管理方式,它和共享內存沒有關系,也沒有共享內存的限制,通常情況下,每個memcached進程可以管理2GB的內存空間,如果需要更多的空間,可以增加進程數。

    2. Memcached適合什么場合

    在很多時候,memcached都被濫用了,這當然少不了對它的抱怨。我經常在論壇上看見有人發貼,類似于“如何提高效率”,回復是“用memcached”,至于怎么用,用在哪里,用來干什么一句沒有。memcached不是萬能的,它也不是適用在所有場合。

    Memcached 是“分布式”的內存對象緩存系統,那么就是說,那些不需要“分布”的,不需要共享的,或者干脆規模小到只有一臺服務器的應用, memcached不會帶來任何好處,相反還會拖慢系統效率,因為網絡連接同樣需要資源,即使是UNIX本地連接也一樣。在我之前的測試數據中顯示, memcached本地讀寫速度要比直接PHP內存數組慢幾十倍,而APC、共享內存方式都和直接數組差不多。可見,如果只是本地級緩存,使用 memcached是非常不劃算的。

     Memcached在很多時候都是作為數據庫前端cache使用的。因為它比數據庫少了很多SQL解析、磁盤操作等開銷,而且它是使用內存來管理數據的,所以它可以提供比直接讀取數據庫更好的性能,在大型系統中,訪問同樣的數據是很頻繁的, memcached可以大大降低數據庫壓力,使系統執行效率提升。另外,memcached也經常作為服務器之間數據共享的儲媒介,例如在SSO系統中保存系統單點登陸狀態的數據就可以保存在memcached中,被多個應用共享。

    需要注意的是,memcached使用內存管理數據,所以它是易失的,當服務器重啟,或者memcached進程中止,數據便會丟失,所以 memcached不能用來持久保存數據。很多人的錯誤理解,memcached的性能非常好,好到了內存和硬盤的對比程度,其實memcached使用內存并不會得到成百上千的讀寫速度提高,它的實際瓶頸在于網絡連接,它和使用磁盤的數據庫系統相比,好處在于它本身非常“輕”,因為沒有過多的開銷和直接的讀寫方式,它可以輕松應付非常大的數據交換量,所以經常會出現兩條千兆網絡帶寬都滿負荷了,memcached進程本身并不占用多少CPU資源的情況。

    通常的網頁緩存方式有動態緩存和靜態緩存等幾種,在ASP.NET中已經可以實現對頁面局部進行緩存,而使用memcached的緩存比 ASP.NET的局部緩存更加靈活,可以緩存任意的對象,不管是否在頁面上輸出。而memcached最大的優點是可以分布式的部署,這對于大規模應用來說也是必不可少的要求。

    LiveJournal.com使用了memcached在前端進行緩存,取得了良好的效果,而像wikipedia,sourceforge等也采用了或即將采用memcached作為緩存工具。memcached可以大規模網站應用發揮巨大的作用。

    2.1 memcached 的工作原理

    首先 memcached 是以守護程序方式運行于一個或多個服務器中,隨時接受客戶端的連接操作,客戶端可以由各種語言編寫,目前已知的客戶端 API 包括 Perl/PHP/Python/Ruby/Java/C#/C 等等。PHP 等客戶端在與 memcached 服務建立連接之后,接下來的事情就是存取對象了,每個被存取的對象都有一個唯一的標識符 key,存取操作均通過這個 key 進行,保存到 memcached 中的對象實際上是放置內存中的,并不是保存在 cache 文件中的,這也是為什么 memcached 能夠如此高效快速的原因。注意,這些對象并不是持久的,服務停止之后,里邊的數據就會丟失。

    .2  memcached 安裝

    首先是下載 memcached 了,目前最新版本是 1.1.12,直接從官方網站即可下載到 memcached-1.1.12.tar.gz。除此之外,memcached 用到了 libevent,我下載的是 libevent-1.1a.tar.gz

    接下來是分別將 libevent-1.1a.tar.gz 和 memcached-1.1.12.tar.gz 解開包、編譯、安裝:

    # tar -xzf libevent-1.1a.tar.gz 
    # cd libevent-1.1a 
    # ./configure --prefix=/usr 
    # make 
    # make install 
    # cd .. 
    # tar -xzf memcached-1.1.12.tar.gz 
    # cd memcached-1.1.12 
    # ./configure --prefix=/usr 
    # make 
    # make install
    安裝完成之后,memcached 應該在 /usr/bin/memcached。

    3.如何使用memcached-Server端?

    在服務端運行:

    # ./memcached -d -m 2048 -l 10.0.0.40 -p 11211  -u httpd
    -d 以守護程序(daemon)方式運行 memcached;
    -m 設置 memcached 可以使用的內存大小,單位為 M;

    -l 設置監聽的 IP&nb

    sp;地址,如果是本機的話,通常可以不設置此參數;
    -p 設置監聽的端口,默認為 11211,所以也可以不設置此參數;
    -u 指定用戶,如果當前為 root 的話,需要使用此參數指定用戶。

    這將會啟動一個占用2G內存的進程,并打開11211端口用于接收請求。由于32位系統只能處理4G內存的尋址,所以在大于4G內存使用PAE的32位服務器上可以運行2-3個進程,并在不同端口進行監聽。

    4. 如何使用memcached-Client端?

    在應用端包含一個用于描述Client的Class后,就可以直接使用,非常簡單。

    PHP Example:
    $options["debug"] = false;

    $memc = new MemCachedClient($options);

    $myarr = array("one","two", 3);

    $memc->set("key_one", $myarr);
    $options["servers"] = array("192.168.1.41:11211", "192.168.1.42:11212");

    $val = $memc->get("key_one");

    print $val[0]."\n"; // prints 'one‘

    print $val[1]."\n"; // prints 'two‘

    print $val[2]."\n"; // prints 3
    5.為什么不使用數據庫做這些?

    暫且不考慮使用什么樣的數據庫(MS-SQL, Oracle, Postgres, MysQL-InnoDB, etc..), 實現事務(ACID,Atomicity, Consistency, Isolation, and Durability )需要大量開銷,特別當使用到硬盤的時候,這就意味著查詢可能會阻塞。當使用不包含事務的數據庫(例如Mysql-MyISAM),上面的開銷不存在,但讀線程又可能會被寫線程阻塞。Memcached從不阻塞,速度非常快。

    6.為什么不使用共享內存?

    最初的緩存做法是在線程內對對象進行緩存,但這樣進程間就無法共享緩存,命中率非常低,導致緩存效率極低。后來出現了共享內存的緩存,多個進程或者線程共享同一塊緩存,但畢竟還是只能局限在一臺機器上,多臺機器做相同的緩存同樣是一種資源的浪費,而且命中率也比較低。

    Memcached Server和Clients共同工作,實現跨服務器分布式的全局的緩存。并且可以與Web Server共同工作,Web Server對CPU要求高,對內存要求低,Memcached Server對CPU要求低,對內存要求高,所以可以搭配使用。

    7.Mysql 4.x的緩存怎么樣?

    Mysql查詢緩存不是很理想,因為以下幾點:

    當指定的表發生更新后,查詢緩存會被清空。在一個大負載的系統上這樣的事情發生的非常頻繁,導致查詢緩存效率非常低,有的情況下甚至還不如不開,因為它對cache的管理還是會有開銷。

    在32位機器上,Mysql對內存的操作還是被限制在4G以內,但memcached可以分布開,內存規模理論上不受限制。

    Mysql上的是查詢緩存,而不是對象緩存,如果在查詢后還需要大量其它操作,查詢緩存就幫不上忙了。

    如果要緩存的數據不大,并且查詢的不是非常頻繁,這樣的情況下可以用Mysql 查詢緩存,不然的話memcached更好。

    8.數據庫同步怎么樣?

    這里的數據庫同步是指的類似Mysql Master-Slave模式的靠日志同步實現數據庫同步的機制。

    你可以分布讀操作,但無法分布寫操作,但寫操作的同步需要消耗大量的資源,而且這個開銷是隨著slave服務器的增長而不斷增長的。

    下一步是要對數據庫進行水平切分,從而讓不同的數據分布到不同的數據庫服務器組上,從而實現分布的讀寫,這需要在應用中實現根據不同的數據連接不同的數據庫。

    當這一模式工作后(我們也推薦這樣做),更多的數據庫導致更多的讓人頭疼的硬件錯誤。

    Memcached可以有效的降低對數據庫的訪問,讓數據庫用主要的精力來做不頻繁的寫操作,而這是數據庫自己控制的,很少會自己阻塞 自己。

    9.Memcached快嗎?

    非常快,它使用libevent,可以應付任意數量打開的連接(使用epoll,而非poll),使用非阻塞網絡IO,分布式散列對象到不同的服務器,查詢復雜度是O(1)。

    10.memcached的相關抽象類

    public abstract class BaseManager<T extends BaseObject> implements Manager<T> 
     
         private MemcachedClient memcached; 
     
         protected int default_cache_time_second = 3600;  
     
          public void setMemcached(MemcachedClient memcached) 
     
             this.memcached = memcached; 
     
          } 
     
          public MemcachedClient getMemcached() 
     
             return memcached; 
     
         } 
     
          public void setDefault_cache_time_second(int default_cache_time_second) 
     
             this.default_cache_time_second = default_cache_time_second; 
     
        } public Object getCacheValueFromMemcached(String key) {

            return getCacheValueFromMemcached(key, null);

        }

        public Object getCacheValueFromMemcached(String key, Object obj) {

            Object new_obj = null;

            try {

                new_obj = memcached.get(key);

                } catch (Exception e) {

                if (logger.isWarnEnabled()) {

    logger.warn("Failed to get from MeMCache", e); 
     
                 } 
     
             } 
     
             return (new_obj != null) ? new_obj : obj; 
           } 
     
           public void setCacheValueToMemcached(String cacheKey, int time_to_live, Serializable obj) 
     
              if (null != memcached.get(cacheKey)) 
     
                 memcached.replace(cacheKey, time_to_live, obj); 
     
              } else 
     
                 memcached.add(cacheKey, time_to_live, obj); 
     
             } 
     
           }  
         }
    11.service調用memcache的一個例子:

    public List<Integer> getLastModifyAlbumMember(int limit) {

            String cacheKey = this.createCachekey(new

           Object[]{"schedule","lastmodifyalbumember",limit});

            List list = (List) this.getCacheValueFromMemcached(cacheKey);

            List<Integer> list1 = new ArrayList<Integer>();

            if(null!=list&&list.size()>0){

                for (Object aList : list) {

                    list1.add(Integer.parseInt(String.valueOf(aList)));

                }

            }

            return list1;

        }
    參考資料:

    http://www.danga.com/

    http://www.linuxjournal.com/article/7451



    -----------------------------------------------------
    Silence, the way to avoid many problems;
    Smile, the way to solve many problems;

    posted on 2012-04-19 17:36 Chan Chen 閱讀(4054) 評論(1)  編輯  收藏 所屬分類: Memcached

    評論

    # re: Memcached實現內存緩存(一) 2014-09-23 17:47 周小帥

    太牛了 ,大神 膜拜啊 收了我把  回復  更多評論   


    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    主站蜘蛛池模板: 久久久久久久久久国产精品免费| 一级**爱片免费视频| 最近的中文字幕大全免费8| 国产av无码专区亚洲av果冻传媒| 国产天堂亚洲国产碰碰| 四虎永久成人免费影院域名| 国产精品亚洲五月天高清| 国产乱子伦精品免费无码专区| 精品亚洲福利一区二区| 亚洲国产免费综合| 久久国产美女免费观看精品| 狠狠色伊人亚洲综合成人| 一级毛片免费观看不卡视频| 亚洲熟妇av一区| 在线观看成人免费| 四虎影视久久久免费| 亚洲日韩精品无码一区二区三区| 日本免费人成网ww555在线| 亚洲综合精品香蕉久久网97| 成年在线观看网站免费| 狠狠综合亚洲综合亚洲色| 久久精品国产精品亚洲人人| 日本高清免费观看| 亚洲精品美女久久7777777| 亚洲AV成人潮喷综合网| 久久久久久久99精品免费观看| 亚洲福利视频网址| 免费A级毛片无码A∨男男| 最近2019中文免费字幕在线观看| 亚洲毛片在线免费观看| 日韩一区二区三区免费体验| 国产免费人成视频尤勿视频| 久久精品国产亚洲AV高清热| 最近的中文字幕大全免费版| 免费VA在线观看无码| 亚洲综合一区二区精品久久| 国产91久久久久久久免费| 无码精品国产一区二区三区免费| 亚洲一区AV无码少妇电影| 亚洲一区二区三区在线观看精品中文| 成年人免费的视频|