def _ensure_cluster_status_set(t): m = t.send_raw(CMD_INFO) logging.debug('Ask `info` Rsp %s', m) cluster_enabled = PAT_CLUSTER_ENABLED.findall(m) if len(cluster_enabled) == 0 or int(cluster_enabled[0]) == 0: raise hiredis.ProtocolError('Node %s:%d is not cluster enabled' % (t.host, t.port)) m = t.send_raw(CMD_CLUSTER_INFO) logging.debug('Ask `cluster info` Rsp %s', m) cluster_state = PAT_CLUSTER_STATE.findall(m) cluster_slot_assigned = PAT_CLUSTER_SLOT_ASSIGNED.findall(m) if cluster_state[0] != 'ok' and int(cluster_slot_assigned[0]) == 0: raise hiredis.ProtocolError('Node %s:%d is not in a cluster' % (t.host, t.port))
def _ensure_cluster_status_unset(t): m = t.talk_raw(CMD_PING) if m.lower() != 'pong': raise hiredis.ProtocolError('Expect pong but recv: %s' % m) m = t.talk_raw(CMD_INFO) logging.debug('Ask `info` Rsp %s', m) cluster_enabled = PAT_CLUSTER_ENABLED.findall(m) if len(cluster_enabled) == 0 or int(cluster_enabled[0]) == 0: raise hiredis.ProtocolError( 'Node %s:%d is not cluster enabled' % (t.host, t.port)) m = t.talk_raw(CMD_CLUSTER_INFO) logging.debug('Ask `cluster info` Rsp %s', m) cluster_state = PAT_CLUSTER_STATE.findall(m) cluster_slot_assigned = PAT_CLUSTER_SLOT_ASSIGNED.findall(m) if cluster_state[0] != 'fail' or int(cluster_slot_assigned[0]) != 0: raise hiredis.ProtocolError( 'Node %s:%d is already in a cluster' % (t.host, t.port))
def join_cluster(cluster_host, cluster_port, newin_host, newin_port): t = Talker(newin_host, newin_port) try: _ensure_cluster_status_unset(t) m = t.talk('cluster', 'meet', cluster_host, cluster_port) if m.lower() != 'ok': raise RedisStatusError('Unexpected reply after MEET: %s' % m) _poll_check_status(t) logging.info('Instance at %s:%d has joined %s:%d; now balancing slots', newin_host, newin_port, cluster_host, cluster_port) m = t.talk_raw(CMD_CLUSTER_INFO) cluster_state = PAT_CLUSTER_STATE.findall(m) if cluster_state[0] != 'ok': raise hiredis.ProtocolError('Node %s:%d is already in a cluster' % (t.host, t.port)) slots = int(PAT_CLUSTER_SLOT_ASSIGNED.findall(m)[0]) myself = None nodes = [] m = t.talk_raw(CMD_CLUSTER_NODES) for node_info in m.split('\n'): if len(node_info) == 0: continue node = ClusterNode(*node_info.split(' ')) if 'myself' in node_info: myself = node else: nodes.append(node) if myself is None: raise RedisStatusError('Myself is missing:\n%s' % m) mig_slots_in_each = SLOT_COUNT / (1 + len(nodes)) / len(nodes) logging.info('Migrating %d slots in each nodes', mig_slots_in_each) for node in nodes: _migr_slot(node, t, myself.node_id, mig_slots_in_each, nodes) finally: t.close()
def join_cluster(cluster_host, cluster_port, newin_host, newin_port, balancer=None, balance_plan=base_balance_plan): nodes = [] t = Talker(newin_host, newin_port) try: _join_to_cluster(cluster_host, cluster_port, t) logging.info('Instance at %s:%d has joined %s:%d; now balancing slots', newin_host, newin_port, cluster_host, cluster_port) m = t.talk_raw(CMD_CLUSTER_INFO) logging.debug('Ask `cluster info` Rsp %s', m) cluster_state = PAT_CLUSTER_STATE.findall(m) if cluster_state[0] != 'ok': raise hiredis.ProtocolError( 'Node %s:%d is already in a cluster' % (t.host, t.port)) slots = int(PAT_CLUSTER_SLOT_ASSIGNED.findall(m)[0]) nodes = _list_nodes(t, default_host=newin_host)[0] for source, target, count in balance_plan(nodes, balancer): _migr_slots(source, target, count, nodes) finally: t.close() for n in nodes: n.close()