DolphinDB异常检测引擎:实时告警

目录

    • 摘要
    • 一、异常检测引擎概述
      • [1.1 什么是异常检测引擎](#1.1 什么是异常检测引擎)
      • [1.2 异常检测引擎特点](#1.2 异常检测引擎特点)
      • [1.3 适用场景](#1.3 适用场景)
    • 二、创建异常检测引擎
      • [2.1 基本语法](#2.1 基本语法)
      • [2.2 创建简单引擎](#2.2 创建简单引擎)
      • [2.3 输出格式](#2.3 输出格式)
    • 三、异常检测规则
      • [3.1 阈值规则](#3.1 阈值规则)
      • [3.2 统计规则](#3.2 统计规则)
      • [3.3 组合规则](#3.3 组合规则)
      • [3.4 复杂规则](#3.4 复杂规则)
    • 四、窗口模式
      • [4.1 无窗口模式](#4.1 无窗口模式)
      • [4.2 有窗口模式](#4.2 有窗口模式)
    • 五、实战案例
      • [5.1 设备温度告警系统](#5.1 设备温度告警系统)
      • [5.2 多指标组合告警](#5.2 多指标组合告警)
      • [5.3 统计异常检测](#5.3 统计异常检测)
    • 六、引擎管理
      • [6.1 查看引擎状态](#6.1 查看引擎状态)
      • [6.2 删除引擎](#6.2 删除引擎)
      • [6.3 引擎监控](#6.3 引擎监控)
    • 七、告警通知
      • [7.1 告警推送](#7.1 告警推送)
      • [7.2 告警聚合](#7.2 告警聚合)
    • 八、总结
    • 参考资料

摘要

本文深入讲解DolphinDB异常检测引擎。从引擎原理到创建配置,从规则定义到告警输出,从多规则组合到实战应用,全面介绍异常检测引擎的核心功能。通过丰富的代码示例,帮助读者掌握实时告警系统的核心技能。


一、异常检测引擎概述

1.1 什么是异常检测引擎

异常检测引擎是DolphinDB内置的流计算引擎,用于实时检测数据异常:
#mermaid-svg-srni6ik8IHDAoIoE{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-srni6ik8IHDAoIoE .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-srni6ik8IHDAoIoE .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-srni6ik8IHDAoIoE .error-icon{fill:#552222;}#mermaid-svg-srni6ik8IHDAoIoE .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-srni6ik8IHDAoIoE .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-srni6ik8IHDAoIoE .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-srni6ik8IHDAoIoE .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-srni6ik8IHDAoIoE .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-srni6ik8IHDAoIoE .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-srni6ik8IHDAoIoE .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-srni6ik8IHDAoIoE .marker{fill:#333333;stroke:#333333;}#mermaid-svg-srni6ik8IHDAoIoE .marker.cross{stroke:#333333;}#mermaid-svg-srni6ik8IHDAoIoE svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-srni6ik8IHDAoIoE p{margin:0;}#mermaid-svg-srni6ik8IHDAoIoE .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-srni6ik8IHDAoIoE .cluster-label text{fill:#333;}#mermaid-svg-srni6ik8IHDAoIoE .cluster-label span{color:#333;}#mermaid-svg-srni6ik8IHDAoIoE .cluster-label span p{background-color:transparent;}#mermaid-svg-srni6ik8IHDAoIoE .label text,#mermaid-svg-srni6ik8IHDAoIoE span{fill:#333;color:#333;}#mermaid-svg-srni6ik8IHDAoIoE .node rect,#mermaid-svg-srni6ik8IHDAoIoE .node circle,#mermaid-svg-srni6ik8IHDAoIoE .node ellipse,#mermaid-svg-srni6ik8IHDAoIoE .node polygon,#mermaid-svg-srni6ik8IHDAoIoE .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-srni6ik8IHDAoIoE .rough-node .label text,#mermaid-svg-srni6ik8IHDAoIoE .node .label text,#mermaid-svg-srni6ik8IHDAoIoE .image-shape .label,#mermaid-svg-srni6ik8IHDAoIoE .icon-shape .label{text-anchor:middle;}#mermaid-svg-srni6ik8IHDAoIoE .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-srni6ik8IHDAoIoE .rough-node .label,#mermaid-svg-srni6ik8IHDAoIoE .node .label,#mermaid-svg-srni6ik8IHDAoIoE .image-shape .label,#mermaid-svg-srni6ik8IHDAoIoE .icon-shape .label{text-align:center;}#mermaid-svg-srni6ik8IHDAoIoE .node.clickable{cursor:pointer;}#mermaid-svg-srni6ik8IHDAoIoE .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-srni6ik8IHDAoIoE .arrowheadPath{fill:#333333;}#mermaid-svg-srni6ik8IHDAoIoE .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-srni6ik8IHDAoIoE .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-srni6ik8IHDAoIoE .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-srni6ik8IHDAoIoE .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-srni6ik8IHDAoIoE .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-srni6ik8IHDAoIoE .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-srni6ik8IHDAoIoE .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-srni6ik8IHDAoIoE .cluster text{fill:#333;}#mermaid-svg-srni6ik8IHDAoIoE .cluster span{color:#333;}#mermaid-svg-srni6ik8IHDAoIoE div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-srni6ik8IHDAoIoE .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-srni6ik8IHDAoIoE rect.text{fill:none;stroke-width:0;}#mermaid-svg-srni6ik8IHDAoIoE .icon-shape,#mermaid-svg-srni6ik8IHDAoIoE .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-srni6ik8IHDAoIoE .icon-shape p,#mermaid-svg-srni6ik8IHDAoIoE .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-srni6ik8IHDAoIoE .icon-shape .label rect,#mermaid-svg-srni6ik8IHDAoIoE .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-srni6ik8IHDAoIoE .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-srni6ik8IHDAoIoE .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-srni6ik8IHDAoIoE :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 异常检测引擎
匹配
不匹配
数据流
异常规则
规则匹配
输出告警
正常数据
规则类型
阈值规则
统计规则
组合规则

1.2 异常检测引擎特点

特点 说明
实时检测 毫秒级延迟
多规则 支持多规则组合
灵活配置 Lambda表达式定义规则
自动输出 异常数据自动输出

1.3 适用场景

场景 说明
设备告警 设备参数异常告警
阈值监控 实时阈值监控
趋势异常 数据趋势异常检测
组合告警 多条件组合告警

二、创建异常检测引擎

2.1 基本语法

python 复制代码
// 创建异常检测引擎
agg = createAnomalyDetectionEngine(
    "engine_name",     // 引擎名称
    metrics,           // 异常检测规则(Lambda表达式列表)
    outputTable,       // 输出表
    timeColumn,        // 时间列
    [keyColumn],       // 分组列(可选)
    [windowSize],      // 窗口大小
    [garbageSize]      // 垃圾回收阈值
)

2.2 创建简单引擎

python 复制代码
// 创建输入流表
share streamTable(1:0, 
    `device_id`timestamp`temperature,
    [INT, TIMESTAMP, DOUBLE]) as input_stream

// 创建输出表
share table(1:0,
    `device_id`timestamp`temperature`anomaly_type,
    [INT, TIMESTAMP, DOUBLE, SYMBOL]) as output_table

// 创建异常检测引擎
agg = createAnomalyDetectionEngine("anomaly_engine",
    <[temperature > 30,    // 规则1:温度>30
      temperature < 10]>,  // 规则2:温度<10
    output_table, `timestamp, `device_id)

// 订阅流表
subscribeTable(, "input_stream", "anomaly_detect", -1, agg, true)

2.3 输出格式

python 复制代码
// 异常检测输出格式
// - device_id: 分组列
// - timestamp: 时间列
// - temperature: 检测列
// - anomaly_type: 异常类型(规则索引)

// 例如:
// device_id | timestamp | temperature | anomaly_type
// 1         | 10:00:00  | 35.0        | 0  (规则0匹配:温度>30)
// 2         | 10:00:01  | 5.0         | 1  (规则1匹配:温度<10)

三、异常检测规则

3.1 阈值规则

python 复制代码
// 阈值规则:简单的阈值判断
agg = createAnomalyDetectionEngine("threshold_engine",
    <[temperature > 30,     // 高温告警
      temperature < 10,     // 低温告警
      humidity > 80,        // 高湿度告警
      humidity < 20]>,      // 低湿度告警
    output_table, `timestamp, `device_id)

3.2 统计规则

python 复制代码
// 统计规则:基于统计指标
// 需要配合窗口使用

agg = createAnomalyDetectionEngine("stats_engine",
    <[temperature > avg(temperature) + 3 * std(temperature),  // 超过3倍标准差
      temperature < avg(temperature) - 3 * std(temperature)]>, // 低于3倍标准差
    output_table, `timestamp, `device_id,
    60000)  // 窗口大小60秒

3.3 组合规则

python 复制代码
// 组合规则:多条件组合
agg = createAnomalyDetectionEngine("combo_engine",
    <[temperature > 30 and humidity > 70,  // 高温高湿
      temperature < 10 and humidity < 30,  // 低温低湿
      temperature > 35 or humidity > 90]>, // 高温或高湿
    output_table, `timestamp, `device_id)

3.4 复杂规则

python 复制代码
// 复杂规则:使用函数
agg = createAnomalyDetectionEngine("complex_engine",
    <[abs(temperature - prev(temperature)) > 5,  // 温度突变>5度
      temperature > 30 and temperature > prev(temperature) * 1.2]>, // 温度突增20%
    output_table, `timestamp, `device_id)

四、窗口模式

4.1 无窗口模式

python 复制代码
// 无窗口:每条数据独立判断
agg = createAnomalyDetectionEngine("no_window_engine",
    <[temperature > 30]>,
    output_table, `timestamp, `device_id)

// 适用场景:
// - 简单阈值判断
// - 不需要历史数据

4.2 有窗口模式

python 复制代码
// 有窗口:基于窗口内数据判断
agg = createAnomalyDetectionEngine("window_engine",
    <[temperature > avg(temperature) + 3 * std(temperature)]>,
    output_table, `timestamp, `device_id,
    60000)  // 60秒窗口

// 适用场景:
// - 统计规则
// - 需要历史数据

五、实战案例

5.1 设备温度告警系统

python 复制代码
// ========== 1. 创建流表 ==========
share streamTable(100000:0, 
    `device_id`timestamp`temperature`humidity`pressure,
    [INT, TIMESTAMP, DOUBLE, DOUBLE, DOUBLE]) as sensor_stream

// ========== 2. 创建告警输出表 ==========
share table(1:0,
    `device_id`timestamp`value`anomaly_type`alert_level,
    [INT, TIMESTAMP, DOUBLE, SYMBOL, INT]) as alert_table

// ========== 3. 创建异常检测引擎 ==========
agg = createAnomalyDetectionEngine("temp_alert_engine",
    <[temperature > 35,     // 规则0:严重高温
      temperature > 30,     // 规则1:一般高温
      temperature < 5,      // 规则2:严重低温
      temperature < 10]>,   // 规则3:一般低温
    alert_table, `timestamp, `device_id)

// ========== 4. 订阅流表 ==========
subscribeTable(, "sensor_stream", "temp_alert", -1, agg, true)

// ========== 5. 添加告警级别 ==========
share table(1:0,
    `device_id`timestamp`value`anomaly_type`alert_level,
    [INT, TIMESTAMP, DOUBLE, SYMBOL, INT]) as final_alert_table

subscribeTable(, "alert_table", "level_handler", -1,
    def(msg) {
        result = select device_id, timestamp, value, anomaly_type,
                        case when anomaly_type in ["0", "2"] then 2  // 严重
                             else 1 end as alert_level
                 from msg
        final_alert_table.append!(result)
    }, true)

// ========== 6. 模拟数据 ==========
def simulateAlert() {
    for (i in 1..100) {
        sensor_stream.append!(
            table(
                take(1..10, 100) as device_id,
                take(now(), 100) as timestamp,
                rand(0.0..40.0, 100) as temperature,  // 包含异常温度
                rand(40.0..60.0, 100) as humidity,
                rand(1000.0..1020.0, 100) as pressure
            )
        )
        sleep(100)
    }
}

simulateAlert()

// 查看告警
select * from final_alert_table order by timestamp desc limit 20

5.2 多指标组合告警

python 复制代码
// ========== 1. 创建流表 ==========
share streamTable(100000:0, 
    `device_id`timestamp`temperature`humidity`vibration,
    [INT, TIMESTAMP, DOUBLE, DOUBLE, DOUBLE]) as sensor_stream

// ========== 2. 创建告警输出表 ==========
share table(1:0,
    `device_id`timestamp`anomaly_type`description,
    [INT, TIMESTAMP, SYMBOL, STRING]) as combo_alert_table

// ========== 3. 创建组合告警引擎 ==========
agg = createAnomalyDetectionEngine("combo_alert_engine",
    <[temperature > 30 and humidity > 70,   // 高温高湿
      temperature > 30 and vibration > 5,    // 高温高振动
      humidity > 80 and vibration > 3,       // 高湿高振动
      temperature > 35 or vibration > 10]>,  // 严重异常
    combo_alert_table, `timestamp, `device_id)

// ========== 4. 订阅流表 ==========
subscribeTable(, "sensor_stream", "combo_alert", -1, agg, true)

5.3 统计异常检测

python 复制代码
// ========== 1. 创建流表 ==========
share streamTable(100000:0, 
    `device_id`timestamp`temperature,
    [INT, TIMESTAMP, DOUBLE]) as sensor_stream

// ========== 2. 创建告警输出表 ==========
share table(1:0,
    `device_id`timestamp`temperature`avg_temp`std_temp`anomaly_type,
    [INT, TIMESTAMP, DOUBLE, DOUBLE, DOUBLE, SYMBOL]) as stats_alert_table

// ========== 3. 创建统计异常引擎 ==========
agg = createAnomalyDetectionEngine("stats_alert_engine",
    <[temperature > avg(temperature) + 3 * std(temperature),
      temperature < avg(temperature) - 3 * std(temperature)]>,
    stats_alert_table, `timestamp, `device_id,
    300000)  // 5分钟窗口

// ========== 4. 订阅流表 ==========
subscribeTable(, "sensor_stream", "stats_alert", -1, agg, true)

六、引擎管理

6.1 查看引擎状态

python 复制代码
// 查看所有引擎状态
getStreamEngineStat()

// 查看特定引擎
getStreamEngineStat("anomaly_engine")

6.2 删除引擎

python 复制代码
// 删除引擎
dropStreamEngine("anomaly_engine")

6.3 引擎监控

python 复制代码
// 引擎监控函数
def monitorAnomalyEngine() {
    stat = getStreamEngineStat()
    
    for (row in stat) {
        if (row.type == "AnomalyDetectionEngine") {
            print("异常检测引擎: " + row.name)
            print("  状态: " + row.status)
            print("  规则数: " + string(row.numMetrics))
            print("  处理行数: " + string(row.processedRows))
            print("  告警数: " + string(row.outputRows))
        }
    }
}

monitorAnomalyEngine()

七、告警通知

7.1 告警推送

python 复制代码
// 告警推送函数
def pushAlert(alert) {
    // 发送邮件
    // sendEmail(alert)
    
    // 发送短信
    // sendSMS(alert)
    
    // 发送微信
    // sendWeChat(alert)
    
    print("告警推送: " + alert.device_id + " - " + alert.anomaly_type)
}

// 订阅告警表
subscribeTable(, "alert_table", "push_handler", -1,
    def(msg) {
        for (row in msg) {
            pushAlert(row)
        }
    }, true)

7.2 告警聚合

python 复制代码
// 告警聚合:避免告警风暴
share table(1:0,
    `device_id`anomaly_type`first_time`last_time`count,
    [INT, SYMBOL, TIMESTAMP, TIMESTAMP, LONG]) as aggregated_alerts

// 聚合逻辑
def aggregateAlerts(msg) {
    for (row in msg) {
        existing = select * from aggregated_alerts
                   where device_id = row.device_id
                   and anomaly_type = row.anomaly_type
                   and last_time > now() - 60000  // 1分钟内
        
        if (existing.rows() > 0) {
            update aggregated_alerts
            set last_time = row.timestamp, count = count + 1
            where device_id = row.device_id
            and anomaly_type = row.anomaly_type
            and last_time > now() - 60000
        } else {
            insert into aggregated_alerts
            values (row.device_id, row.anomaly_type, row.timestamp, row.timestamp, 1)
        }
    }
}

subscribeTable(, "alert_table", "aggregate_handler", -1, aggregateAlerts, true)

八、总结

本文详细介绍了DolphinDB异常检测引擎:

  1. 引擎原理:实时异常检测
  2. 创建方法:简单引擎、分组引擎
  3. 检测规则:阈值规则、统计规则、组合规则
  4. 窗口模式:无窗口、有窗口
  5. 实战应用:温度告警、组合告警、统计异常
  6. 告警通知:告警推送、告警聚合

思考题

  1. 如何设计合理的告警规则?
  2. 如何避免告警风暴?
  3. 统计异常检测适合什么场景?

参考资料


相关推荐
程序猿编码1 小时前
如何把远程文件变化“骗“成本地inotify事件:一个LD_PRELOAD钩子
c语言·开发语言·网络·tcp/ip·安全
Shadow(⊙o⊙)1 小时前
库的制作与原理2.0---动静态链接,main全解析,CPU在执行文件时的作用,GOT表。
linux·运维·服务器
橙淮10 小时前
并发编程(六)
java·jvm
段一凡-华北理工大学10 小时前
2026 高炉炼铁智能化技术全景与演进路径~系列文章11:演进路径与行业未来
大数据·网络·人工智能·算法·工业智能体·高炉炼铁智能化
拽着尾巴的鱼儿10 小时前
springboot openfeign 自定义feign 接口重试机制
java·spring boot·后端
白露与泡影10 小时前
2026大厂Java面试题大全!牛客网最新版
java·开发语言
lolo大魔王10 小时前
Linux 文件系统超全面详解(原理、结构、挂载、分区、inode、日志、管理命令)
linux·运维·服务器
EntyIU11 小时前
JVM内存与GC笔记
java·jvm·笔记
XS03010611 小时前
并发编程 六
java·后端