예제 #1
0
    def set(self, key, value, all=False, save=False, host=None, port=None):
        """Command: redis-cli config set

        :param key: target key
        :param value: value to set
        :param save: If true, save value to config file
        :param all: If true, send command to all redis
        :param host: host info for redis
        :param port: port info for redis
        """
        if not isinstance(all, bool):
            msg = m.get('error_option_type_not_boolean')
            msg = msg.format(options='all')
            logger.error(msg)
            return
        if not isinstance(save, bool):
            msg = m.get('error_option_type_not_boolean')
            msg = msg.format(options='save')
            logger.error(msg)
            return
        if (not host or not port) and not all:
            msg = m.get('use_host_port_or_option_all')
            logger.error(msg)
            return
        sub_cmd = 'config set {key} {value} 2>&1'.format(key=key, value=value)
        if all:
            meta = []
            ret = RedisCliUtil.command_all_async(sub_cmd)
            ok_cnt = 0
            for m_s, host, port, result, message in ret:
                addr = '{}:{}'.format(host, port)
                if result == 'OK':
                    if utils.to_str(message) == 'OK':
                        ok_cnt += 1
                    else:
                        meta.append([m_s, addr, color.red(message)])
                else:
                    meta.append([m_s, addr, color.red('FAIL')])
            if meta:
                utils.print_table([['TYPE', 'ADDR', 'RESULT']] + meta)
            logger.info('success {}/{}'.format(ok_cnt, len(ret)))
        else:
            output = RedisCliUtil.command(sub_cmd=sub_cmd,
                                          host=host,
                                          port=port,
                                          formatter=self.no_print)
            output = output.strip()
            if output == "OK":
                logger.info(output)
            else:
                logger.error(output)
        if save:
            RedisCliUtil.save_redis_template_config(key, value)
            center = Center()
            center.update_ip_port()
            success = center.check_hosts_connection()
            if not success:
                return
            center.configure_redis()
            center.sync_conf()
예제 #2
0
    def rowcount(self):
        """Query and show cluster row count
        """
        logger.debug('rowcount')

        masters = []
        center = Center()
        center.update_ip_port()
        master_nodes = center.get_master_obj_list()
        for master_node in master_nodes:
            node = master_node['addr']
            masters.append(node)

        # open-redis-cli-all info Tablespace | grep totalRows | awk -F ',
        # ' '{print $4}' | awk -F '=' '{sum += $2} END {print sum}'
        ret = RedisCliUtil.command_all_async('info Tablespace', slave=True)
        outs = ''
        for _, host, port, res, stdout in ret:
            if res == 'OK':
                endpoint = '{}:{}'.format(host, port)
                if endpoint in masters:
                    outs = '\n'.join([outs, stdout])
            else:
                logger.warning("FAIL {}:{} {}".format(host, port, stdout))
        lines = outs.splitlines()

        key = 'totalRows'
        partitions = 'partitions'
        evictions = 'evictedRows'
        filtered_lines = (filter(lambda x: key in x, lines))
        #self._print(filtered_lines)

        # Table list
        table_list = []
        result = []
        for line in filtered_lines:
            tableStats, _ = line.split(':')
            tableId = tableStats.split('_')
            if tableId[1] in table_list:
                pass
            else:
                table_list.append(tableId[1])

        for tid in table_list:
            table_lines = (filter(lambda x: tid in x, filtered_lines))
            ld = RedisCliUtil.to_list_of_dict(table_lines)
            row_count = reduce(lambda x, y: x + int(y[key]), ld, 0)
            partitions_count = reduce(lambda x, y: x + int(y[partitions]), ld,
                                      0)
            evictions_count = reduce(lambda x, y: x + int(y[evictions]), ld, 0)
            result.append([tid, row_count, partitions_count, evictions_count])

        utils.print_table(
            [['Table_ID', 'ROW_COUNT', 'PARTITION_COUNT', 'EVICTED_ROWS']] +
            result)
예제 #3
0
    def masters_with_dir(self, server, dir):
        """Find masters that use the specified directory path

        :param server: IP or hostname
        :param dir: directory path
        """
        center = Center()
        center.update_ip_port()
        logger.debug('masters_with_dir')
        master_nodes = center.get_master_obj_list()
        ret = RedisCliUtil.command_all_async('config get dir', slave=True)
        outs = ''
        meta = []
        m_endpoint = []
        for node in master_nodes:
            m_endpoint.append(node['addr'])
        for _, host, port, res, stdout in ret:
            if res == 'OK':
                flat_stdout = '\n'.join([outs, stdout])
                line = flat_stdout.splitlines()
                if self.compare_ip(host, server) and dir in line[2]:
                    endpoint = '{}:{}'.format(socket.gethostbyname(host), port)
                    if endpoint in m_endpoint:
                        meta.append([host, port, line[2]])
            else:
                logger.warning("FAIL {}:{} {}".format(host, port, stdout))
        utils.print_table([['HOST', 'PORT', 'PATH']] + meta)
