def perform_resharding(masters_with_slots, masters_without_slots, source): amount_of_masters = len(masters_with_slots) + len(masters_without_slots) i = 0 for master_with_slots in masters_with_slots: shards_amount_master_will_give = master_with_slots.calculate_amount_of_shards( amount_of_masters) logger.debug("%s will give %s shards per split" % (master_with_slots, shards_amount_master_will_give)) shards_amount_per_one_master = int(shards_amount_master_will_give) for master_without_slots in masters_without_slots: cmd_args = [ '--cluster', 'reshard', source, '--cluster-from', master_with_slots.node_id, '--cluster-to', master_without_slots.node_id, '--cluster-slots', str(shards_amount_per_one_master), '--cluster-yes' ] logger.debug( "Sharding %s to %s %s slots" % (master_with_slots.node_id, master_without_slots.node_id, shards_amount_per_one_master)) run_redis_cli_cmd(cmd_args, False) logger.debug('Soon will run sanity check') time.sleep(5) cmd_args = [ '--cluster', 'fix', master_without_slots.ip + ":" + str(master_without_slots.port) ] result = run_redis_cli_cmd(cmd_args, True) logger.debug('Sanity check returned code %s' % (str(result.returncode))) i += 1
def is_valid_redis_node(node_address): logging.debug('Validating connection to the %s', node_address) host, port = util.split_address(node_address) cmd_args = ['-c', '-h', host, '-p', port, 'ping'] result = util.run_redis_cli_cmd(cmd_args, True) parsed_cmd_result = result.stdout.decode("utf-8").rstrip() if parsed_cmd_result == "PONG": cmd_args = ['-c', '-h', host, '-p', port, 'cluster', 'info'] result = util.run_redis_cli_cmd(cmd_args, True) parsed_cmd_result = result.stdout.decode("utf-8").rstrip() if parsed_cmd_result.find("cluster_size:0") >= 0: logging.error( 'Managed to establish a connection with the %s node. But node is a part of an empty redis cluster', node_address) return False logging.debug('Successfully established connection to %s', node_address) return True logging.error( 'Could not establish connection with the %s node. Returned code: %s', node_address, result.returncode) return False
def add_node_to_cluster(source, target, target_role): for redis_node_address in target: host, port = split_address(redis_node_address) if is_ip(host): is_valid_redis_node(redis_node_address) logging.info('Adding %s with the %s role to the cluster ', target, target_role) full_node_address = host + ":" + str(port) cmd = ['--cluster', 'add-node', full_node_address, source] if target_role == "slave": cmd.append("--cluster-slave") result = run_redis_cli_cmd(cmd, True) if result.returncode == 0: logging.info('[V] Node %s was added to the cluster with role %s', full_node_address, target_role) else: logging.error( '[X] Node %s was NOT added to the cluster. ' 'Check if the given node is in clustered mode, ' 'if is it empty or if this node is already part of the cluster', full_node_address) else: logging.error( '[X] %s node does not have a valid address', target)
def get_slot_distribution(host, port): cmd_args = ['-c', '-h', host, '-p', port, 'cluster', 'nodes'] result = util.run_redis_cli_cmd(cmd_args, True) result_as_array = parse_cmd_output_to_array(result.stdout) return extract_cluster_masters(result_as_array)