StreamSQL

July 14, 2026 · View on GitHub

GoDoc Go Report CI RELEASE codecov Mentioned in Awesome Go

English| 简体中文

StreamSQL 是为物联网边缘设计的、可嵌入的 SQL 流处理引擎。它介于「时序数据库」和「Apache Flink」之间——既能像 Flink 一样做实时计算,又能像时序数据库一样轻量部署:在 128MB 的网关进程内,用一条 SQL 跑实时过滤、窗口聚合、CDC 式变化检测和复杂事件模式识别。

时序数据库的实时性 + Flink 的计算能力 + 极简的部署与集成体验。

📖 官方文档 | 🐙 GitHub · Gitee · GitCode

  • 🪶 轻量可嵌入 纯内存、零外部依赖,作为基础库塞进 128MB 网关,秒级启动
  • 🧩 全功能 SQL 滚动/滑动/计数/会话/全局窗口、事件时间 + Watermark、CASE、嵌套字段、HAVING
  • 🔍 分析函数 lag / had_changed / changed_col / 累积统计,专攻 CDC 变化检测与上下文回溯
  • 🧩 复杂事件识别(CEP) MATCH_RECOGNIZE(SQL:2016,对齐 Flink)——轻量边缘引擎中独有
  • 🚀 边缘级性能 x86 单核过滤 ~192 万 msg/s;128MB 可承载 10 万+ 设备分区状态
  • 🔌 RuleGo 生态 借 RuleGo 组件接入 MQTT / HTTP / 消息队列 / 数据库等任意数据源

为什么用 StreamSQL

传统流处理只有两个极端:时序数据库存储强但实时计算弱;Flink / Storm 功能强但部署重、吃 GB 级内存,不适合边缘。StreamSQL 填补中间的空白——专为边缘端设计,在资源受限的环境里对海量数据做实时聚合与模式识别。

维度StreamSQLApache FlinkeKuiper时序数据库
部署复杂度极简复杂简单中等
资源占用极低(~10MB)高(GB 级)极低(~10MB)中等
可嵌入 / 作基础库⚠️⚠️
完整 SQL有限
复杂事件识别(CEP)
分析函数 / 变化检测
事件时间 + Watermark⚠️
边缘部署⚠️
集群水平扩展单机单机

适合:IoT 网关 / 工业控制器 / 车载系统的边缘实时计算、设备监控与异常检测、流处理原型验证、为 RuleGo 规则链补 SQL 能力。 不适合:需要水平扩展的大规模集群、需要持久化状态或 ACID 事务的场景。

安装

go get github.com/rulego/streamsql

快速开始

每条数据立即处理并输出——实时转换与过滤,无需等待窗口:

package main

import (
	"fmt"
	"github.com/rulego/streamsql"
)

func main() {
	ssql := streamsql.New()
	defer ssql.Stop()

	err := ssql.Execute(`SELECT deviceId,
	    temperature * 1.8 + 32 AS fahrenheit,
	    CASE WHEN temperature > 30 THEN 'hot' ELSE 'normal' END AS level
	    FROM stream WHERE temperature > 0`)
	if err != nil {
		panic(err)
	}

	ssql.AddSink(func(results []map[string]interface{}) {
		fmt.Printf("结果: %+v\n", results)
	})

	ssql.Emit(map[string]interface{}{"deviceId": "sensor01", "temperature": 32.5})
}
// => 结果: map[deviceId:sensor01 fahrenheit:90.5 level:hot]

核心能力

🧩 复杂事件识别(CEP)—— 轻量边缘引擎独有

识别按特定顺序出现的事件序列:连续越限防抖、先升后降、开停机工作流、乱序事件。SQL:2016 标准 MATCH_RECOGNIZE,对齐 Flink SQL,四道闸保证边缘内存有界。

-- 温度连续 3 次越限才算真报警(防抖,避免单点抖动误报)
SELECT * FROM stream
MATCH_RECOGNIZE (
    ORDER BY ts
    MEASURES MATCH_NUMBER() AS mn, LAST(A.temp) AS peak
    ONE ROW PER MATCH
    PATTERN (A{3}) WITHIN '1h'
    DEFINE A AS temp > 50
)

支持模式变量 + 量词(? * + {n})、交替 |PERMUTE、导航(PREV/NEXT/FIRST/LAST)、聚合、SUBSETFINAL/RUNNINGWITHIN 主动过期。详见模式识别文档

🔍 分析函数 —— CDC 变化检测与累积

在无窗口的连续事件流上做跨事件状态计算,每条事件到达立刻求值,状态跨事件保留。

-- CDC 变化检测:只在温度变化时输出,并带上一次的温度值
SELECT deviceId, temperature, lag(temperature) AS prev
FROM stream
WHERE had_changed(true, temperature)

-- 分区 + 累积:每个设备各自的状态、开服至今累计
SELECT deviceId, acc_sum(score) OVER (PARTITION BY deviceId) AS total
FROM stream

OVER (PARTITION BY ... WHEN ...) 控制分区与更新条件。详见分析函数文档

