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

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

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

    Kevin.Zhong

    彪悍的人生不需要解釋,彪悍的代碼不需要測試。

      BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
      17 隨筆 :: 12 文章 :: 14 評論 :: 0 Trackbacks

    memcached全面剖析–2.理解memcached的內(nèi)存存儲

    作者:charlee  來源:idv2.com  時間:2008-09-28  閱讀:57 次  原文鏈接   [收藏]  

    下面是《memcached全面剖析》的第二部分。

    發(fā)表日:2008/7/9
    作者:前坂徹(Toru Maesaka)
    原文鏈接:http://gihyo.jp/dev/feature/01/memcached/0002

    我是mixi株式會社研究開發(fā)組的前坂徹。 上次的文章介紹了memcached是分布式的高速緩存服務(wù)器。 本次將介紹memcached的內(nèi)部構(gòu)造的實(shí)現(xiàn)方式,以及內(nèi)存的管理方式。 另外,memcached的內(nèi)部構(gòu)造導(dǎo)致的弱點(diǎn)也將加以說明。

    Slab Allocation機(jī)制:整理內(nèi)存以便重復(fù)使用

    最近的memcached默認(rèn)情況下采用了名為Slab Allocator的機(jī)制分配、管理內(nèi)存。 在該機(jī)制出現(xiàn)以前,內(nèi)存的分配是通過對所有記錄簡單地進(jìn)行malloc和free來進(jìn)行的。 但是,這種方式會導(dǎo)致內(nèi)存碎片,加重操作系統(tǒng)內(nèi)存管理器的負(fù)擔(dān),最壞的情況下, 會導(dǎo)致操作系統(tǒng)比memcached進(jìn)程本身還慢。Slab Allocator就是為解決該問題而誕生的。

    下面來看看Slab Allocator的原理。下面是memcached文檔中的slab allocator的目標(biāo):

    the primary goal of the slabs subsystem in memcached was to eliminate memory fragmentation issues totally by using fixed-size memory chunks coming from a few predetermined size classes.

    也就是說,Slab Allocator的基本原理是按照預(yù)先規(guī)定的大小,將分配的內(nèi)存分割成特定長度的塊, 以完全解決內(nèi)存碎片問題。

    Slab Allocation的原理相當(dāng)簡單。 將分配的內(nèi)存分割成各種尺寸的塊(chunk), 并把尺寸相同的塊分成組(chunk的集合)(圖1)。


    圖1 Slab Allocation的構(gòu)造圖

    而且,slab allocator還有重復(fù)使用已分配的內(nèi)存的目的。 也就是說,分配到的內(nèi)存不會釋放,而是重復(fù)利用。

    Slab Allocation的主要術(shù)語

    Page

    分配給Slab的內(nèi)存空間,默認(rèn)是1MB。分配給Slab之后根據(jù)slab的大小切分成chunk。

    Chunk

    用于緩存記錄的內(nèi)存空間。

    Slab Class

    特定大小的chunk的組。

    在Slab中緩存記錄的原理

    下面說明memcached如何針對客戶端發(fā)送的數(shù)據(jù)選擇slab并緩存到chunk中。

    memcached根據(jù)收到的數(shù)據(jù)的大小,選擇最適合數(shù)據(jù)大小的slab(圖2)。 memcached中保存著slab內(nèi)空閑chunk的列表,根據(jù)該列表選擇chunk, 然后將數(shù)據(jù)緩存于其中。


    圖2 選擇存儲記錄的組的方法

    實(shí)際上,Slab Allocator也是有利也有弊。下面介紹一下它的缺點(diǎn)。

    Slab Allocator的缺點(diǎn)

    Slab Allocator解決了當(dāng)初的內(nèi)存碎片問題,但新的機(jī)制也給memcached帶來了新的問題。

    這個問題就是,由于分配的是特定長度的內(nèi)存,因此無法有效利用分配的內(nèi)存。 例如,將100字節(jié)的數(shù)據(jù)緩存到128字節(jié)的chunk中,剩余的28字節(jié)就浪費(fèi)了(圖3)。


    圖3 chunk空間的使用

    對于該問題目前還沒有完美的解決方案,但在文檔中記載了比較有效的解決方案。

    The most efficient way to reduce the waste is to use a list of size classes that closely matches (if that's at all possible) common sizes of objects that the clients of this particular installation of memcached are likely to store.

    就是說,如果預(yù)先知道客戶端發(fā)送的數(shù)據(jù)的公用大小,或者僅緩存大小相同的數(shù)據(jù)的情況下, 只要使用適合數(shù)據(jù)大小的組的列表,就可以減少浪費(fèi)。

    但是很遺憾,現(xiàn)在還不能進(jìn)行任何調(diào)優(yōu),只能期待以后的版本了。 但是,我們可以調(diào)節(jié)slab class的大小的差別。 接下來說明growth factor選項(xiàng)。

    使用Growth Factor進(jìn)行調(diào)優(yōu)

    memcached在啟動時指定 Growth Factor因子(通過-f選項(xiàng)), 就可以在某種程度上控制slab之間的差異。默認(rèn)值為1.25。 但是,在該選項(xiàng)出現(xiàn)之前,這個因子曾經(jīng)固定為2,稱為“powers of 2”策略。

    讓我們用以前的設(shè)置,以verbose模式啟動memcached試試看:

    $ memcached -f 2 -vv

    下面是啟動后的verbose輸出:

    slab class   1: chunk size    128 perslab  8192
    slab class 2: chunk size 256 perslab 4096
    slab class 3: chunk size 512 perslab 2048
    slab class 4: chunk size 1024 perslab 1024
    slab class 5: chunk size 2048 perslab 512
    slab class 6: chunk size 4096 perslab 256
    slab class 7: chunk size 8192 perslab 128
    slab class 8: chunk size 16384 perslab 64
    slab class 9: chunk size 32768 perslab 32
    slab class 10: chunk size 65536 perslab 16
    slab class 11: chunk size 131072 perslab 8
    slab class 12: chunk size 262144 perslab 4
    slab class 13: chunk size 524288 perslab 2

    可見,從128字節(jié)的組開始,組的大小依次增大為原來的2倍。 這樣設(shè)置的問題是,slab之間的差別比較大,有些情況下就相當(dāng)浪費(fèi)內(nèi)存。 因此,為盡量減少內(nèi)存浪費(fèi),兩年前追加了growth factor這個選項(xiàng)。

    來看看現(xiàn)在的默認(rèn)設(shè)置(f=1.25)時的輸出(篇幅所限,這里只寫到第10組):

    slab class   1: chunk size     88 perslab 11915
    slab class 2: chunk size 112 perslab 9362
    slab class 3: chunk size 144 perslab 7281
    slab class 4: chunk size 184 perslab 5698
    slab class 5: chunk size 232 perslab 4519
    slab class 6: chunk size 296 perslab 3542
    slab class 7: chunk size 376 perslab 2788
    slab class 8: chunk size 472 perslab 2221
    slab class 9: chunk size 592 perslab 1771
    slab class 10: chunk size 744 perslab 1409

    可見,組間差距比因子為2時小得多,更適合緩存幾百字節(jié)的記錄。 從上面的輸出結(jié)果來看,可能會覺得有些計算誤差, 這些誤差是為了保持字節(jié)數(shù)的對齊而故意設(shè)置的。

    將memcached引入產(chǎn)品,或是直接使用默認(rèn)值進(jìn)行部署時, 最好是重新計算一下數(shù)據(jù)的預(yù)期平均長度,調(diào)整growth factor, 以獲得最恰當(dāng)?shù)脑O(shè)置。內(nèi)存是珍貴的資源,浪費(fèi)就太可惜了。

    接下來介紹一下如何使用memcached的stats命令查看slabs的利用率等各種各樣的信息。

    查看memcached的內(nèi)部狀態(tài)

    memcached有個名為stats的命令,使用它可以獲得各種各樣的信息。 執(zhí)行命令的方法很多,用telnet最為簡單:

    $ telnet 主機(jī)名 端口號

    連接到memcached之后,輸入stats再按回車,即可獲得包括資源利用率在內(nèi)的各種信息。 此外,輸入"stats slabs"或"stats items"還可以獲得關(guān)于緩存記錄的信息。 結(jié)束程序請輸入quit。

    這些命令的詳細(xì)信息可以參考memcached軟件包內(nèi)的protocol.txt文檔。

    $ telnet localhost 11211
    Trying ::1...
    Connected to localhost.
    Escape character is '^]'.
    stats
    STAT pid 481
    STAT uptime 16574
    STAT time 1213687612
    STAT version 1.2.5
    STAT pointer_size 32
    STAT rusage_user 0.102297
    STAT rusage_system 0.214317
    STAT curr_items 0
    STAT total_items 0
    STAT bytes 0
    STAT curr_connections 6
    STAT total_connections 8
    STAT connection_structures 7
    STAT cmd_get 0
    STAT cmd_set 0
    STAT get_hits 0
    STAT get_misses 0
    STAT evictions 0
    STAT bytes_read 20
    STAT bytes_written 465
    STAT limit_maxbytes 67108864
    STAT threads 4
    END
    quit

    另外,如果安裝了libmemcached這個面向C/C++語言的客戶端庫,就會安裝 memstat 這個命令。 使用方法很簡單,可以用更少的步驟獲得與telnet相同的信息,還能一次性從多臺服務(wù)器獲得信息。

    $ memstat --servers=server1,server2,server3,...

    libmemcached可以從下面的地址獲得:

    查看slabs的使用狀況

    使用memcached的創(chuàng)造著Brad寫的名為memcached-tool的Perl腳本,可以方便地獲得slab的使用情況 (它將memcached的返回值整理成容易閱讀的格式)。可以從下面的地址獲得腳本:

    使用方法也極其簡單:

    $ memcached-tool 主機(jī)名:端口 選項(xiàng)

    查看slabs使用狀況時無需指定選項(xiàng),因此用下面的命令即可:

    $ memcached-tool 主機(jī)名:端口

    獲得的信息如下所示:

     #  Item_Size   Max_age  1MB_pages Count   Full?
    1 104 B 1394292 s 1215 12249628 yes
    2 136 B 1456795 s 52 400919 yes
    3 176 B 1339587 s 33 196567 yes
    4 224 B 1360926 s 109 510221 yes
    5 280 B 1570071 s 49 183452 yes
    6 352 B 1592051 s 77 229197 yes
    7 440 B 1517732 s 66 157183 yes
    8 552 B 1460821 s 62 117697 yes
    9 696 B 1521917 s 143 215308 yes
    10 872 B 1695035 s 205 246162 yes
    11 1.1 kB 1681650 s 233 221968 yes
    12 1.3 kB 1603363 s 241 183621 yes
    13 1.7 kB 1634218 s 94 57197 yes
    14 2.1 kB 1695038 s 75 36488 yes
    15 2.6 kB 1747075 s 65 25203 yes
    16 3.3 kB 1760661 s 78 24167 yes

    各列的含義為:

    含義
    # slab class編號
    Item_Size Chunk大小
    Max_age LRU內(nèi)最舊的記錄的生存時間
    1MB_pages 分配給Slab的頁數(shù)
    Count Slab內(nèi)的記錄數(shù)
    Full? Slab內(nèi)是否含有空閑chunk

    從這個腳本獲得的信息對于調(diào)優(yōu)非常方便,強(qiáng)烈推薦使用。

    內(nèi)存存儲的總結(jié)

    本次簡單說明了memcached的緩存機(jī)制和調(diào)優(yōu)方法。 希望讀者能理解memcached的內(nèi)存管理原理及其優(yōu)缺點(diǎn)。

    下次將繼續(xù)說明LRU和Expire等原理,以及memcached的最新發(fā)展方向—— 可擴(kuò)充體系(pluggable architecher))。

    posted on 2008-10-15 11:31 Kevin.Zhong 閱讀(174) 評論(0)  編輯  收藏 所屬分類: memcache
    主站蜘蛛池模板: 亚洲人成精品久久久久| 亚洲高清成人一区二区三区| 亚洲人成伊人成综合网久久久| 亚洲国产精品无码久久九九大片| 色播精品免费小视频| 亚洲色图.com| 五月亭亭免费高清在线| 亚洲综合成人网在线观看| 久久99青青精品免费观看| 亚洲精选在线观看| 1000部拍拍拍18勿入免费视频软件| 亚洲性69影院在线观看| 免费电视剧在线观看| 亚洲AV无码AV日韩AV网站| 亚洲精品无码激情AV| 一级毛片免费观看不收费| 亚洲精品无码成人片久久| 永久免费av无码入口国语片| 2022年亚洲午夜一区二区福利| 巨波霸乳在线永久免费视频| 亚洲日韩国产一区二区三区在线| 免费看片A级毛片免费看| 成人免费观看男女羞羞视频| 亚洲综合网站色欲色欲| 8888四色奇米在线观看免费看| 亚洲最大视频网站| 又黄又爽无遮挡免费视频| 国内精品免费视频精选在线观看| 亚洲伊人久久大香线焦| 国产猛烈高潮尖叫视频免费| 一级做a爰性色毛片免费| 亚洲精品综合一二三区在线| 免费黄色小视频网站| 91精品成人免费国产| 亚洲jjzzjjzz在线观看| 免费观看午夜在线欧差毛片| 久久爰www免费人成| 亚洲永久网址在线观看| 亚洲午夜福利AV一区二区无码| 美女内射毛片在线看免费人动物| 久久久久亚洲精品无码网址色欲 |