예제 #4
0
    def find_noaddr(self):
        """Find noaddr nodes that is not used anymore in cluster
        """
        center = Center()
        center.update_ip_port()
        logger.debug('find_noaddr')
        ret = RedisCliUtil.command_all_async('cluster nodes', slave=True)
        outs = ''
        meta = []
        for _, host, port, res, stdout in ret:
            if res == 'OK':
                outs = '\n'.join([outs, stdout])
                lines = outs.splitlines()
                filtered_lines = (filter(lambda x: 'noaddr' in x, lines))
            else:
                logger.warning("FAIL {}:{} {}".format(host, port, stdout))

        total_list = []
        for line in filtered_lines:
            total_list.append(line.split()[0])

        # Remove duplicates
        unique_list = list(set(total_list))
        for uuid in unique_list:
            meta.append([uuid])
        utils.print_table([['UUID']] + meta)
예제 #5
0
    def failover_with_dir(self, server, dir):
        """Find masters that use the specified directory path and do failover with its slave

        :param server: IP or hostname
        :param dir: directory path
        """
        center = Center()
        center.update_ip_port()
        logger.debug('failover_with_dir')
        master_nodes = center.get_master_obj_list()
        cluster_id = config.get_cur_cluster_id()
        lib_path = config.get_ld_library_path(cluster_id)
        path_of_fb = config.get_path_of_fb(cluster_id)
        sr2_redis_bin = path_of_fb['sr2_redis_bin']
        env_cmd = [
            'GLOBIGNORE=*;',
            'export LD_LIBRARY_PATH={};'.format(lib_path['ld_library_path']),
            'export DYLD_LIBRARY_PATH={};'.format(
                lib_path['dyld_library_path']),
        ]
        redis_cli_cmd = os.path.join(sr2_redis_bin, 'redis-cli')

        # Find masters with dir
        ret = RedisCliUtil.command_all_async('config get dir', slave=True)
        outs = ''
        meta = []
        m_endpoint = []
        for node in master_nodes:
            m_endpoint.append(node['addr'])
        for _, host, port, res, stdout in ret:
            if res == 'OK':
                flat_stdout = '\n'.join([outs, stdout])
                line = flat_stdout.splitlines()
                if self.compare_ip(host, server) and dir in line[2]:
                    endpoint = '{}:{}'.format(socket.gethostbyname(host), port)
                    if endpoint in m_endpoint:
                        meta.append(endpoint)
            else:
                logger.warning("FAIL {}:{} {}".format(host, port, stdout))

        for endpoint in meta:
            for master_node in master_nodes:
                if endpoint == master_node['addr']:
                    for slave_node in master_node['slaves']:
                        addr = slave_node['addr']
                        (s_host, s_port) = addr.split(':')
                        sub_cmd = 'cluster failover takeover'
                        command = '{} {} -h {} -p {} {}'.format(
                            ' '.join(env_cmd),
                            redis_cli_cmd,
                            s_host,
                            s_port,
                            sub_cmd,
                        )
                        self._print(
                            message.get('try_failover_takeover').format(
                                slave=addr))
                        stdout = subprocess.check_output(command, shell=True)
                        self._print(stdout)
예제 #6
0
    def get(self, key, all=False, host=None, port=None):
        """Command: redis-cli config get

        :param key: redis config keyword
        :param all: If true, send command to all redis
        :param host: host info for redis
        :param port: port info for redis
        """
        if not isinstance(all, bool):
            msg = m.get('error_option_type_not_boolean')
            msg = msg.format(options='all')
            logger.error(msg)
            return
        if (not host or not port) and not all:
            msg = m.get('use_host_port_or_option_all')
            logger.error(msg)
            return
        sub_cmd = 'config get "{key}" 2>&1'.format(key=key)
        if all:
            meta = []
            ret = RedisCliUtil.command_all_async(sub_cmd)
            for m_s, host, port, result, message in ret:
                addr = '{}:{}'.format(host, port)
                if result == 'OK':
                    if message:
                        _, value = message.split('\n')
                        meta.append([m_s, addr, value])
                    else:
                        meta.append([m_s, addr, color.red('Invalid Key')])
                else:
                    meta.append([m_s, addr, color.red(result)])
            utils.print_table([['TYPE', 'ADDR', 'RESULT']] + meta)
        else:
            output = RedisCliUtil.command(sub_cmd=sub_cmd,
                                          host=host,
                                          port=port,
                                          formatter=self.no_print)
            output = output.strip()
            if output:
                key, value = output.split('\n')
                logger.info(value)
            else:
                msg = m.get('error_invalid_key').format(key=key)
                logger.error(msg)
