【51CTO.com原创稿件】1 引言
目前业界已经有很多杰出的监控系统如Nagios、Zabbix、Prometheus,但都是面向运维人员,在应对复杂多变的业务指标监控时显得不够灵活。
为此苏宁数据云在流式计算框架Apache Flink之上设计了一组包含ETL、指标计算、告警触发、告警通知模块的业务监控引擎。
其基本规则是告警SQL DSL语言,定义完备易用的场景规则语法和算子并支持动态更新调整,以便于业务方接入。下面对其基本原理和实现进行介绍,供各位同行参考指正。
2 DSL规则设计
初期调研了各个业务方的需求,整理归纳出核心需求点主要是基于维度和时间的指标绝对值、同环比或方差在超出阈值范围则触发告警,且业务方接入的是原始明细数据,故在设计规则中需要包含数据清洗过滤、分组、聚合计算、时间窗口设置特性。
而SQL语言作为开发人员最熟悉的数据处理语言,选择其作为原型,可以省去理解和沟通的成本。
语法规则如下:
- SELECT {metrics} FROM {metricFilters} WHERE {alertConditions} GROUP BY {groupByExpr} ORDER BY {orderByExpr} FOR LAST {number} MINUTE
目前聚合函数支持的均值(avg)、记数(count)、总数(sum)、去重记数(distinct_count)等指标计算,并支持多个指标四则混合运算、位运算、比较运算、逻辑运算。
以下SQL规则表达的业务含义是根据错误类型和城市信息进行分组,5分钟内错误数量大于100且与前5分钟环比大于20%则触发告警:
- SELECT COUNT(errorType, 5) AS currentTypeNum, COUNT(errorType, 10, 5) AS previewTypeNum, (currentTypeNum - previewTypeNum) / previewTypeNumAS circularPercent, errorType, city
- FROM mobileAppIdIN ("Suning_PCbrowser","Suning_WAP")
- WHERE currentTypeNum>100 AND circularPercent>0.2
- GROUP BY errorType, city
- ORDER BY EVENT_TIME
- FOR LAST10 MINUTE
3 实现设计
3.1 SQL解析
基于Antlr定义词法和语法,使用Maven Antlr插件生成AST解析器,Visitor模式遍历语法树实现各个部分处理器,不熟悉的同学可以参考Antlr官方手册,此处不再赘述。
解析SQL语句过程如下:
需要注意的是考虑到ETL过程和计算过程都是独立模块,若计算过程通过字段名引用字段值,则中间对象必然是键值对方式的Map结构,在传输中序列化和反序列化必然会对性能有一定的影响。
为此在遍历抽象语法树过程中须构建一个解析上下文,把字段名引用改为数组下标,ETL过程产生的中间数据对象为数组结构,计算时访问字段值的时间复杂度为O(1)。
例如原始数据为:
- {"errorType":"E005","mobileAppId":"Suning_WAP","city":"025","network":"CMCC"}
- 解析出子字段数组[“errorType”,”city”]发送ETL模块,处理后数据对象Row为[“E005”,”025”],算子COUNT(“errorType”)实际运行中为COUNT(ROW[0])
3.2 整体架构
整个流程中ETL和告警计算模块都是运行在Apache Flink中,借用Flink实时计算和状态持久化能力。
每个业务接入方的数据格式不尽相同,把相关数据解析、清洗、过滤、丰富等功能单独抽离成ETL模块,可以根据接入方业务需求单独定制部署,其中SQL中FROM阶段提前到ETL模块,提取过滤掉不需要的数据,降低数据传输量。
3.3 SQL引擎在Flink中的运行机制
告警规则SourceStream转成广播流BroadcastStream并connect到数据解析Stream,因并行度不一致且未分组须使用BroadcastProcessFunction处理规则的变化通知,把SQL规则解析成字段提取和过滤处理器,保存在BroadcastState中达到数据流和广播流共享状态的目的。
从Kafka中消费ETL模块提取的字段和规则ID,根据告警规则Group子句提取分组信息;结合规则流解析Select子句表达式计算所有指标;再次结合规则流解析Where 子句告警触发条件和状态机相关参数,判断系统当前健康状态,触发健康状态机变迁;把系统状态变迁和当前指标值作为告警事件写入Kakfa,由告警通知模块根据通知规则配置处理相关发送逻辑。
3.4 聚合计算
Apache Flink是流式实时处理框架,而聚合计算类似于批处理,需要计算窗口内的所有数据;相对应告警SQL可能会产生大量分组,每个分组其实都是独立的告警规则,若是缓存一个事件窗口的数据进行计算,会对Flink的状态维护产生巨大压力,所以对于聚合计算采用的分钟级分桶计算和累加器聚合结果设计思路。
根据时间窗口长度创建环形队列,每分钟一个桶,按照时间计算当前元素桶的位置,计算当前桶的值。
类似于Spark和Flink中累加器Accumulator实现,保存分钟级计算中间结果、合并累加器、获取最终值,因此计算过程中不必保留原始数据,只需要在Flink中保存累加器的状态即可。
- /**
- * Creates a new accumulator, starting a new aggregate.
- */
- ADD createAccumulator();
- /**
- * Adds the given input value to the given accumulator, returning the
- * new accumulator value.
- */
- ADD add(ELE value, ADD accumulator);
- /**
- * Gets the result of the aggregation from the accumulator.
- */
- OUT getResult(ADD accumulator);
- /**
- * Merges two accumulators, returning an accumulator with the merged state.
- */
- ADD merge(ADD a, ADD b);
- }
其中去重计数distinct_count聚合计算在告警场景允许精度损失故采用支持分桶累加的HyperLogLog算法,降低对内存的要求。
3.5 告警状态机
是否产生告警事件并不是依据计算出的指标,而是根据Where从句判断指标是否超出阈值返回True或False确定当前系统健康状态,比对当前状态产生的健康状态变迁事件作为触发告警事件。
目前设计系统的状态有三种,即正常(Normal)、警告(Warning)、严重(Critical),而后两种就是分别对应两个SQL DSL中Where从句表达式,状态变迁图如下:
业务系统是否产生告警通知也可以根据这几种事件进行配置,如果连续5分钟异常才产生告警,则可以只关注CONTINUE相关事件。当然告警通知系统也有通知合并和告警风暴抑制相关功能。
4 问题和展望
目前此引擎已经用于苏宁易购登录、商品详情页、购物车和支付多个业务线的用户体验监控,帮助产品和业务运营人员可以快速发现和定位问题。为了提升处理能力和降低接入难度,以下两个方面还需要进行优化:
苏宁数据云服务产品
苏宁数据云已有大数据开发套件(提供全方位的大数据开发服务)、人工智能服务(实现智能的人机互动做出更好决策)、数据分析及展示服务(提供海量数据处理与分析方法)、平台基础服务(提供大数据平台基础服务),实时告警数据分析平台也在规划建设中。实时计算中实现监控规则DSL是内部项目的一次技术探索,若能经过实际业务的考验,也会考虑通过数据云对外提供服务。
作者简介
黄小虎,苏宁科技集团消费者平台购物流程架构负责人,全面负责苏宁易购商品详情页、购物车、大聚会等核心系统的优化及大促保障工作。对电商交易流程和业务有较深入的思考和研究,专注于高并发大型电商网站的架构设计、高可用的系统设计。曾主导和参与了 Commerce 系统拆分、商品详情页接入层优化、云信客服系统重构等重大技术攻关项目。现致力于打造苏宁易购新一代核心购物流程系统,希望将购物体验做到更好。
胡正林,苏宁科技集团消费者平台高级架构师,十余年软件开发经验,熟悉大型分布式高并发系统架构和开发,目前主要负责易购各系统架构优化与大促保障工作。
【51CTO原创稿件,合作站点转载请注明原文作者和出处为51CTO.com】
最近,DevOps的采用导致了企业计算的重大转变。除无服务器计算,动态配置和即付...
本文转载自网络,原文链接:https://mp.weixin.qq.com/s/vlOUg46B5bcmToX-fjavJQ...
9月17日,2020云栖大会上,阿里云正式发布工业大脑3.0。 阿里云智能资深产品专家...
2020年对于云计算行业来说是突破性的一年,因为公共云供应商增加了收入,而疫情...
在TOP云(zuntop.com)科技租赁过服务器的站长都知道独立服务器在价格上比VPS主...
一、PostgreSQL行业位置 一 行业位置 首先我们看一看RDS PostgreSQL在整个行业当...
很长时间没有更新原创文章了,但是还一直在思考和沉淀当中,后面公众号会更频繁...
中国最?好的一朵云飘进了华瑞银行。阿里云将进一步助力华瑞银行All in Cloud。 -...
定义 this是函数运行时自动生成的内部对象,即调用函数的那个对象。(不一定很准...
查看表结构,sbtest1有主键、k_1二级索引、i_c二级索引 CREATE TABLE `sbtest1` ...