基于Flink构建发动机的挑战与实践
原标题:建立基于Flink
背景及现状
倩欣集团的CEP引擎的挑战与实践作为一家网络安全公司,专门为政府、企业、教育、金融等机构和组织提供企业级网络安全技术、产品和服务。钱信NGSOC产品的核心引擎是CEP引擎,用于实时检测网络攻击。其技术演变过程如下图所示。
基于斯珀的CEP方案于2015年开始使用,但当时遇到了很多问题,其中最重要的是性能问题,因为斯珀不支持很多规则条目,一般会有几十条以上的规则受到严重影响。2017年,钱欣的技术方案演变为由C实现的Dolphin 1.0,其在单台机器上的性能大大提高。2018年,迟安新决定将其技术方案转向基于弗林克的马刀。倩欣产品的具体应用场景是企业系统的安全检测和数据分析,从下到上分为四个业务处理流程,即数据收集、分析、处理和显示结果,核心是第三层数据处理。本产品的用户主要是安全规则团队,他们可以使用规则编辑器添加、删除、编辑和查找安全规则,可以批量启动/停止多个规则,同时可以将处于启动状态的有效规则统一发送给产品。
就数据大小而言,该产品并没有解决一个或几个大型数据集群的问题,而是解决了数百个中小型数据集群的操作和维护问题。在B2B领域,由于产品直接部署给客户,许多客户使用内部隔离网络,无法连接到外部网络,也没有专门的人员负责集群操作和维护。在这种情况下,即使是小小的升级也需要很长时间。因此,产品更加注重解决该领域的数据集群可操作性问题。
钱信在最初计划使用Flink作为技术方案和进行研究的过程中发现了一系列的痛点。由于企业级硬件资源的有限环境和规则集数量和类型的不确定性,很难控制Flink程序的运行,现有的库“Flink SQL”和“Flink CEP”无法满足其业务性能要求。具体难点如下:
1.不能进行语义优化、不便于动态更新规则。
今天,当网络安全事件发生井喷时,安全需求迅速扩大。为了在有限的时间内快速支持特定的语义,关联引擎的整体架构必须非常灵活,以满足未来安全分析场景的各种需求。然而,当需求发生巨大变化时,基于开源相关引擎实现的产品将会遇到许多问题。
2.状态监控 高可用支持不足。
面向企业的网络安全监控引擎有一些特定的要求,这些要求在当前的解决方案中得不到很好的支持。
3.CEP 网络负载高、CPU 利用率低。
与互联网企业中使用的大规模集群相比,钱信针对的企业级应用集群规模更小,硬件资源有限,客户定制化程度更高,导致对安全监控规则的要求更严格,引擎发布成本更高。然而,现有的Flink开源解决方案要么需要根据业务需求进行修改,要么性能不佳,无法很好地解决上述问题。
其次,Flink-CEP只是一个有限的序列运算符。在运行时,所有的数据都需要传输到CEP操作符,然后每个条件语句在CEP操作符中串行执行。在这种收集到单个点的操作模式下,需要匹配更多冗余数据,从而产生不必要的网络负载并降低CPU利用率。第三,还有一些非官方的开源轻量级CEP引擎,比如Flink-siddhi,它们功能简单,不是一个完整的解决方案。其他棘手问题包括不支持空窗口偏离和聚集而不保存原始数据。
为了解决上述问题,志安新推出了一款基于Flink的全新CEP引擎Sabre。整体架构如下图所示,包括三个核心模块,配置端在左侧,Sabre-server在中间,Sabre操作端在右侧。核心数据流中有两条主线。红线表示提交、编译、发布和运行规则的过程。绿线表示状态监控的生成、收集、统计和显示过程。如图所示,该架构与Hive非常相似,是大数据OLAP系统的通用架构。下面详细介绍了三个核心模块和两个核心数据流。
首先,规则由规则配置端创建,性能保护策略由性能保护配置端修改。然后,将任务所属的规则文件和性能保护策略文件推送到Sabre-server提供的REST接口,该接口将调用文件分析和优化方法来构建规则的有向无环图。接下来,实现词汇语法分析方法,将规则有向无环图中每个节点的EPL转换为其对应的AST(抽象语法树),然后AST被转换为任务java代码。最后,调用maven命令将java代码打包到任务jar包中,并将任务jar包和基本运行时提交给Flink-on-CHANK集群。Flink有多种操作模式(例如,独立Flink集群、纱线上的Flink集群、纱线上的Flink作业等)。),Sabre采用“Flink作业在纱线上”模式。在黔星NGSOC应用的具体场景下,使用CHANK可以统一维护硬件资源,在CHANK上使用Flink作业可以与Hadoop平台无缝接口,从而实现任务之间的资源隔离。
在Sabre任务执行期间,卡夫卡数据源向引擎提供原始事件。发动机处理结果分为两种类型:回注事件和报警事件。警报事件将被输出到目的地卡夫卡,供低级应用程序使用。回注事件是指规则的处理结果可以直接回注到下级规则中,作为下级规则的数据源事件,从而实现规则的相互引用。
绿线流程(Green Line Process)是指在任务执行过程中,节点的操作监控消息会定期输出到Sabre-server的监控消息缓冲区,然后监控消息统计员会汇总每个规则实例的操作监控消息,并将其作为整个规则的操作监控状态,最后通过Sabre-server提供的REST接口将其推送到规则监控端。下图显示了
技术架构
Sabre的组件依赖性和版本兼容性。
在大多数情况下,钱信将其产品作为黑盒发布,但如果用户已经部署了大数据处理平台,产品将作为应用程序提供。由于客户规模庞大、项目多样、部署环境复杂,或者纱线集群或Sabre的多个版本的存在,需要作为客户已部署的Flink集群的单个Flink应用程序发布。如何节约成本,提高实施效率,适应上述复杂的部署环境,是一个亟待解决的问题。为此,Sabre的设计原则是只使用Flink的分布式计算能力,业务代码应该尽可能减少对API层的依赖,以便与各种Flink版本兼容。如图所示,部署、核心、应用程序接口和库是Flink的基本组件堆栈。Sabre对API层的依赖被最小化,并且只引用了三个数据流API:数据流、密钥流和分裂流。函数依赖只包括数据流的赋值函数、平面映射函数、联合函数、关键字比函数、拆分函数、进程函数、添加函数和其他函数、关键字流最基本的进程函数以及拆分流的选择函数。因为可以依赖的Flink应用编程接口很少,Sabre可以很容易地适应各种Flink版本,因此具有良好的Flink版本兼容性。
在运营商方面,Sabre对Flink进行了一系列改造。下图显示了Flink和Sabre之间的对比,主要包括三列,即Flink本机运算符、Sabre运算符以及两者之间的对比结果。比较结果主要包括四种情况:相同、实现、优化和新建。Sabre拥有13个完全自主研发的核心操作符,其中数据源、定制卡辛克(CustomKafkaSink)和定制数据库(CustomDatabase)已经按照Flink接口要求实现,过滤器、密钥、连接和聚合已经按照Flink原始操作符的语义重新实现,定制窗口和序列已经基于Flink原始操作符的语义进行了优化。
下图展示了马刀的规则和EPL设计。序列、聚合、不出现、流机器学习流M1和连接都是窗口执行时间中包含的计算运算符。蓝色虚线表示引用了动态数据,紫色虚线表示过滤器可以直接连接输出组件,而无需通过窗口。
Window 算子
众所周知,加入和聚合的时间范围受到窗口的限制,而Flink最初的窗口操作符不适合网络安全监控。因此,Sabre设计了一个“自定义窗口操作符”,并重新实现了与“自定义窗口操作符”相匹配的连接和聚合操作符。新窗口有以下六个主要功能:
实时触发并立即匹配:其目的是满足自动实时响应的需求。一旦发出警报,将及时触发响应。无重复匹配:重复报警是规则引擎的常见问题。大量重复报警将增加安全人员的工作量,操作员将清除整个报警相关事件窗口,从而减少重复报警的次数。无序校正:窗口窗口以一个特定的单位为边界,一个接一个地切入时隙。一旦发现乱序情况,插入乱序事件时可以直接定位时隙,基于流状态机进行局部计算,窗口事件超时,计算运算符的值同步更新,加入计数运算符,超时事件删除时计数值同步减少;实时资源和状态监控:由于窗口对内存和CPU的影响较大,因此需要对这些资源进行特殊的监控和保护;流量控制:主要是为了更好地保护从属应用。Sequence 序列算子
Sabre重新设计了Flink CEP与EPL实施的序列运算符。左边是Flink CEP的官方代码显示,它使用程序代码拼凑“NFA自动机”。右边是Sabre中序列运算符的实现,它包括三个不同的过滤器。通过使用正则表达式来提高表达能力。此外,Sabre预先设置了过滤器,无效事件不会传输给窗口操作员,从而减少了不必要的网络负载。此外,只有少数有效数据需要定期匹配,这降低了CPU利用率(过滤器可以是并行的)。
NotOccur 不发生算子
NotOccur是Sabre在Flink基础上添加的一个操作符,支持空事件触发。
Trigger 全局算子
Sabre还为窗口实现了全局触发器。触发器(Trigger)可以将多个子计算运算符组合成复杂的表达式,并实现一个带有GroupBy/Distinct函数的Key运算符来适应这个触发器运算符。
Dynamic Data
Dynamicdata可以映射到数据库中的表,但是该表需要特别优化。具体而言,如果事件的知识产权在威胁情报列表中,并且该威胁情报可能相对较长,例如几十万行或甚至更长,在这种情况下,需要优化该表的数据结构以提高效率。动态数据可以用在其他操作符中,如过滤器、连接等。
流式统计与机器学习 StreamML
机器学习在网络异常检测中变得越来越重要。为了满足实时检测的需要,Sabre不使用Flink机器学习(Flink MachineLearning),而是引入了自主开发的流式机器学习算子StreamML。
Flink MachineLearning是一个基于批处理模式DataSetApi的机器学习函数库,StreamML是一个流式机器学习操作器,其目的是满足网络安全监控的具体要求。与阿里巴巴的开源Alink相比,StreamML允许机器学习算法工程师通过配置规则快速验证算法模型,而无需编写任何程序代码。此外,流式机器学习操作员StreamML实现了“模型训练/更新”和“模型使用”的统一概念。其核心功能是通过算法、技术和模型实现数据训练和新的数据检测。流式机器学习算子StreamL引入了三种类型的输入,即:事件流、检测对象和对象属性;输出还包括三种类型:事件、警报和预警。
streaming machine learning operator StreamL的组件堆栈自下而上由三部分组成:机器学习方法、应用场景和产品业务。通过基本的机器学习算法(如统计学习算法、序列分析算法和聚类分析算法),流媒体机器学习算子StreamML可以满足特定的安全监控应用场景(如行为特征异常检测、时间序列异常检测和群组聚类分析),从而为用户提供可理解的产品服务(如基线、用户和实体行为分析UEBA)。
行为特征的异常检测:基于所收集的样本数据(长时间),为统计分析对象建立行为基线,并基于该基线检测偏离正常行为模式的行为。例如,用户通常在哪里发起连接?哪个接线员?哪个国家?哪个地区?这种异常的用户行为是组织中常见的异常吗?时序异常检测:根据一个或多个统计属性,判断按时序排列的数字序列是否异常,从而通过监控指标变化来发现安全事件。例如,监控网站每小时的流量以防止分布式拒绝服务攻击;对每个账户的传输文件大小的平均值进行建模,并检测传输文件大小的平均值中存在异常值的账户。聚类分析(Cluster analysis):挖掘数据特征属性之间的潜在相关性,并用相似的特征值对数据进行聚类。例如,用户有什么特殊的特征吗?可执行/特权用户?根据执行的操作命令和可访问的实体,识别信息技术管理员、数据库管理员和其他高级用户。Sabre与Flink具有相同的性能,因为Flink用作底层运行组件。此外,Sabre还在以下几个方面优化了性能,以满足网络安全监控领域的具体要求:
全局组件(数据源、动态表)引用优化。由于卡夫卡式数据源的主题有限以及规则数量的动态扩展,多个规则很有可能共享同一个数据源。根据EPL语义等价原则合并同一个数据源,从而减少了数据输入和线程的总量。新的匹配引擎。序列算子采用了一种新型的流式状态机引擎,重用了状态机缓存的状态,提高了匹配速度。类似的优化还包括大规模知识产权匹配引擎和大规模字符串匹配引擎。流量和日志中需要大规模的知识产权和字符串匹配,通过知识产权匹配引擎和大规模字符串匹配引擎进行优化以提高效率。表格计算表达式优化。对于规则中引用的动态表,将根据表达式的具体特征构建相应的最优计算数据结构,以避免扫描整个表数据,进而保证执行时间复杂度不变。自定义流窗口操作符。采用“时隙”技术实现失序校正功能,具有实时输出、不重复、不遗漏报警的特点。图表上的字段被自动推导以优化事件结构。根据规则前后的逻辑关系,推导出规则中标记的原始日志相关字段,而不输出所有字段,从而优化输出事件结构,减小输出事件大小。地图上的数据分区被自动推导以优化流拓扑。由于特定的功能需求,窗口经常缓存大量数据,从而消耗更多的内存。全局窗口的哈希优化可防止所有全局窗口被分配给同一个Taskmanager进程,从而提高引擎的整体内存利用率。上图是Sabre流状态机引擎的表示,其主要功能是序列匹配。在图的左边是一台标准的普通发动机。正常的过程可以从模式到语法树,再到NFA,然后到DFA,或者从Paterrn直接到NFA。图的左下方是正则表达式的NFA表示,右侧是正则表达式的DFA表示。在使用DFA(图中的绿线)时,已经进行了改进。目的是在出现故障时提高处理性能。当正则表达式的后半部分出现乱序时,改进对性能改进的效果最好。
大型常规发动机主要使用两种互补的方法(图中的上半部分和下半部分)。将NFA移交给外交部时,在许多情况下并不成功。在这种情况下,成品分析的半成品经常被生成,称为未完成成品分析(Unfinished-DFA)。第一种方法属于混合状态自动机,包括NFA和DFA,适用于模式数量小于1000的情况。然而,第二种方法适用于图案数量超过1000甚至数万的情况。在该方法中,首先需要找到锚点,然后进行匹配以降低整体时间复杂度。这两种方法的结合可以更好地解决大规模规则匹配问题。
产品运维
多级规则
多级规则是产品运行和维护的一个显著特征。如下图所示,为了满足复杂场景的需要,一个规则的输出可以直接用作另一个规则的输入。通过这种规则拆分的方式,复杂的“多级规则”可以分层构建。例如,图中“暴力检测”规则的结果可以直接重新注入到下面的“登录成功”规则中,而无需额外的通信组件,从而实现更复杂的“暴力破解”规则。
服务化/多租户/资源监控
产品采用微服务架构,使用多租户和多任务来满足多个规则引擎的使用场景,并实时监控资源,确保系统稳定运行。
规则级的状态/资源监控
规则级状态和资源监控是非常重要的产品要求。该产品采用分布式监控,提供三级分布式监控能力(用户、任务和规则),支持吞吐量、每股收益、中央处理器和内存的监控。
整体系统保护
整体系统保护主要涉及两个方面,即流量控制和自我保护。
未来发展与思考
未来基于Flink的Sabre引擎将不断优化产品性能和功能,并将在简洁的项目中总结优秀的实践,并及时反馈给Apache Flink社区。
本文作者:韩鹏
安琪鑫
尚云参见云起号码,点击此处查看更多:http://yqh.aliyun.com/? Utm _ content=g _ 1000100940