批量选举的递归实现

背景:分布式存储系统里,文件是分块存储的,如果每个文件块是1M,那么1G的文件就会有1024个文件块。系统需要为每个文件块分配合适的存储节点,这个过程我们称为选举。

问题:如果为每一个文件块都选举一次,那么1G的文件需要选举1024次,这样对系统要求较高,耗时较长。但如果为1024个文件块选举一次,那么会导致文件分布不均匀,同时如果存储节点没有足够的空间,会导致选举失败。

解决思路:默认按64M选举,如每个文件块为1M,则64个文件块分布在相同的存储节点上。如选举因空间不足导致失败,则减少选举文件大小64->32->16->8,直到无法减少。


int AllotPageStoreList(
    const list<PageTagInfo>& page_tag_info_list, //文件块列表
    const uint32_t replica_factor,		//需要的副本数
    list<PageForwardNodesInfo>& page_forward_nodes_info_list,	//选举出来的存储节点
    uint32_t& max_allot_size)		//每次选举的文件大小(64M)
{
    list<PageTagInfo> allot_page_list;		//每次选举的块列表
    uint32_t allot_size = 0;                //本次选举的文件块大小
    for(list<PageTagInfo>::const_iterator it = page_tag_info_list.begin(); it != page_tag_info_list.end();)
    {

        allot_size += it->page_size;   	//根据文件块大小,增加本次选举的文件大小
        allot_page_list.push_back(*it); //同时记录下本次的文件块
        ++it;

        if((allot_size < max_allot_size) && (it != page_tag_info_list.end()))
        {
            continue;
        }
        //直到本次选举的文件大小达到要求,或文件块已选举完,则开始选举
        
        status = root_service_.GetNodeManager()->AllotStoreNode(allot_size,node_list,replica_factor);
        
        //如因存储空间不足导致失败,则将选举的文件大小减半,递归选举
        if(error_disk_full == status)
        {
            if(allot_page_list.size() < 2)  //列表里只有一个,无法再分了,直接返回失败
            {
                return status;
            }

            max_allot_size = max_allot_size / 2; //将选举的文件大小减半

            list<PageForwardNodesInfo> allot_page_forward_nodes_info_list;
            status = AllotPageStoreList(allot_page_list,replica_factor,allot_page_forward_nodes_info_list,max_allot_size); //递归选举
            //直到选举成功
            if(status != btq_error_success) 
            {
                return status;
            }

            if((allot_page_list.size() != allot_page_forward_nodes_info_list.size())) //如果选举出来的文件块数量不对,则认为失败
            {
                return error_failed;
            }

            //将选举好的文件块->存储节点的信息与需要返回的合并
            page_forward_nodes_info_list.splice(page_forward_nodes_info_list.end(),allot_page_forward_nodes_info_list);
        }
        else if(error_success == status)
        {
            //选举成功,则为每个文件块分配存储节点
            for(list<PageTagInfo>::iterator allot_it = allot_page_list.begin(); allot_it != allot_page_list.end(); ++allot_it)
            {
                page_forward_nodes_info.page_tag =  *allot_it; //记录某次文件块
                page_forward_nodes_info.node_list = node_list; //将选举成功的存储节点赋值
                page_forward_nodes_info_list.push_back(page_forward_nodes_info);  //将选举好的文件块->存储节点的信息与需要返回的合并
            } 
        } 
        else 
        {
            return status; 
        } 
        
        allot_size = 0; //选举的文件大小归零
        allot_page_list.clear(); //清空文件块列表 
    } 
    
    if((page_tag_info_list.size() != page_forward_nodes_info_list.size()))
    { 
        return error_failed;
    } 
    
    return status;
}


</pre><pre>


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值