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

参考资料


相关推荐
SimonKing5 小时前
艹,维护AI写的代码,我心态崩了......
java·后端·程序员
用户298698530146 小时前
Java Word 文档样式进阶:段落与文本背景色设置完全指南
java·后端
小bo波21 小时前
从"任意文件复制"深挖Java I/O:字符流与字节流的本质抉择
java·nio·io流·后端开发·文件复制
zzzzzz3101 天前
9K Star 炸裂开源!这个 C 语言写的代码知识图谱,把 Linux 内核索引压缩到了 3 分钟
linux·服务器·sql
nanxun8862 天前
记一次诡异的 Docker 容器"串包"故障排查
java
用户1563068103512 天前
Day01 | Java 基础(Java SE)
java
行者全栈架构师2 天前
Maven dependency:tree 的 8 个高级用法
java·后端
行者全栈架构师2 天前
IDEA 中 Maven 项目的 15 个红色报错快速解决方法
java·后端
令人头秃的代码0_02 天前
mac(m5)平台编译openjdk
java
唐青枫3 天前
Java JDBC 实战指南:从 Connection 到事务和连接池
java