tair的fdb原理

tair是taobao的KV数据库,支持插拔的插件开发和文件和内存两种存储引擎,以下是对他文件存储引擎的原理剖析。

CURD的数据都是以item的形式给出,每个item的结构如下:

主要由几部分构成:

1)  元数据部分,bucket_index表示了keyhashcode在索引文件bucket段中间的位置。

Meta_offset表示了该keymeta数据在索引文件的meta_pools段中的偏移量。

2)  meta部分,表示了该key将写入索引文件的meta_pools段的内容。其中size表示该key写入数据文件的信息的长度,这些信息包括data段,keyvalue

3)  data段包括数据的描述元信息,如修改时间,创建时间,版本,padsize等等。

4)  keyvalue

 

物理文件存在索引文件和数据文件两种,每种文件都有特定的IMAGE头做标识。

 

索引文件如下:

索引文件分为三部分

1)  元数据,包括了item的数量,其中有几个参数非常重要:

Idx_file_size:表示当前的metaoffset,当没有delete数据的前提下,该数据表示下一个itemmeta数据在meta_pools中的offset

Dat_file_size:表示了数据文件中的下一个itemdata中的offset

Free_idx_header:当某些key delete的时候,其key会在meta_pools中回收,这个时候free_idx_header维持着一条free meta链条的指针(因为meta的长度是固定的)。

2)  meta信息索引区:这个区域的数量基本上是bucket count*4,先用keyhashcode%bucketCount来取得一组同义词(hashcode%bucketCount相等)的中首个同义词在meta_pools中的offset,也就是item中的meta_offset.然后用进行同义词树遍历查找。知道找到该hashcode==key.hashcodeitem进行update或者找到树的叶子节点判断为该key的数据为null,必须new

3)  元描述数据存储区:主要是用来存储item结构中的meta信息段,因为meta信息和写入数据文件的信息不同的是,其长度是固定的,所以,同义词的meta信息会用meta信息中的leftright来表示树的左子节点和右子节点。其中二叉树是有序的二叉树。

 

 

数据文件:

主要包括两部分:

1)  IMAGE信息。

2)  数据的存储区,存储的数据包括item的数据区,keyvalue

 

其中新增数据的场景如下:

 

关于回收

1)索引文件的回收。当key被删除的时候,meta_pools中的meta会被回收,所有被回收的meta空间被leftright串行起来组成链表,回收的时候,将会将index元信息中的free_idx_header作为指针指向链表的端点,当下一次有key进行new的时候,优先分配这个回收链表中的meta空间。

         //首先判断时候有回收的空间。

if(header->free_idx_head != 0) {

          fdb_item temp_item;

          temp_item.meta_offset = header->free_idx_head;

          log_debug("read from freeindex, offset: %llu",

                    temp_item.meta_offset);

          if(read_meta(temp_item) && (temp_item.meta.size == 0)) {

            log_debug("set new item's meta offset to: %llu",

                      temp_item.meta_offset);

            ret_item.meta_offset = temp_item.meta_offset;

            header->free_idx_head = temp_item.meta.left;

          }

        }

        PROFILER_END();

                   //其次再从meta_pools的尾巴上开始分配

        if(ret_item.meta_offset == 0) {

          ret_item.meta_offset = header->idx_file_size;

          log_debug("set meta offset to index file: %llu",

                    header->idx_file_size);

          header->idx_file_size += FDB_ITEM_META_SIZE;

        }

2)数据文件的回收,数据文件的回收分为updatedelete两种,update的时候,如果原来的value分配的空间小于更新的value的空间,那么要将原来的data的空间回收,另外分配新的数据空间。Delete也是同样的道理。回收后的空间,将被放入到数据文件的一个pool中进行统一管理。

                   free_block.size = old_item.meta.size;

        free_block.offset = old_item.meta.offset;

                   //进行统一管理。

        fb_manager->insert(free_block);

在分配数据空间的时候,会先从这个free pool中看是否能够找到足够容纳下的连续的数据空间。否则则按照index文件的元数据dat_file_size后面进行分配。

if(fb_manager->search(ret_item.meta.size, fb)) {

          ret_item.meta.offset = fb.offset;

          ret_item.meta.size = fb.size;

        }

        else {

          ret_item.meta.offset = header->dat_file_size;

          header->dat_file_size += ret_item.meta.size;

        }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值