• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
  • memcached深度分析(2)

    發表于:2015-07-10來源:uml.org.cn作者:火龍果軟件點擊數: 標簽:數據庫
    這個函數 fork 了整個進程之后,父進程就退出,接著重新定位 STDIN 、 STDOUT 、 STDERR 到空設備, daemon 就建立成功了。 Memcached 本身的啟動過程,在 memcach

      這個函數 fork 了整個進程之后,父進程就退出,接著重新定位 STDIN 、 STDOUT 、 STDERR 到空設備, daemon 就建立成功了。

      Memcached 本身的啟動過程,在 memcached.c 的 main 函數中順序如下:

      1 、調用 settings_init() 設定初始化參數

      2 、從啟動命令中讀取參數來設置 setting 值

      3 、設定 LIMIT 參數

      4 、開始網絡 socket 監聽(如果非 socketpath 存在)( 1.2 之后支持 UDP 方式)

      5 、檢查用戶身份( Memcached 不允許 root 身份啟動)

      6 、如果有 socketpath 存在,開啟 UNIX 本地連接(Sock 管道)

      7 、如果以 -d 方式啟動,創建守護進程(如上調用 daemon 函數)

      8 、初始化 item 、 event 、狀態信息、 hash 、連接、 slab

      9 、如設置中 managed 生效,創建 bucket 數組

      10 、檢查是否需要鎖定內存頁

      11 、初始化信號、連接、刪除隊列

      12 、如果 daemon 方式,處理進程 ID

      13 、event 開始,啟動過程結束, main 函數進入循環。

      在 daemon 方式中,因為 stderr 已經被定向到黑洞,所以不會反饋執行中的可見錯誤信息。

      memcached.c 的主循環函數是 drive_machine ,傳入參數是指向當前的連接的結構指針,根據 state 成員的狀態來決定動作。

      Memcached 使用一套自定義的協議完成數據交換,它的 protocol 文檔可以參考: http://code.sixapart.com/svn/memcached/trunk/server/doc/protocol.txt

      在API中,換行符號統一為\r\n

      Memcached的內存管理方式

      Memcached有一個很有特色的內存管理方式,為了提高效率,它使用預申請和分組的方式管理內存空間,而并不是每次需要寫入數據的時候去malloc,刪除數據的時候free一個指針。Memcached使用slab->chunk的組織方式管理內存。

      1.1和1.2的slabs.c中的slab空間劃分算法有一些不同,后面會分別介紹。

      Slab可以理解為一個內存塊,一個slab是memcached一次申請內存的最小單位,在memcached中,一個slab的大小默認為 1048576字節(1MB),所以memcached都是整MB的使用內存。每一個slab被劃分為若干個chunk,每個chunk里保存一個 item,每個item同時包含了item結構體、key和value(注意在memcached中的value是只有字符串的)。slab按照自己的 id分別組成鏈表,這些鏈表又按id掛在一個slabclass數組上,整個結構看起來有點像二維數組。slabclass的長度在1.1中是21,在 1.2中是200。

      slab有一個初始chunk大小,1.1中是1字節,1.2中是80字節,1.2中有一個factor值,默認為1.25

      在1.1中,chunk大小表示為初始大小*2^n,n為classid,即:id為0的slab,每chunk大小1字節,id為1的slab,每 chunk大小2字節,id為2的slab,每chunk大小4字節……id為20的slab,每chunk大小為1MB,就是說id為20的slab里只有一個chunk:

    void slabs_init(size_t limit) {
        int i;
        int size=1;
     
        mem_limit = limit;
        for(i=0; i<=POWER_LARGEST; i++, size*=2) {
            slabclass[i].size = size;
            slabclass[i].perslab = POWER_BLOCK / size;
            slabclass[i].slots = 0;
            slabclass[i].sl_curr = slabclass[i].sl_total = slabclass[i].slabs = 0;
            slabclass[i].end_page_ptr = 0;
            slabclass[i].end_page_free = 0;
            slabclass[i].slab_list = 0;
            slabclass[i].list_size = 0;
            slabclass[i].killing = 0;
        }
     
        /* for the test suite:  faking of how much we've already malloc'd */
        {
            char *t_initial_malloc = getenv("T_MEMD_INITIAL_MALLOC");
            if (t_initial_malloc) {
                mem_malloced = atol(getenv("T_MEMD_INITIAL_MALLOC"));
            }
        }
     
        /* pre-allocate slabs by default, unless the environment variable
           for testing is set to something non-zero */
        {
            char *pre_alloc = getenv("T_MEMD_SLABS_ALLOC");
            if (!pre_alloc || atoi(pre_alloc)) {
                slabs_preallocate(limit / POWER_BLOCK);
            }
        }
    }
    
    

      在1.2中,chunk大小表示為初始大小*f^n,f為factor,在memcached.c中定義,n為classid,同時,201個頭不是全部都要初始化的,因為factor可變,初始化只循環到計算出的大小達到slab大小的一半為止,而且它是從id1開始的,即:id為1的slab,每 chunk大小80字節,id為2的slab,每chunk大小80*f,id為3的slab,每chunk大小80*f^2,初始化大小有一個修正值 CHUNK_ALIGN_BYTES,用來保證n-byte排列 (保證結果是CHUNK_ALIGN_BYTES的整倍數)。這樣,在標準情況下,memcached1.2會初始化到id40,這個slab中每個 chunk大小為504692,每個slab中有兩個chunk。最后,slab_init函數會在最后補足一個id41,它是整塊的,也就是這個 slab中只有一個1MB大的chunk:

    原文轉自:http://www.uml.org.cn/sjjm/201411134.asp

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>