目录
-
- 摘要
- 一、异常检测引擎概述
-
- [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异常检测引擎:
- 引擎原理:实时异常检测
- 创建方法:简单引擎、分组引擎
- 检测规则:阈值规则、统计规则、组合规则
- 窗口模式:无窗口、有窗口
- 实战应用:温度告警、组合告警、统计异常
- 告警通知:告警推送、告警聚合
思考题:
- 如何设计合理的告警规则?
- 如何避免告警风暴?
- 统计异常检测适合什么场景?