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. 统计异常检测适合什么场景?

参考资料


相关推荐
早睡早起身体好12318 小时前
为什么 Network 中会出现两个同名请求?——CORS 预检请求学习笔记
网络·笔记·学习·网络安全
daad77719 小时前
记录matlab状态机demo
java·网络·matlab
牡丹雅忻119 小时前
AES 加密模式演进:从 ECB、CBC 到 GCM 的 C# 深度实践
java·开发语言·c#
kaoa00019 小时前
Linux入门攻坚——84、网络虚拟化技术-1
linux·运维·服务器
paopaokaka_luck19 小时前
基于springboot3+vue3的智能文库平台(AI智能搜索、AI智能汇总、实时在线状态展示、多格式文档预览与富文本编辑、Echarts图形化分析)
前端·网络·spring boot·网络协议·echarts
学者猫头鹰19 小时前
Java 8 核心新特性
java
RisunJan19 小时前
Linux命令-shutdown(安全关闭或重启系统)
linux·服务器·安全
冰心孤城20 小时前
Excel: xls与xlsx格式转换排坑指南
java·前端·excel
自强的小白20 小时前
maven高级(聚合和私服)以及私服的上传和下载
java·maven
唐青枫20 小时前
Java ReentrantLock 实战详解:比 synchronized 更灵活的可重入锁
java