Base de datos de series de tiempo 丨 Cómo el motor de procesamiento de flujo de DolphinDB realiza la detección de anomalías en los datos del sensor

DolphinDB proporciona una tabla de flujo y un motor de cálculo de flujo para el procesamiento de datos en tiempo real, incluida la detección de anomalías de los datos de los sensores en el Internet de las cosas. El motor de detección de anomalías integrado puede satisfacer las necesidades de la mayoría de los escenarios de detección de anomalías. Si la lógica de detección de anomalías es compleja y especial, y el motor de detección de anomalías estandarizado no puede cumplir con los requisitos, el usuario puede implementarla con una función de procesamiento de mensajes personalizada.


1. Requisitos de la solicitud

Un sistema de monitoreo recopila datos cada segundo. Hay dos requisitos de detección de anomalías como se indica a continuación:

  • Cada 3 minutos, si la temperatura del sensor es superior a 40 grados Celsius dos veces y superior a 30 grados Celsius tres veces, el sistema emitirá una alarma.
  • Si la red de sensores se desconecta y no hay datos en 5 minutos, el sistema emitirá una alarma.

La alarma anterior significa que si se detecta una anomalía, se escribe un registro en una tabla de datos de flujo.


2. Ideas de diseño

El marco de flujo de cálculo de la DolphinDB base de datos de series de tiempo distribuido actualmente soporta motores de agregación de series de tiempo , de sección transversal motores de agregación , anomalía de motores de detección, y los motores de computación de encargo de flujo:

  • Agregador de series de tiempo: puede realizar cálculos de agregación vertical del estado del dispositivo (agregado en series de tiempo), o agregar varios estados de dispositivos horizontalmente y luego agregarlos según el tiempo. La agregación de series de tiempo admite cálculos de transmisión con ventanas deslizantes. DolphinDB ha optimizado el rendimiento de las funciones de agregación de ventanas integradas, y una CPU de un solo núcleo puede completar la agregación de tiempo de casi un millón de estados por segundo.
  • Agregador de sección transversal (Agregador de sección transversal): es una extensión del motor de instantáneas que puede realizar cálculos de agregación horizontal en el estado del dispositivo, como calcular la temperatura promedio de un lote de dispositivos.
  • Motor de detección de anomalías: puede detectar si los datos cumplen con los indicadores de alarma definidos por el usuario en tiempo real. Si se encuentran datos anormales, se enviarán a la mesa para satisfacer las necesidades de monitoreo en tiempo real y alerta temprana de Internet de Cosas.
  • Motor de procesamiento de flujo personalizado: cuando ninguno de los tres motores anteriores puede satisfacer la demanda, los usuarios también pueden usar el script DolphinDB o el lenguaje API para personalizar las funciones de procesamiento de mensajes.

Para el primer requisito, el sistema emitirá una alarma cuando la temperatura del sensor sea anormal en 3 minutos y el motor de detección anormal sea adecuado. Simplemente escriba una expresión con el script DolphinDB para describir la lógica de excepción. Pero el segundo requisito no se aplica. El motor de detección de anomalías se procesa mediante agrupación de dispositivos. El cálculo se activa cada vez que ingresan nuevos datos, o el cálculo de agregación solo se realiza en una ventana móvil de longitud fija a intervalos regulares. Si un sensor no genera nuevos datos, no puede activar cálculos. La solución es personalizar un controlador de mensajes para calcular y detectar. La idea de realización específica es: utilizar una tabla de memoria de valores clave para registrar el tiempo de adquisición más reciente de cada sensor. El mensaje ingresa a la función de procesamiento de mensajes en un cierto intervalo de tiempo (por ejemplo, 1 segundo). La función de procesamiento de mensajes primero actualiza la tabla de memoria de valores clave y luego verifica si el último tiempo de recopilación registrado por cada dispositivo en esta tabla excede los 5 minutos y, de ser así, emitirá una alarma.


3. Pasos de implementación detallados


3.1 Definir la tabla de datos de flujo de entrada y salida

Primero, defina una tabla de datos de transmisión para recibir los datos del sensor recopilados en tiempo real y utilice la función enableTableShareAndPersistence para compartir y conservar la tabla de datos de transmisión en el disco duro. El parámetro cacheSize limita la cantidad máxima de datos retenidos en la memoria a 1 millón de filas. Aunque el dispositivo sensor tiene muchos indicadores, debido a que este ejemplo solo incluye indicadores de temperatura, este ejemplo simplifica la estructura de la tabla. La estructura de la tabla solo contiene tres columnas, a saber, el número de sensor ID del dispositivo, el tiempo ts y la temperatura. el código se muestra a continuación:

