openGauss数据库源码解析系列文章—— AI技术之“指标采集、预测与异常检测”_opengauss transformoperatorplus解析(1)

一、Python所有方向的学习路线

Python所有方向路线就是把Python常用的技术点做整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。

二、学习软件

工欲善其事必先利其器。学习Python常用的开发软件都在这里了,给大家节省了很多时间。

三、入门学习视频

我们在看视频学习的时候,不能光动眼动脑不动手,比较科学的学习方法是在理解之后运用它们,这时候练手项目就很适合了。

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

(1) 收集Agent端采集的数据并进行转储。
(2) 对收集到的数据进行特征分析与异常检测。
(3) 将检测出来的异常信息推送给运维管理人员。

1. Agent模块的组成

Agent模块负责采集并发送指标数据,该模块由DBSource、MemoryChannel、HttpSink三个子模块组成。
(1) DBSource作为数据源,负责定期去收集数据库指标数据并将数据发送到数据通道MemoryChannel中。
(2) MemoryChannel是内存数据通道,本质是一个FIFO队列,用于数据缓存。HttpSink组件消费MemoryChannel中的数据,为了防止MemoryChannel中的数据过多导致OOM(out of Memory,内存溢出),设置了容量上限,当超过容量上限时,过多的元素会被禁止放入队列中。
(3) HttpSink是数据汇聚点,该模块定期从MemoryChannel中获取数据,并以Http(s)的方式将数据进行转发,数据读取之后从MemoryChannel中清除。

2. Detector 模块组成

Detector模块负责数据检测,该模块由Server、Monitor两个子模块组成。
(1) Server是一个Web服务,为Agent采集到的数据提供接收接口,并将数据存储到本地数据库内部,为了避免数据增多导致数据库占用太多的资源,我们将数据库中的每个表都设置了行数上限。
(2) Monitor模块包含时序预测和异常检测等算法,该模块定期从本地数据库中获取数据库指标数据,并基于现有算法对数据进行预测与分析,如果算法检测出数据库指标在历史或未来某时间段或时刻出现异常,则会及时的将信息推送给用户。

8.5.3 关键源码解析

1 总体流程解析

智能索引推荐工具的路径是openGauss-server/src/gausskernel/dbmind/tools/anomaly_detection,下面的代码详细展示了程序的入口。

def forecast(args):
    …
    # 如果没有指定预测方式,则默认使用’auto_arima’算法
    if not args.forecast_method:
        forecast_alg = get_instance('auto_arima')
    else:
        forecast_alg = get_instance(args.forecast_method)
    # 指标预测功能函数
    def forecast_metric(name, train_ts, save_path=None):
        …
            forecast_alg.fit(timeseries=train_ts)
            dates, values = forecast_alg.forecast(
                period=TimeString(args.forecast_periods).standard)
        date_range = "{start_date}~{end_date}".format(start_date=dates[0],
                                               end_date=dates[-1])
        display_table.add_row(
            [name, date_range, min(values), max(values), sum(values) / len(values)]
        )
# 校验存储路径
        if save_path:
            if not os.path.exists(os.path.dirname(save_path)):
                os.makedirs(os.path.dirname(save_path))
            with open(save_path, mode='w') as f:
                for date, value in zip(dates, values):
                    f.write(date + ',' + str(value) + '\n')
    # 从本地sqlite中抽取需要的数据
    with sqlite_storage.SQLiteStorage(database_path) as db:
        if args.metric_name:
            timeseries = db.get_timeseries(table=args.metric_name, period=max_rows)
            forecast_metric(args.metric_name, timeseries, args.save_path)
        else:
# 获取sqlite中所有的表名
            tables = db.get_all_tables()
            # 从每个表中抽取训练数据进行预测
for table in tables:
                timeseries = db.get_timeseries(table=table, period=max_rows)
                forecast_metric(table, timeseries)
# 输出结果
    print(display_table.get_string())

# 代码远程部署
def deploy(args):
    print('Please input the password of {user}@{host}: '.format(user=args.user, host=args.host))
# 格式化代码远程部署指令
    command = 'sh start.sh --deploy {host} {user} {project_path}' \
        .format(user=args.user,
                host=args.host,
                project_path=args.project_path)
    # 判断指令执行情况
if subprocess.call(shlex.split(command), cwd=SBIN_PATH) == 0:
        print("\nExecute successfully.")
    else:
        print("\nExecute unsuccessfully.")
… 
# 展示当前监控的参数
def show_metrics():
…

# 项目总入口
def main():
   …


2. 关键代码段解析

(1) 后台线程的实现。
前面已经介绍过了,本功能可以分为三个角色:Agent、Monitor以及Detector,这三个不同的角色都是常驻后台的进程,各自执行着不同的任务。Daemon类就是负责运行不同业务流程的容器类,下面介绍该类的实现。