예제 #7
0
    def slots(self):
        """Command: redis-cli cluster slots"""
        def formatter(outs):
            lines = outs.splitlines()
            replicas = config.get_replicas()
            column_count = 2 + 2 * (replicas + 1)
            row_count = len(lines) / column_count
            header = [['start', 'end', 'm_ip', 'm_port']]
            remain = column_count - 4
            data = []
            for i in range(0, remain / 2):
                header[0].append('s_ip_%d' % i)
                header[0].append('s_port_%d' % i)
            for i in range(0, row_count):
                data.append(lines[i * column_count:column_count * (i + 1)])
            data.sort(key=lambda x: int(x[0]))
            table = AsciiTable(header + data)
            print(table.table)

        RedisCliUtil.command('cluster slots', formatter=formatter)
예제 #8
0
 def rowcount(self):
     """Query and show cluster row count
     """
     logger.debug('rowcount')
     # open-redis-cli-all info Tablespace | grep totalRows | awk -F ',
     # ' '{print $4}' | awk -F '=' '{sum += $2} END {print sum}'
     ret = RedisCliUtil.command_all_async('info Tablespace', slave=False)
     outs = ''
     for _, host, port, res, stdout in ret:
         if res == 'OK':
             outs = '\n'.join([outs, stdout])
         else:
             logger.warning("FAIL {}:{} {}".format(host, port, stdout))
     lines = outs.splitlines()
     key = 'totalRows'
     filtered_lines = (filter(lambda x: key in x, lines))
     ld = RedisCliUtil.to_list_of_dict(filtered_lines)
     # row_count = reduce(lambda x, y: {key: int(x[key]) + int(y[key])}, ld)
     row_count = reduce(lambda x, y: x + int(y[key]), ld, 0)
     self._print(row_count)
예제 #9
0
    def forget_noaddr(self):
        """Forget noaddr nodes that is not used anymore in cluster
        """
        center = Center()
        center.update_ip_port()
        logger.debug('forget_noaddr')
        ret = RedisCliUtil.command_all_async('cluster nodes', slave=True)
        outs = ''
        meta = []
        for _, host, port, res, stdout in ret:
            if res == 'OK':
                outs = '\n'.join([outs, stdout])
                lines = outs.splitlines()
                filtered_lines = (filter(lambda x: 'noaddr' in x, lines))
            else:
                logger.warning("FAIL {}:{} {}".format(host, port, stdout))

        total_list = []
        for line in filtered_lines:
            total_list.append(line.split()[0])

        # Remove duplicates
        unique_list = list(set(total_list))

        # Forget noaddr uuid
        for uuid in unique_list:
            sub_cmd = 'cluster forget "{id}" 2>&1'.format(id=uuid)
            ret = RedisCliUtil.command_all_async(sub_cmd, slave=True)
            count = 0
            for _, host, port, res, stdout in ret:
                if res == 'OK':
                    count += 1
                    pass
                else:
                    logger.warning("FAIL {}:{} {}".format(host, port, stdout))
            msg = '{num} nodes have forgot {id}'.format(num=count, id=uuid)
            self._print(msg)
예제 #10
0
    def distribution(self):
        """Check the distribution of all masters and slaves
        """
        center = Center()
        center.update_ip_port()
        logger.debug('distribution')
        ret = RedisCliUtil.command_all_async('cluster nodes', slave=True)
        outs = ''
        for _, host, port, res, stdout in ret:
            if res == 'OK':
                outs = '\n'.join([outs, stdout])
                lines = outs.splitlines()
                myself_key = 'myself'
                filtered_lines = (filter(lambda x: myself_key in x, lines))
            else:
                logger.warning("FAIL {}:{} {}".format(host, port, stdout))

        meta = []
        total_masters = 0
        total_slaves = 0
        for nd in center.master_host_list:
            num_of_masters = 0
            num_of_slaves = 0
            node = socket.gethostbyname(nd)

            host_lines = (filter(lambda x: (node + ':') in x, filtered_lines))
            for node in host_lines:
                params = node.split()
                endpoint = params[1]
                roles = params[2]
                host = endpoint.split(':')[0]
                role = roles.split(',')[1]
                if role == 'master':
                    if len(params) == 9:
                        num_of_masters += 1
                else:
                    num_of_slaves += 1
            total_masters += num_of_masters
            total_slaves += num_of_slaves
            hostname = str(socket.gethostbyaddr(host)[0]) + str('(') + str(
                host) + str(')')
            meta.append([hostname, num_of_masters, num_of_slaves])

        meta.append(['TOTAL', total_masters, total_slaves])
        utils.print_table([['HOST', 'MASTER', 'SLAVE']] + meta)