st = streamTable (1000000: 0, `deviceID`ts`temperature, [INT, DATETIME, FLOAT]) 
enableTableShareAndPersistence (table = st, tableName =` sensor, asynWrite = false, compress = true, cacheSize = 1000000)

其次定义报警输出流数据表用于异常检测引擎的输出。按照DolphinDB用户手册中对创建异常检测引擎函数createAnomalyDetectionEngine各参数的说明,异常引擎对输出表的格式有严格要求,即它的第一列必须是时间类型,用于存放检测到异常的时间戳,并且该列的数据类型需与输入表的时间列一致。如果keyColumn(分组列)参数不为空,那么第二列为keyColumn,在本例中,分组列为传感器编号deviceID。之后的两列分别为int类型和string/symbol类型,用于记录异常的类型(在metrics中的下标)和异常的内容。建表代码如下:

share streamTable(1000:0, `time`deviceID`anomalyType`anomalyString, [DATETIME,INT,INT, SYMBOL]) as warningTable

3.2 创建异常检测引擎,实现传感器温度异常报警的功能

异常检测引擎中,设置异常指标为sum(temperature > 40) > 2 && sum(temperature > 30) > 3 ,分组列(keyColumn)为传感器编号deviceID,数据窗口windowSize为180秒,计算的时间间隔step为30秒。这些参数如何设置可参考异常检测引擎。代码如下:

engine = createAnomalyDetectionEngine(name="engine1", metrics=<[sum(temperature > 40) > 2 && sum(temperature > 30) > 3  ]>,dummyTable=sensor, outputTable=warningTable, timeColumn=`ts, keyColumn=`deviceID, windowSize = 180, step = 30)
subscribeTable(tableName="sensor", actionName="sensorAnomalyDetection", offset=0, handler= append!{engine}, msgAsTable=true)

3.3 创建自定义消息处理函数,实现传感器离线报警的功能

第二个需求,需要保存每个传感器的最新数据采集时间,用于判断是否已有5分钟未采集数据。本例采用键值内存表保存每个设备的最新状态,并以传感器编号deviceID作为主键。键值表中,基于键值的查找和更新具有非常高的效率。收到传感器数据时,用append!函数更新键值表中的记录。如果新记录中的主键值不存在于表中,那么往表中添加新的记录;如果新记录的主键值与已有记录的主键值重复时,会更新表中该主键值对应的记录。

在输出异常信息到报警输出流数据表时,异常的类型anomalyType因为上节异常检测引擎已用0,所以这里设为1。异常的内容设为空。

配置函数subscribeTable的参数throttle和batchSize,可以达到批量处理消息提升性能的目的。参数throttle决定handler间隔多久时间处理一次消息,本例中设定为每秒处理一次。这里要注意当消息的数量达到batchSize时,即便间隔时间没到也会处理进来的消息,所以需要将batchSize设置为一个比较大的数。示例代码如下,其中传感器数deviceNum假设为3:

t=keyedTable(`deviceID,100:0,`deviceID`time,[INT,DATETIME])
deviceNum=3
insert into t values(1..deviceNum,take(now().datetime(),deviceNum))
def checkNoData (mutable keyedTable, mutable outputTable, msg) {
	keyedTable.append!(select deviceID, ts from msg)
	warning = select now().datetime(), deviceID, 1 as anomalyType, "" as anomalyString from keyedTable where time < datetimeAdd(now().datetime(), -5, "m")
	if(warning.size() > 0) outputTable.append!(warning)
}
subscribeTable(tableName="sensor", actionName="noData", offset=0,handler=checkNoData{t, warningTable}, msgAsTable=true, batchSize=1000000, throttle=1)


4. 模拟写入与验证

假设3个传感器,一秒钟采集一次数据,前一分钟所有设备都有数据,1分钟后第3个设备无数据。示例代码如下:

def writeData(){
	deviceNum = 3
	for (i in 0:60) {
		data = table(take(1..deviceNum, deviceNum) as deviceID, take(now().datetime(), deviceNum) as ts, rand(10..41, deviceNum) as temperature)
		sensor.append!(data)
		sleep(1000)
	}
	deviceNum = 2
	for (i in 0:600) {
		data = table(take(1..deviceNum, deviceNum) as deviceID ,take(now().datetime(), deviceNum) as ts, rand(10..45,deviceNum) as temperature)
		sensor.append!(data)
		sleep(1000)
	}	
}
submitJob("simulateData", "simulate sensor data", writeData)

运行后,查询报警输出表warningTable,可看到结果示例如下:

47c4f8756c9257c7c933403c4f000cc0.png


附录

测试代码


Supongo que te gusta

Origin blog.51cto.com/15022783/2675837
Recomendado
Clasificación