当前位置 博文首页 > 东山絮柳仔:数据库服务器资源使用情况周报

    东山絮柳仔:数据库服务器资源使用情况周报

    作者:东山絮柳仔 时间:2021-07-03 18:28

    一.项目说明

    1.1 项目目的

    1.盘活服务器资源,提高资源的使用率;资源是公司的资产,只有尽可能发挥其价值,才能创造更多的价值。所以,有必要知道,公司整体(或某业务、产品)所属的 DB Server的资源使用情况。主要从CPU、内存、Disk的平均数和中位数来反映。实现更合理的资源分配和集中性的管理,节省资源成本。

    2.慢查询的次数,既可以说明程序的性能和Server的压力,说明了待确认和优化的情况,也说明了资源的紧张性。

    3.此类历史数据的积累,可以生成一个变化趋势图,说明资源使用趋势。

    4.之前的监控大部分诊断具体的一个DB Server或应用,这个是针对公司整体(或某业务、产品)所属的 DB Server;是监控体系的一个完善和补充。

     即:资源盘活、充分利用、降本增效、监控补充。

     1.2 部署环境及架构

    现有的监控数据已收集到InfluxDB 和 elasticsearch 中,本次要实现的功能是将数据计算聚合到MySQL中,然后通过邮件发送给相关人员。存储到MySQL 数据库中,一是因为 此类数据有一定的价值(具有追溯性和便于历史趋势分析),二是 InfluxDB  、elasticsearch 数据都有过期时间,数据保留的天数不是太长。

    二.表的创建

    2.1 存储DB资源使用情况的表

    表名定义为weekly_dbperformance,具体的脚本如下:

    CREATE TABLE `weekly_dbperformance` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `cpu_mean` varchar(255) NOT NULL DEFAULT '',
      `cpu_median` varchar(255) NOT NULL DEFAULT '',
      `mem_mean` varchar(255) NOT NULL DEFAULT '',
      `mem_median` varchar(255) NOT NULL DEFAULT '',
      `disk_mean` varchar(255) NOT NULL DEFAULT '',
      `disk_median` varchar(255) NOT NULL DEFAULT '',
      `datetime_created` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '数据行创建时间',
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=3740 DEFAULT CHARSET=utf8mb4;

    在记录数据生成的时间字段添加个索引

    create index idx_datetime on weekly_dbperformance (datetime_created);

    2.2  存储DB 实例慢查询情况的表

    表名定义为weekly_dbslowqty,具体的脚本如下:

    CREATE TABLE `weekly_dbslowqty` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `qindex_name` varchar(50) NOT NULL DEFAULT '',
      `qstartdate` varchar(50) NOT NULL DEFAULT '',
      `qenddate` varchar(50) NOT NULL DEFAULT '',
      `slowqty` varchar(20) NOT NULL DEFAULT '',
      `datetime_created` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '数据行创建时间',
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=3740 DEFAULT CHARSET=utf8mb4;

    在记录查询的开始时间的字段上添加个索引

    create index idx_qstartdate on weekly_dbslowqty (qstartdate);

    三.主要功能代码

    3.1 统计DB Server资源使用率

    可执行文件为collect_dbperformance.py

    从InfluxDB中查询DB Server的资源使用情况。包括CPU的平均数、CPU的中位数、内存使用的平均数、内存使用的中位数、磁盘平均使用率、磁盘使用的中位数。

    拉取计算的是过去7天的数据。

    #!/usr/bin/python
    # -*- coding: UTF-8 -*-
    
    
    
    from influxdb import InfluxDBClient
    
    import pytz
    import time
    import dateutil.parser
    import datetime
    
    import db_monitor_conn
    mysqldb = db_monitor_conn.db
    # use cursor
    cursor = mysqldb.cursor()
    
    class DBApi(object):
        """
        通过infludb获取数据
        """
    
        def __init__(self, ip, port):
            """
            初始化数据
            :param ip:influxdb地址
            :param port: 端口
            """
            self.db_name = 'telegraf'
            self.use_cpu_table = 'cpu' # cpu使用率表
            self.phy_mem_table = 'mem'# 物理内存表
            self.disk_table = 'disk'# 磁盘表
            self.client = InfluxDBClient(ip, port, '用*户*名', '密*码', self.db_name)  # 连接influxdb数据库
            print ('test link influxdb')
    
    
        def get_use_dbperformance(self, s_time, e_time):
            """
            获取磁盘io使用率
            :param host: 查询的主机host (telegraf 配置参数中的host栏位)
            :param s_time: 开始时间
            :param e_time: 结束时间
            :return:
            """
    
            response = {}
            ### 时间还需转换,否则报错 TypeError: Tuple or struct_time argument required
    
            #s = time.strptime(s_time, '%Y-%m-%d %H:%M:%S')
            #e = time.strptime(e_time, '%Y-%m-%d %H:%M:%S')
            s = time.strptime(s_time, '%Y-%m-%d')
            e = time.strptime(e_time, '%Y-%m-%d')
            start_time = int(time.mktime(s)) * 1000 * 1000 * 1000
            end_time = int(time.mktime(e)) * 1000 * 1000 * 1000
    
            #start_time = s_time
            #end_time = e_time
            cpu_mean_list = cpu_median_list = mem_mean_list = mem_median_list = disk_mean_list = disk_median_list = ['0.0']
            ##print('开始查询CPU使用率的平均数')
            cpu_mean_list = self.client.query(
                "select mean(usage_user) from cpu where  time>=%s and time<=%s and cpu = 'cpu-total' AND host != 'qqlog_XXX_XXX' ;" % (
                    start_time, end_time))
            ##print(cpu_mean_list)
            ### cpu_mean_list的格式 ResultSet({'('cpu', None)': [{'time': '2018-06-21T16:00:00Z', 'mean': 1.7141865567279297}]})
            cpu_mean_points = list(cpu_mean_list.get_points(measurement='cpu'))
            ##print(cpu_mean_points)
            ### cpu_mean_points的格式[{'time': '2018-06-21T16:00:00Z', 'mean': 1.7141865567279297}]
            cpu_mean = cpu_mean_points[0]['mean']
            ##print(cpu_mean)
            ### cpu_mean 的格式1.7141865567279297
            ##print('查询CPU使用率的平均数结束')
            ##print('开始查询CPU使用率的中位数')
            cpu_median_list = self.client.query(
                "SELECT median(usage_user) from cpu  where time>=%s and time<=%s and cpu = 'cpu-total' AND host != 'qqlog_XXX_XXX';" % (
                    start_time, end_time))
            ##print(cpu_median_list)
            #### cpu_median_list的格式为ResultSet({'('cpu', None)': [{'time': '2018-06-21T16:00:00Z', 'median': 0.726817042581142}]})
            cpu_median_points = list(cpu_median_list.get_points(measurement='cpu'))
            cpu_median = cpu_median_points[0]['median']
            ##print(cpu_median)
            ##print('开始查询mem使用率的平均数')
            mem_mean_list = self.client.query(
                "SELECT  mean(used) /mean(total) from mem  where time>=%s and time<=%s and host != 'qqlog_XXX_XXX';" % (
                    start_time, end_time))
            print(mem_mean_list)
            ### mem_mean_list的格式为ResultSet({'('mem', None)': [{'time': '2018-06-21T16:00:00Z', 'mean_mean': 0.729324184536873}]})
            mem_mean_points = list(mem_mean_list.get_points(measurement='mem'))
            mem_mean = mem_mean_points[0]['mean_mean']
            ##print(mem_mean)
            ##print('开始查询mem使用率的中位数')
            mem_median_list = self.client.query(
                "SELECT  median(used) /median(total) from mem  where time>=%s and time<=%s AND host != 'qqlog_XXX_XXX' ;" % (
                    start_time, end_time))
            ##print(mem_median_list)
            ###mem_median_list的格式为ResultSet({'('mem', None)': [{'time': '2018-06-21T16:00:00Z', 'median_median': 0.8698493636354012}]})
            mem_median_points = list(mem_median_list.get_points(measurement='mem'))
            mem_median = mem_median_points[0]['median_median']
            ##print('开始查询disk使用率的平均数')
            disk_mean_list = self.client.query(
                "SELECT mean(used) /mean(total) from disk  where time>=%s and time<=%s  AND host != 'qqlog_XXX_XXX';" % (
                    start_time, end_time))
            ##print (disk_mean_list)
            ###disk_mean_list的格式为esultSet({'('
    
    下一篇:没有了