def rescue_cluster(host, port, subst_host, subst_port): failed_slots = set(xrange(SLOT_COUNT)) t = None s = None try: t = Talker(host, port) _ensure_cluster_status_set(t) for node in _list_masters(t)[0]: failed_slots -= set(node.assigned_slots) if len(failed_slots) == 0: logging.info('No need to rescue cluster at %s:%d', host, port) return s = Talker(subst_host, subst_port) _ensure_cluster_status_unset(s) m = s.talk('cluster', 'meet', host, port) logging.debug('Ask `cluster meet` Rsp %s', m) if m.lower() != 'ok': raise RedisStatusError('Unexpected reply after MEET: %s' % m) m = s.talk('cluster', 'addslots', *failed_slots) logging.debug('Ask `cluster addslots` Rsp %s', m) if m.lower() != 'ok': raise RedisStatusError('Unexpected reply after ADDSLOTS: %s' % m) _poll_check_status(s) logging.info('Instance at %s:%d serves %d slots to rescue the cluster', subst_host, subst_port, len(failed_slots)) finally: if t is not None: t.close() if s is not None: s.close()
def start_cluster_on_multi(host_port_list): talkers = [] try: for host, port in set(host_port_list): t = Talker(host, port) talkers.append(t) _ensure_cluster_status_unset(t) logging.info('Instance at %s:%d checked', t.host, t.port) first_talker = talkers[0] for i, t in enumerate(talkers[1:]): t.talk('cluster', 'meet', first_talker.host, first_talker.port) slots_each = SLOT_COUNT / len(talkers) slots_residue = SLOT_COUNT - slots_each * len(talkers) first_node_slots = slots_residue + slots_each first_talker.talk('cluster', 'addslots', *xrange(first_node_slots)) logging.info('Add %d slots to %s:%d', slots_residue + slots_each, first_talker.host, first_talker.port) for i, t in enumerate(talkers[1:]): t.talk('cluster', 'addslots', *xrange( i * slots_each + first_node_slots, (i + 1) * slots_each + first_node_slots)) logging.info('Add %d slots to %s:%d', slots_each, t.host, t.port) for t in talkers: _poll_check_status(t) finally: for t in talkers: t.close()
def start_cluster_on_multi(host_port_list, max_slots=SLOT_COUNT): talkers = [] try: for host, port in set(host_port_list): t = Talker(host, port) talkers.append(t) _ensure_cluster_status_unset(t) logging.info('Instance at %s:%d checked', t.host, t.port) first_talker = talkers[0] for i, t in enumerate(talkers[1:]): t.talk('cluster', 'meet', first_talker.host, first_talker.port) slots_each = SLOT_COUNT / len(talkers) slots_residue = SLOT_COUNT - slots_each * len(talkers) first_node_slots = slots_residue + slots_each _add_slots(first_talker, 0, first_node_slots, max_slots) logging.info('Add %d slots to %s:%d', slots_residue + slots_each, first_talker.host, first_talker.port) for i, t in enumerate(talkers[1:]): _add_slots(t, i * slots_each + first_node_slots, (i + 1) * slots_each + first_node_slots, max_slots) logging.info('Add %d slots to %s:%d', slots_each, t.host, t.port) for t in talkers: _poll_check_status(t) finally: for t in talkers: t.close()
def replicate(master_host, master_port, slave_host, slave_port): master_talker = None t = Talker(slave_host, slave_port) try: master_talker = Talker(master_host, master_port) _ensure_cluster_status_set(master_talker) myself = _list_nodes(master_talker)[1] myid = (myself.node_id if myself.role_in_cluster == 'master' else myself.master_id) _join_to_cluster(master_host, master_port, t) logging.info('Instance at %s:%d has joined %s:%d; now set replica', slave_host, slave_port, master_host, master_port) m = t.talk('cluster', 'replicate', myid) logging.debug('Ask `cluster replicate` Rsp %s', m) if m.lower() != 'ok': raise RedisStatusError('Unexpected reply after REPCLIATE: %s' % m) _check_slave(slave_host, slave_port, master_talker) logging.info('Instance at %s:%d set as replica to %s', slave_host, slave_port, myid) finally: t.close() if master_talker is not None: master_talker.close()
def quit_cluster(host, port): nodes = [] myself = None t = Talker(host, port) try: _ensure_cluster_status_set(t) nodes, myself = _list_nodes(t) nodes.remove(myself) if myself.role_in_cluster == 'master': _check_master_and_migrate_slots(nodes, myself) logging.info('Migrated for %s / Broadcast a `forget`', myself.node_id) for node in nodes: tk = node.talker() try: tk.talk('cluster', 'forget', myself.node_id) except hiredis.ReplyError, e: if 'Unknown node' not in e.message: raise t.talk('cluster', 'reset')
def quit_cluster(host, port): nodes = [] myself = None t = Talker(host, port) try: _ensure_cluster_status_set(t) nodes, myself = _list_nodes(t) nodes.remove(myself) if myself.role_in_cluster == 'master': _check_master_and_migrate_slots(nodes, myself) logging.info('Migrated for %s / Broadcast a `forget`', myself.node_id) for node in nodes: tk = node.talker() tk.talk('cluster', 'forget', myself.node_id) t.talk('cluster', 'reset') finally: t.close() if myself is not None: myself.close() for n in nodes: n.close()
def start_cluster(host, port): t = Talker(host, port) try: _ensure_cluster_status_unset(t) m = t.talk('cluster', 'addslots', *xrange(SLOT_COUNT)) logging.debug('Ask `cluster addslots` Rsp %s', m) if m.lower() != 'ok': raise RedisStatusError('Unexpected reply after ADDSLOTS: %s' % m) _poll_check_status(t) logging.info('Instance at %s:%d started as a standalone cluster', host, port) finally: t.close()
def shutdown_cluster(host, port): t = Talker(host, port) try: _ensure_cluster_status_set(t) myself = None m = t.talk_raw(CMD_CLUSTER_NODES) logging.debug('Ask `cluster nodes` Rsp %s', m) nodes_info = filter(None, m.split('\n')) if len(nodes_info) > 1: raise RedisStatusError('More than 1 nodes in cluster.') try: m = t.talk('cluster', 'reset') except hiredis.ReplyError, e: if 'containing keys' in e.message: raise RedisStatusError('Cluster containing keys') raise logging.debug('Ask `cluster delslots` Rsp %s', m)