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

本文深入探讨了TFS存储系统的内部工作原理,包括DataServer如何初始化存储空间并划分Block,以及NameServer如何选择合适的DataServer来创建新的Block。此外,还详细介绍了客户端请求Block的过程。
摘要由CSDN通过智能技术生成
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)
    {
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值