예제 #11
0
    def nodes_with_dir(self, server, dir):
        """Find nodes that use the specified directory path

        :param server: IP or hostname
        :param dir: directory path
        """
        center = Center()
        center.update_ip_port()
        logger.debug('nodes_with_dir')
        ret = RedisCliUtil.command_all_async('config get dir', slave=True)
        outs = ''
        meta = []
        for _, host, port, res, stdout in ret:
            if res == 'OK':
                flat_stdout = '\n'.join([outs, stdout])
                line = flat_stdout.splitlines()
                if self.compare_ip(host, server) and dir in line[2]:
                    meta.append([host, port, line[2]])
            else:
                logger.warning("FAIL {}:{} {}".format(host, port, stdout))
        utils.print_table([['HOST', 'PORT', 'PATH']] + meta)
예제 #12
0
 def nodes(self):
     """Command: redis-cli cluster nodes"""
     RedisCliUtil.command('cluster nodes')
예제 #13
0
 def info(self):
     """Command: redis-cli cluster info"""
     RedisCliUtil.command('cluster info')
예제 #14
0
 def alert(self, host=None, port=None):
     """Command: redis-cli info alert"""
     RedisCliUtil.command('info alert', host=host, port=port)
예제 #15
0
 def replication(self, host=None, port=None):
     """Command: redis-cli info replication"""
     RedisCliUtil.command('info replication', host=host, port=port)
예제 #16
0
 def tablespace(self, host=None, port=None):
     """Command: redis-cli info tablespace"""
     RedisCliUtil.command(sub_cmd='info tablespace', host=host, port=port)
예제 #17
0
 def eviction(self, host=None, port=None):
     """Command: redis-cli info eviction"""
     RedisCliUtil.command(sub_cmd='info eviction', host=host, port=port)
예제 #18
0
 def memory(self, host=None, port=None):
     """Command: redis-cli info memory"""
     RedisCliUtil.command(sub_cmd='info memory', host=host, port=port)
예제 #19
0
 def all(self, host=None, port=None):
     """Command: redis-cli info all"""
     RedisCliUtil.command(sub_cmd='info', host=host, port=port)
예제 #20
0
    def failover_list(self):
        """ Find failovered|no-slave|no-slot masters and failbacked slaves
        """
        center = Center()
        center.update_ip_port()
        logger.debug('failover_list')
        master_nodes = center.get_master_obj_list()
        slave_nodes = center.get_slave_nodes()
        master_ports = center.master_port_list
        slave_ports = center.slave_port_list
        output_msg = []

        failovered_masters = []
        for master_node in master_nodes:
            addr = master_node['addr']
            port = addr.split(':')[1]
            try:
                value = int(port)
                if value in slave_ports:
                    failovered_masters.append(addr)
            except ValueError:
                pass

        noslave_masters = []
        for master_node in master_nodes:
            if len(master_node['slaves']) == 0:
                noslave_masters.append(master_node['addr'])
            else:
                for slave_node in master_node['slaves']:
                    if slave_node['status'] == 'disconnected':
                        noslave_masters.append(master_node['addr'])
                        break

        noslot_masters = []
        ret = RedisCliUtil.command_all_async('cluster nodes', slave=True)
        outs = ''
        for _, host, port, res, stdout in ret:
            if res == 'OK':
                outs = '\n'.join([outs, stdout])
                lines = outs.splitlines()
                filtered_nodes = (filter(lambda x: 'myself,master' in x,
                                         lines))
            else:
                logger.warning("FAIL {}:{} {}".format(host, port, stdout))
        for line in filtered_nodes:
            words = line.split()
            if len(words) == 8:
                noslot_masters.append(line.split()[1])

        failbacked_slaves = []
        for slave_nodes in slave_nodes:
            port = slave_nodes.split(':')[1]
            try:
                value = int(port)
                if value in master_ports:
                    failbacked_slaves.append(slave_nodes)
            except ValueError:
                pass

        output_msg.append('1) failovered masters:')
        output_msg.extend(failovered_masters)
        output_msg.append('')
        output_msg.append('2) no-slave masters:')
        output_msg.extend(noslave_masters)
        output_msg.append('')
        output_msg.append('3) no-slot masters:')
        output_msg.extend(noslot_masters)
        output_msg.append('')
        output_msg.append('4) failbacked slaves:')
        output_msg.extend(failbacked_slaves)
        output_msg.append('')

        logger.info(color.ENDC + '\n'.join(output_msg))