美文网首页
SeaweedFS索引文件内存管理

SeaweedFS索引文件内存管理

作者: DebugLiSir | 来源:发表于2018-05-02 15:47 被阅读0次

    当使用SeaweedFS系统储存1亿条索引数据时就会出现内存相对较大的问题,自己产生索引的key值时。

    索引文件形式

    索引文件中每个索引形式如下:

    Key|Offset|Size

    PS:Key的类型是uint64,Offset的类型是uint32,Size的类型是uint32。即索引大小为16个字节。

    所以当索引数量等于1亿时,如果将索引文件直接加载到内存中,其大小约为1.5G左右。由于直接加载到内存的话,不利于索引的查找,因此必须要对索引内存进行管理。SeaweedFS提供了4中索引内存管理方式,如下:

    1. InMemory
    2. LevelDb
    3. BoltDb
    4. Btree

    下面将分别对这四种内存管理方式进行讨论:

    InMemory

    其内存管理方式是由一系列的紧缩节组成,主要的数据结构如下:

    type CompactMap struct {              // InMemory使用的内存结构
            list []*CompactSection            // 多个节组成
     }
     type CompactSection struct {        // 每个节的构成
             sync.RWMutex                      // 节对应的读写锁
             values []NeedleValue            //  节的存储空间 
             overflow map[Key]NeedleValue  // 当values存满或者key小于values最后一个key值时存放在这里
             start Key                                // 本节中最小的那个key
             end Key                                 // 本节中最大的那个key
             counter int                             // values中key值个数 
     }
    

    InMemory时,索引插入操作如下:

    1. 首先查找是否存在能够包含当前key值的节,找到,则转2操作;未找到,则转3操作。
    2. 找到对应的节,则按key值大小顺序插入节内,如果节末key大于将要插入数据的key值或者节的大小超过bitch(默认节大小:100000),则转4操作;否则转5操作。
    3. 申请新节,并且节与节之间按照start字段的大小排序,然后转2操作继续进行插入节数据操作。
    4. 将数据存放在节中的overflow结构中。
    5. 将数据存放在values的末尾,并将counter+1

    PS:

    1. 这种管理方式要求节与节有序,并且每个节之内的所有数据也是有序的。
    2. 创建新节的条件是,未找到能够包含插入值的节。

    缺点

    1. 内存占用空间较大,例如两个数据也要开辟10W个数据的使用空间。
    2. 当数据上传顺序不合理时,会造成比较严重的空间浪费。(上传数据时按照数据中key值从小到大依次上传)
    3. 没有利用数据之间的关系,进行数据压缩来减少内存的占用率。

    数据实测:

    1G左右的索引数据,使用InMemory内存管理方式加载到内存后,内存占用大小约为3.6G左右。

    BTree

    SeaweedFS使用Google的度为32的BTree来实现内存索引管理,其对应的item为NeedValue。

    经过实地测试,使用这种索引方式来管理内存时,1亿个索引存放在内存中的大小为5G左右。

    缺点:

    1. 内存占用明显过大。

    levelDb

    SeaweedFS中使用的是syndtr按照google的leveldb(K/V)数据库编写的GOlang版本。

    SeaweedFS中会根据索引文件的时间戳来决定是否更新levelDB对应的文件,如果启动时不存在levelDB所需要的文件,则SeaWeedFs会读取索引文件中的条目来自动生成levelDB文件。

    leveldb数据库采用Snappy compression library来压缩数据,从而使数据方便存储。

    数据实测:

    1亿条索引,所占的内存空间为27M,申请的虚拟内存为900多M。比较符合项目要求。

    PS:
    SeaweedFS会在加载时统计需要删除的旧数据的大小。在使用leveldb内存管理时,会创建BTree来进行统计。
    统计完成后,BTree应当被GC。但是SeaWeedFS中BTree仍然存在,没有被销毁,占用较大内存。这里需要注意!!!
    sweedfs存在问题,unmout某个vid后,再mout时会出现leveldb不可用的错误。修改方案在unmout时,调用volume的close方法。

    Boltdb

    SeaweedFS使用的是bolt(K/V)数据。其加载以及使用方式基本与leveldb数据库相同。注意事项也一致。

    相关文章

      网友评论

          本文标题:SeaweedFS索引文件内存管理

          本文链接:https://www.haomeiwen.com/subject/gkiqrftx.html