TFS分析(基于1.3.1) -- BlockId 的生成

来源:互联网 发布:网络外部性和规模效应 编辑:程序博客网 时间:2024/05/18 02:10
TFS的官方文档里面提到:在TFS中,将大量的小文件(实际数据文件)合并成为一个大文件,这个大文件称为块(Block), 每个Block拥有在集群内唯一的编号(Block Id), Block Id在NameServer在创建Block的时候分配。
对此有如下疑问:
DataServer在初始化的时候就已经将所有的block全部建立出来了,nameServer在什么时候来通知DataServer来分配block呢。


我们先来看看DataServer初始化的时候会做了哪些事情:
1、通过BlockFileManager的format_block_file_system函数来初始化存储空间,将存储空间划分为多个block,同时建立相应的索引文件

int BlockFileManager::format_block_file_system(const SysParam::FileSystemParam& fs_param)    {............................................      // 3. create super block file      //该函数会在存储空间新建一个super索引文件,以后服务启动的时候会通过该文件加载DataServer里的所有Block信息      ret = create_fs_super_blk();      if (TFS_SUCCESS != ret)        return ret;............................................      return TFS_SUCCESS;    }

2、DataServer在上报心跳的时候,上报自身的存储信息已经已有的block信息。

//节点的状态信息,NameServer根据状态信息,选举合适的DataServer新建Block(待确定,还没有找到相关的实现代码)struct DataServerStatInfo    {      uint64_t id_;      int64_t use_capacity_;      int64_t total_capacity_;      int32_t current_load_;      int32_t block_count_;      int32_t last_update_time_;      int32_t startup_time_;      Throughput total_tp_;      int32_t current_time_;      DataServerLiveStatus status_;    };    

//用来标识该DataServer包含有哪些block    typedef std::vector<BlockInfo> BLOCK_INFO_LIST

4、当Client调用Open时,NameServer会给Client选择一个blockId,供Client写入
int MetaManager::write_block_info(uint32_t& block_id, int32_t mode, uint32_t& lease_id, int32_t& version,        VUINT64& ds_list)    {    ..............................................................          //nameserver assign a new write block      if ((block_id == 0)          && (mode & BLOCK_CREATE))      {        VINT64 fail_ds;        //选择一个合适的block id        block_id = elect_write_block(fail_ds);        if (block_id == 0)        {          TBSYS_LOG(ERROR, "elect write block faild...");          return EXIT_NO_BLOCK;        }      }      BlockChunkPtr ptr = meta_mgr_.get_block_chunk(block_id);      ptr->mutex_.rdlock();      BlockCollect* block_collect = ptr->find(block_id);      // create block in slave nameserver.      if ((mode & BLOCK_NEWBLK))      {        if (block_collect == NULL)        {          ptr->mutex_.unlock();          //如果block id 不存在,则通知DataServer新建          block_collect = add_new_block(block_id);          if (block_collect == NULL)          {            TBSYS_LOG(ERROR, "add new block(%u) failed, dataserver not found", block_id);            return EXIT_NO_DATASERVER;          }          ptr->mutex_.rdlock();          TBSYS_LOG(DEBUG, "block(%u), not found meta data, add new(%p)", block_id, block_collect);        }       ............................................................      }......................................................................      return TFS_SUCCESS;    }
    
    //通知DataServer新建一个block     BlockCollect* MetaManager::add_new_block(uint32_t& block_id, const uint64_t ds_id)    {.....................................................................      for (uint32_t i = 0; i < elect_ds_list.size(); ++i)      {        TBSYS_LOG(DEBUG, "dataserver(%s)", tbsys::CNetUtil::addrToString(elect_ds_list[i]).c_str());        NewBlockMessage nbmsg;        nbmsg.add_new_id(new_block_id);        //给DataServer发送NewBlockMessage消息,通知DataServer新建Block(阻塞模式)        if (send_message_to_server(elect_ds_list[i], &nbmsg, NULL) == TFS_SUCCESS)        {          add_success_ds_list.push_back(elect_ds_list[i]);          TBSYS_LOG(INFO, "add block:%u on server:%s succeed", new_block_id, tbsys::CNetUtil::addrToString(                elect_ds_list[i]).c_str());        }        else        {          TBSYS_LOG(INFO, "add block:%u on server:%s failed", new_block_id, tbsys::CNetUtil::addrToString(                elect_ds_list[i]).c_str());        }      }......................................................      return block_collect;    }
    
5、当DataServer收到NewBlockMessage消息,则新建BlockId,同时缓存,并持久化到硬盘(源码步骤很详细,不细说明)
   int BlockFileManager::new_block(const uint32_t logic_block_id, uint32_t& physical_block_id,        const BlockType block_type)    {    }

0 0