Exemple #1
0
def rescue_cluster(host, port, subst_host, subst_port):
    failed_slots = set(xrange(SLOT_COUNT))
    with Talker(host, port) as t:
        _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

        with Talker(subst_host, subst_port) as s:
            _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))
Exemple #2
0
def _poll_check_status(t):
    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] != 'ok' or int(cluster_slot_assigned[0]) != SLOT_COUNT:
        raise RedisStatusError('Unexpected status: %s' % m)
Exemple #3
0
def _check_slave(slave_host, slave_port, t):
    slave_addr = '%s:%d' % (slave_host, slave_port)
    for line in t.talk('cluster', 'nodes').split('\n'):
        if slave_addr in line:
            if 'slave' in line:
                return
            raise RedisStatusError('%s not switched to a slave' % slave_addr)
Exemple #4
0
def shutdown_cluster(host, port):
    with Talker(host, port) as t:
        _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)
Exemple #5
0
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()
Exemple #6
0
 def expect_talk_ok(m, slot):
     if m.lower() != 'ok':
         raise RedisStatusError('\n'.join([
             'Error while moving slot [ %d ] between' % slot,
             'Source node - %s:%d' % (source_node.host, source_node.port),
             'Target node - %s:%d' % (target_node.host, target_node.port),
             'Got %s' % m]))
Exemple #7
0
def _join_to_cluster(clst, new):
    _ensure_cluster_status_set(clst)
    _ensure_cluster_status_unset(new)

    m = clst.talk('cluster', 'meet', new.host, new.port)
    logging.debug('Ask `cluster meet` Rsp %s', m)
    if m.lower() != 'ok':
        raise RedisStatusError('Unexpected reply after MEET: %s' % m)
    _poll_check_status(new)
Exemple #8
0
def start_cluster(host, port):
    with Talker(host, port) as t:
        _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)
 def raise_(self, message):
     raise RedisStatusError(message, self.host, self.port)
Exemple #10
0
 def addslots(t, begin, end):
     m = t.talk('cluster', 'addslots', *xrange(begin, end))
     logging.debug('Ask `cluster addslots` Rsp %s', m)
     if m.lower() != 'ok':
         raise RedisStatusError('Unexpected reply after ADDSLOTS: %s' % m)