閱讀553 返回首頁    go 阿裏雲 go 技術社區[雲棲]


OceanBase分布式存儲引擎公共模塊——內存管理

OceanBase分布式存儲引擎公共模塊——內存管理

內存管理是C++高性能服務器的核心問題。一些通用的內存管理庫,比如Google TCMalloc,在內存申請/釋放速度、小內存管理、所開銷等方麵都已經做得相當卓越了,然而,我們並沒有采用。這是因為,通用內存管理庫在性能上畢竟不如專用的內存池,更為嚴重的問題是,它鼓勵了開發人員忽視內存管理的陋習,比如在服務器程序中濫用C++標準模板庫(STL)。

在分布式存儲係統開發初期,內存相關的Bug相當常見,比如內存越界、服務器出現Core Comp,這些Bug都非常難以調試。因此,這個時期內存管理的首要問題並不是高效,而是可控性,並防止內存碎片。

OceanBase係統有一個全局的定長內存池,這個內存池維護了由64KB大小的定長內存塊組成的空閑鏈表,其工作原理如下:

  • 如果申請的內存不超過64KB,嚐試從空閑鏈表中獲取一個64KB的內存塊返回給申請者;如果空閑鏈表為空,需要首先從操作係統中申請一批大小為64KB的內存塊加入空閑鏈表。釋放時將64KB的內存塊加入到空閑鏈表中以便下次重用。
  • 如果申請的內存超過64KB,直接調用Glibc 的內存分配(malloc)函數,向操作係統申請用戶所需大小的內存塊。釋放時直接調用Glibc的內存釋放(free)函數,將內存塊歸還操作係統。

OceanBase的全局內存池實現簡單,但內存使用率較低,即使申請幾個字節的內存,也需要占用大小為64KB的內存塊。因此,全局內存池不適合管理小塊內存,每個需要申請內存的模塊,比如UpdateServer中的MemTable,ChunkServer中的緩存等,都隻能從全局內存池中申請大塊內存,每個模塊內部再實現專用的內存池。每個線程會緩存若幹個大小分別為64KB和2MB的內存塊,每個線程總是首先嚐試從線程局部緩存中申請內存,如果申請不到,再從全局內存池中申請。

class ObIAllocator
{
public:
    //內存申請接口
    virtual void* alloc (const int64_t sz) = 0;
    //內存釋放接口
    virtual void free (void* ptr) = 0;
};
class ObMalloc : public ObIAllocator
{
public:
    //設置模塊號
    void set_mod_id(int32_t mod_id);
    //申請大小為sz的內存塊
    void * alloc (const int64_t sz);
    //釋放內存
    void free (void* ptr);
}
class ObTCMalloc : public ObIAllocator
{
publilc:
    //設置模塊號
    void set_mod_id(int32_t mod_id);
    //申請大小為sz的內存塊
    void * alloc (const int64_t sz);
    //釋放內存
    void free (void* ptr);
}

ObIAllocator 是內存管理器的接口,包含alloc和free兩個方法。ObMalloc和ObTCMalloc是兩個實現了ObIAllocator接口的全局內存池,不同點在於,ObMalloc不支持線程緩存,ObTCMalloc支持線程緩存。ObTCMalloc首先嚐試從線程局部的空閑鏈表申請內存塊,如果申請不到,在通過ObMalloc的alloc方法申請。釋放內存時,如果沒有超出線程緩存的內存塊個數限製,則將內存塊還給線程局部的空閑鏈表;否則,通過ObMalloc的free方法釋放。另外,允許通過set_mod_id函數設置申請者所在的模塊編號,便於統計每個模塊的內存使用情況。

全局內存池的意義如下:

  • 全局內存池可以統計每個模塊的內存使用情況,如果出現內存泄漏,可以很快定位到發生問題的模塊。
  • 全局內存池可用於輔助調試。例如,可以將全局內存池中申請到的內存塊按字節填充為某個非法的值(比如0xFE),當出現內存越界等問題時,服務器程序會很快在chu'xian'wen'ti'd出現問題的位置Core Dump,而不是帶著錯誤運行一段時間後才Core Dump,從而方便問題定位。

總而言之,OceanBase的內存管理沒有采用高深的技術,也沒有做到通用或者最優,但是很好的滿足了服務器程序開發的兩個最主要的需求:可控性以及沒有內存碎片。

最後更新:2017-07-08 18:02:15

  上一篇:go  阿裏人工智能實驗室王剛:找到合適的應用場景是實現人工智能商業化的關鍵點
  下一篇:go  將技術普惠進行到底,阿裏雲全網爆款最低30元/月