class Daemon:
    """
    This class implements the function of running a process in the background."""
    
    def __init__(self):
        …
def daemon_process(self):
        # 注册退出函数
        atexit.register(lambda: os.remove(self.pid_file))
        signal.signal(signal.SIGTERM, handle_sigterm)
# 启动进程
    @staticmethod
    def start(self):
        try:
            self.daemon_process()
        except RuntimeError as msg:
            abnormal_exit(msg)

        self.function(*self.args, **self.kwargs)
    # 停止进程
    def stop(self):
        if not os.path.exists(self.pid_file):
            abnormal_exit("Process not running.")

        read_pid = read_pid_file(self.pid_file)
        if read_pid > 0:
            os.kill(read_pid, signal.SIGTERM)
        if read_pid_file(self.pid_file) < 0:
            os.remove(self.pid_file)


(2) 数据库相关指标采集过程。
数据库的指标采集架构,参考了Apache Flume的设计。将一个完整的信息采集流程拆分为三个部分,分别是Source、Channel以及Sink。上述三个部分被抽象为三个不同的基类,由此可以派生出不同的采集数据源、缓存管道以及数据的接收端。
前文提到过的DBSource即派生自Source、MemoryChannel派生自Channel,HttpSink则派生自Sink。下面这段代码来自metric_agent.py,负责采集指标,在这里将上述模块串联起来了。

def agent_main():
…
    # 初始化通道管理器
cm = ChannelManager()
# 初始化数据源
    source = DBSource()
    http_sink = HttpSink(interval=params['sink_timer_interval'], url=url, context=context)
    source.channel_manager = cm
    http_sink.channel_manager = cm
    # 获取参数文件里面的功能函数
    for task_name, task_func in get_funcs(metric_task):
        source.add_task(name=task_name,
                        interval=params['source_timer_interval'],
                        task=task_func,
                        maxsize=params['channel_capacity'])
    source.start()
    http_sink.start()


(3) 数据存储与监控部分的实现。
Agent将采集到的指标数据发送到Detector服务器上,并由Detector服务器负责存储。Monitor不断对存储的数据进行检查,以便提前发现异常。
这里实现了一种通过SQLite进行本地化存储的方式,代码位于sqlite_storage.py文件中,实现的类为SQLiteStorage,该类实现的主要方法如下:

# 通过时间戳获取最近一段时间的数据
def select_timeseries_by_timestamp(self, table, period):
…
# 通过编号获取最近一段时间的数据
def select_timeseries_by_number(self, table, number):
     …


其中,由于不同指标数据是分表存储的,因此上述参数table也代表了不同指标的名称。
异常检测当前主要支持基于时序预测的方法,包括Prophet算法(由Facebook开源的工业级时序预测算法工具)和ARIMA算法,他们分别被封装成类,供Forecaster调用。
上述时序检测的算法类都继承了AlgModel类,该类的结构如下:

class AlgModel(object):
    """
    This is the base class for forecasting algorithms.
    If we want to use our own forecast algorithm, we should follow some rules.
    """

    def __init__(self):
        pass

    @abstractmethod
    def fit(self, timeseries):
        pass

    @abstractmethod
    def forecast(self, period):
        pass

    def save(self, model_path):
        pass

    def load(self, model_path):
        pass


在Forecast类中,通过调用fit()方法,即可根据历史时序数据进行训练,通过forecast()方法预测未来走势。
获取到未来走势后如何判断是否是异常呢?方法比较多,最简单也是最基础的方法是通过阈值来进行判断,在我们的程序中,默认也是采用该方法进行判断的。

8.5.4 使用示例

Anomaly-Detection工具有start、stop、forecast、show_metrics、deploy五种运行模式,各模式说明如表8-12所示。

表8-12 Anomaly-Detection使用模式及说明

模式名称说明
start启动本地或者远程服务
stop停止本地或远程服务
forecast预测指标未来变化
show_metrics输出当前监控的参数
deploy远程部署代码

Anomaly-Detection工具运行模式使用示例如下所示。
① 使用start模式启动本地collector服务,代码如下:

python main.py start –role collector


### 最后

> **🍅 硬核资料**:关注即可领取PPT模板、简历模板、行业经典书籍PDF。  
> **🍅 技术互助**:技术群大佬指点迷津,你的问题可能不是问题,求资源在群里喊一声。  
> **🍅 面试题库**:由技术群里的小伙伴们共同投稿,热乎的大厂面试真题,持续更新中。  
> **🍅 知识体系**:含编程语言、算法、大数据生态圈组件(Mysql、Hive、Spark、Flink)、数据仓库、Python、前端等等。




**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化学习资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618317507)**

**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值