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); }
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 } }
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); }
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 } } }