예제 #1
0
void load_balancer::run_lb(partition_configuration& pc)
{
    if (_state->freezed())
        return;

    configuration_update_request proposal;
    proposal.config = pc;

    if (pc.primary.is_invalid())
    {
        if (pc.secondaries.size() > 0)
        {
            proposal.node = pc.secondaries[dsn_random32(0, static_cast<int>(pc.secondaries.size()) - 1)];
            proposal.type = CT_UPGRADE_TO_PRIMARY;
        }

        else if (pc.last_drops.size() == 0)
        {
            proposal.node = find_minimal_load_machine(true);
            proposal.type = CT_ASSIGN_PRIMARY;
        }

        // DDD
        else
        {
            proposal.node = *pc.last_drops.rbegin();
            proposal.type = CT_ASSIGN_PRIMARY;

            derror("%s.%d.%d enters DDD state, we are waiting for its last primary node %s to come back ...",
                pc.app_type.c_str(),
                pc.gpid.app_id,
                pc.gpid.pidx,
                proposal.node.to_string()
                );
        }

        if (proposal.node.is_invalid() == false)
        {
            send_proposal(proposal.node, proposal);
        }
    }

    else if (static_cast<int>(pc.secondaries.size()) + 1 < pc.max_replica_count)
    {
        proposal.type = CT_ADD_SECONDARY;
        proposal.node = find_minimal_load_machine(false);
        if (proposal.node.is_invalid() == false && 
            proposal.node != pc.primary &&
            std::find(pc.secondaries.begin(), pc.secondaries.end(), proposal.node) == pc.secondaries.end())
        {
            send_proposal(pc.primary, proposal);
        }
    }
    else
    {
        // it is healthy, nothing to do
    }
}
void simple_stateful_load_balancer::explictly_send_proposal(global_partition_id gpid, rpc_address receiver, config_type type, rpc_address node)
{
    if (gpid.app_id <= 0 || gpid.pidx < 0 || type == CT_NONE)
    {
        derror("invalid params");
        return;
    }

    configuration_update_request req;
    {
        zauto_read_lock l(_state->_lock);
        if (gpid.app_id > _state->_apps.size())
        {
            derror("invalid params");
            return;
        }
        app_state& app = _state->_apps[gpid.app_id-1];
        if (gpid.pidx>=app.partition_count)
        {
            derror("invalid params");
            return;
        }
        req.config = app.partitions[gpid.pidx];
    }

    req.type = type;
    req.node = node;
    send_proposal(receiver, req);
}
예제 #3
0
void load_balancer::run_lb(partition_configuration& pc)
{
    if (_state->freezed())
        return;

    configuration_update_request proposal;
    proposal.config = pc;

    if (pc.primary == end_point::INVALID)
    {
        if (pc.secondaries.size() > 0)
        {
            proposal.node = pc.secondaries[env::random32(0, static_cast<int>(pc.secondaries.size()) - 1)];
            proposal.type = CT_UPGRADE_TO_PRIMARY;
        }
        else
        {
            proposal.node = find_minimal_load_machine(true);
            proposal.type = CT_ASSIGN_PRIMARY;
        }

        if (proposal.node != end_point::INVALID)
        {
            send_proposal(proposal.node, proposal);
        }
    }

    else if (static_cast<int>(pc.secondaries.size()) + 1 < pc.max_replica_count)
    {
        proposal.type = CT_ADD_SECONDARY;
        proposal.node = find_minimal_load_machine(false);
        if (proposal.node != end_point::INVALID)
        {
            send_proposal(pc.primary, proposal);
        }
    }
    else
    {
        // it is healthy, nothing to do
    }
}
예제 #4
0
void load_balancer::explictly_send_proposal(global_partition_id gpid, int role, config_type type)
{
    if (gpid.app_id<=0 || gpid.pidx<0 || role<0) return;

    configuration_update_request req;
    {
        zauto_read_lock l(_state->_lock);
        if (gpid.app_id>_state->_apps.size())
            return;
        app_state& app = _state->_apps[gpid.app_id-1];
        if (gpid.pidx>=app.partition_count)
            return;
        req.config = app.partitions[gpid.pidx];
    }

    dsn::rpc_address proposal_receiver;
    if (!req.config.primary.is_invalid())
        proposal_receiver = req.config.primary;
    else if (!req.config.secondaries.empty())
        proposal_receiver = req.config.secondaries[0];
    else {
        dwarn("no replica in partition config");
        return;
    }

    if (!req.config.primary.is_invalid())
    {
        req.node = req.config.primary;
        --role;
    }

    if (role >= (int)req.config.secondaries.size())
    {
        dwarn("role doesn't exist");
        return;
    }
    else if (role != -1)
        req.node = req.config.secondaries[role];

    req.type = type;
    send_proposal(proposal_receiver, req);
}
예제 #5
0
void simple_load_balancer::run_lb(app_info& info, partition_configuration& pc, bool is_stateful)
{
    if (_state->freezed() && is_stateful)
        return;

    configuration_update_request proposal;
    proposal.config = pc;
    proposal.info = info;

    if (is_stateful)
    {
        if (pc.primary.is_invalid())
        {
            if (pc.secondaries.size() > 0)
            {
                if (s_lb_for_test)
                {
                    std::vector< ::dsn::rpc_address> tmp(pc.secondaries);
                    std::sort(tmp.begin(), tmp.end());
                    proposal.node = tmp[0];
                }
                else
                {
                    proposal.node = pc.secondaries[dsn_random32(0, static_cast<int>(pc.secondaries.size()) - 1)];
                }
                proposal.type = config_type::CT_UPGRADE_TO_PRIMARY;
            }

            else if (pc.last_drops.size() == 0)
            {
                proposal.node = find_minimal_load_machine(true);
                proposal.type = config_type::CT_ASSIGN_PRIMARY;
            }

            // DDD
            else
            {
                proposal.node = *pc.last_drops.rbegin();
                proposal.type = config_type::CT_ASSIGN_PRIMARY;

                derror("%s.%d.%d enters DDD state, we are waiting for its last primary node %s to come back ...",
                    info.app_type.c_str(),
                    pc.pid.get_app_id(),
                    pc.pid.get_partition_index(),
                    proposal.node.to_string()
                    );
            }

            if (proposal.node.is_invalid() == false)
            {
                send_proposal(proposal.node, proposal);
            }
        }

        else if (static_cast<int>(pc.secondaries.size()) + 1 < pc.max_replica_count)
        {
            proposal.type = config_type::CT_ADD_SECONDARY;
            proposal.node = find_minimal_load_machine(false);
            if (proposal.node.is_invalid() == false &&
                proposal.node != pc.primary &&
                std::find(pc.secondaries.begin(), pc.secondaries.end(), proposal.node) == pc.secondaries.end())
            {
                send_proposal(pc.primary, proposal);
            }
        }
        else
        {
            // it is healthy, nothing to do
        }
    }
    
    // stateless
    else
    {
        partition_configuration_stateless pcs(pc);

        if (static_cast<int>(pcs.worker_replicas().size()) < pc.max_replica_count)
        {
            proposal.type = config_type::CT_ADD_SECONDARY;
            proposal.node = find_minimal_load_machine(false);
            if (proposal.node.is_invalid() == false)
            {
                bool send = true;

                for (auto& s : pc.secondaries)
                {
                    // not on the same machine
                    if (s == proposal.node)
                    {
                        send = false;
                        break;
                    }
                }

                if (send)
                {
                    send_proposal(proposal.node, proposal);
                }
            }
        }
        else
        {
            // it is healthy, nothing to do
        }
    }
}