何时用什么:相邻事件比较 → 分析函数;事件序列/顺序模式 → CEP;时间段统计 → 窗口聚合 + HAVING。

🪟 窗口聚合

将无界数据切成有界片段做统计,支持 5 种窗口:

-- 每 5 秒一个滚动窗口,按设备分组求均值
SELECT deviceId, AVG(temperature) AS avg_temp,
       window_start() AS start, window_end() AS end
FROM stream
GROUP BY deviceId, TumblingWindow('5s')
  • 滚动窗口 TumblingWindow('5s'):固定大小,不重叠
  • 滑动窗口 SlidingWindow('30s','10s'):固定大小,按步长滑动
  • 计数窗口 CountingWindow(100):按条数划分
  • 会话窗口 SessionWindow('5m'):按数据活跃度动态开合
  • 全局窗口 GLOBAL WINDOW TRIGGER WHEN ...:无时间边界,由聚合阈值谓词驱动,每分组 O(1) 运行态
  • 内置聚合:MAX / MIN / AVG / SUM / COUNT / STDDEV / MEDIAN / PERCENTILE 等,支持 GROUP BYHAVING

⏱ 事件时间与 Watermark

支持事件时间(数据自带时间戳)和处理时间(系统时钟)两种语义。事件时间用 Watermark 处理乱序与迟到数据:

SELECT deviceId, COUNT(*) AS cnt
FROM stream
GROUP BY deviceId, TumblingWindow('5m')
WITH (TIMESTAMP='eventTime', TIMEUNIT='ms',
      MAXOUTOFORDERNESS='5s',   -- 容忍 5 秒乱序
      ALLOWEDLATENESS='2s',     -- 触发后还能接受 2 秒迟到数据
      IDLETIMEOUT='5s')         -- 空闲 5 秒后按处理时间推进 watermark

🧩 嵌套字段

点号语法访问嵌套结构,数组下标访问数组元素:

SELECT device.info.name AS name, sensors[0].value AS v0
FROM stream WHERE device.info.type = 'temperature'

🔧 自定义函数

一行注册,立即在 SQL 中可用,支持 8 种函数类型(数学/字符串/转换/日期/聚合/分析/窗口/自定义),运行时可动态增删:

functions.RegisterCustomFunction("f2c", functions.TypeConversion,
    "温度转换", "华氏转摄氏", 1, 1,
    func(ctx *functions.FunctionContext, args []any) (any, error) {
        f, _ := functions.ConvertToFloat64(args[0])
        return (f - 32) * 5 / 9, nil
    })
// SELECT f2c(temperature) AS celsius FROM stream

性能

x86 单核 / 128MB / v1.0.3 实测test/e2e/stress_test.goBenchmarkGateway_*):

规则ns/opallocsmsg/s
过滤5226~192 万
转换135912~74 万
分析 + 分区209518~48 万
  • 128MB 内存可承载 10 万+ 设备的分区状态——内存不是瓶颈,CPU 吞吐才是。
  • 稳定性:无 goroutine 泄漏,堆不随负载/分区数线性增长。
  • 一条规则吃满一个核是边缘网关的最优用法;多核靠并行多个独立实例扩展(GOGC 调优可近线性)。

ARM 网关数字为 x86 折算估算,上线前需在目标 SoC 实测。详见网关容量与性能基准

概念

两种处理模式

  • 非聚合模式:不含聚合函数,每条数据立即处理输出,超低延迟——数据清洗、实时告警、数据富化。
  • 聚合模式:含聚合函数或 GROUP BY,数据进窗口,窗口触发时输出聚合结果。

窗口

流数据无界,无法整体处理。窗口把无界数据切成一系列有界片段:滚动、滑动、计数、会话、全局(见上)。

时间语义

  • 事件时间:数据实际产生的时间(如 event_time 字段)。基于时间戳划分窗口,配合 Watermark 正确处理乱序/迟到数据,结果准确但有延迟。
  • 处理时间:数据到达系统的当前时间(默认)。低延迟,但不处理乱序/迟到数据。
特性事件时间处理时间
时间来源数据中的时间戳字段系统当前时间
乱序/迟到支持(Watermark)不支持
结果准确性准确可能不准
延迟较高
配置WITH (TIMESTAMP='field')默认(不指定 WITH)

深入概念(窗口、Watermark、迟到数据)见核心概念文档

与 RuleGo 集成

StreamSQL 可作为RuleGo规则链节点,借其 60+ 组件接入任意数据源与第三方系统,并叠加规则引擎能力:

  • streamTransformx/streamTransform):非聚合 SQL,逐条流式转换
  • streamAggregatorx/streamAggregator):聚合 SQL,窗口聚合
{
  "nodes": [{
    "id": "transform1", "type": "x/streamTransform",
    "configuration": { "sql": "SELECT deviceId, temperature*1.8+32 AS f FROM stream WHERE temperature>20" }
  }]
}

详见RuleGo 集成文档

函数

60+ 内置函数:数学、字符串、转换、日期时间、聚合、分析、窗口等。函数使用指南

贡献与社区

欢迎提交 Issue 和 Pull Request。代码请符合 Go 标准,并附测试用例。

License

Apache License 2.0