利用Microsoft StreamInsight控制较大数据流详解

数据库 其他数据库
本文我们主要介绍了利用Microsoft StreamInsight控制较大数据流的相关知识,并给出了实际的代码示例加以说明,希望能够对您有所帮助。

StreamInsight 流处理体系结构和熟悉的基于.NET 的开发平台使开发人员可以快速实现强大而高效的事件处理应用程序。本文我们主要就介绍一下利用Microsoft StreamInsight控制较大数据流的具体方法,接下来就让我们一起来了解一下这部分内容吧。

利用Microsoft StreamInsight 控制较大数据流

生产线的产量下降后,将容易出现用户媒体流跳过这些流程,或者您的一个产品成为了“必需产品”的情况。真正的窍门是在这些情况发生时进行识别,或根据以往趋势对其做出预测。

成功预测这些情况需要使用近乎实时的方法。在对相关数据进行提取、转换并加载到 SQL Server Analysis Services (SSAS) 等传统商业智能 (BI) 解决方案中时,情况早已发生改变。同样,一些系统依靠请求-响应模式来从事务性数据存储(如 SQL Server Reporting Services 或 SSRS、报告)中请求已更新的数据,像这样的系统总是在接近请求-轮询间隔结束时运行陈旧数据。轮询间隔通常是固定的,因此即使突然发生有趣的活动,消耗系统也不会知道,直到进入下一个间隔。相反,消耗系统应该在满足趣味条件时连续收到通知。

在检测新兴趋势时,时间间隔至关重要 - 在过去的五分钟内,一个特定项目发生了 100 次购买,显而易见,这比过去五个月间的持续购买更能指示新兴趋势。SSAS 和 SSRS 等传统系统需要开发人员通过事务性存储中多维数据集或时间戳列中的单独维度来自行跟踪数据的及时性。理论上,用于识别新兴情况的工具可能具有时间内置的概念,并能提供使用该工具所需的丰富 API。

最后,对未来的准确指示来源于对过去的分析。实际上,这就是传统 BI 的所有功能 - 对大量的历史数据进行汇总和分析,从而识别趋势。遗憾的是,与更多的事务性系统相比,在使用这些系统时需要不同的工具和查询语言。成功识别新兴情况需要实现过去数据和当前数据的无缝关联。只有当对这两种数据使用相同的工具和查询语言时,才可能实现这种紧密集成。

对于生产线监视等特定情况,可通过存在的针对性极强的自定义工具来执行这些功能,但是这些工具通常比较昂贵且用途并不广泛。

为了防止生产线产量下降或确保您的产品定价合适,关键在于具有足够的响应能力,能够根据情况的更改而进行识别与调整。若要轻松快速地识别这些情况,历史查询和实时查询应使用相同的开发人员友好的工具集和查询语言,系统应该以近乎实时的方式来处理大量的数据(大约为每秒成百上千个事件),同时引擎应该足够灵活,能够处理跨越多个问题域的情况。

幸运的是,存在这样的工具。它称为 Microsoft StreamInsight。

StreamInsight 体系结构概述

StreamInsight 是一种复杂事件处理引擎,它每秒能够处理成百上千的事件,且延迟极低。它可以由任何进程(如 Windows 服务)托管,也可以直接嵌入任何应用程序。StreamInsight 具有简单的适配器模型,用于输入和输出数据,并且实时数据和历史数据的查询像任何其他来自任何 Microsoft .NET Framework 语言的程序集一样使用获取的相同 LINQ 语法。其作为 SQL Server 2008 R2 的一部分授予许可。

StreamInsight 的高级体系结构非常简单:通过输入适配器从各种源收集事件。这些事件均通过查询进行分析和转换,并且查询结果通过输出适配器分发给其他系统和人。  图 1 显示了这一简单结构。

利用Microsoft StreamInsight控制较大数据流详解

图 1 Microsoft StreamInsight 高级体系结构

就像面向服务的体系结构关注消息,而数据库系统关注行一样,StreamInsight 等复杂事件处理系统按照事件进行组织。事件是简单的数据段以及与该数据相关的时间 - 与一天中特定时间的传感器读数或股票行情价格相似。事件所携带的数据称为它的负载。

StreamInsight 支持三种类型的事件。点事件是即时且不持续的事件。间隔事件是其负载与特定时间段相关的事件。边缘事件与间隔事件相似,但当边缘事件到达时,其持续时间未知。而系统设置了开始时间,且事件实际上具有无限持续时间,直到另一个边缘事件到达才会为这一事件设置结束时间。例如,速度计读数可能为点事件,因为它不断更改,但是超市的牛奶价格可能为边缘事件,因为其关联时间较长。当牛奶的零售价格更改时(比如,由于分销商定价发生更改),新价格的持续时间未知,因此,与间隔事件相比,边缘事件要更为合适。稍后,当分销商再次更新其定价时,新的边缘事件将覆盖先前定价更改的持续时间,而另一个边缘事件将设置新的价格以便继续。

StreamInsight 中的输入适配器和输出适配器是适配器设计模式的抽象示例。StreamInsight 引擎在其自有的事件表示上运行,但是这些事件的实际来源可能有较大差异,范围从专有接口到硬件传感器到由企业的应用程序生成的状态消息。输入适配器将源事件转换为引擎能够理解的事件流。

来自 StreamInsight 查询的结果表示特定商业知识,且能够高度专业化。将这些结果路由至最合适的地点,这点至关重要。输出适配器可用于将事件的内部表示转换为打印到控制台的文本、通过 Windows Communication Foundation (WCF) 发送到另一个系统以供处理的消息,甚至 Windows Presentation Foundation 应用程序中图表上的点。有关使用文本文件、WCF 和 SQL 等的示例适配器可从 streaminsight.codeplex.com 获得。

StreamInsight Queries by Example

乍一看,StreamInsight 查询似乎与从数据库中查询行相似,但是两者之间存在重大差异。查询数据库时,系统会构造并执行查询,同时返回结果。如果基础数据发生更改,输出并不会因为已运行查询而受影响。数据库查询结果表示某一时刻的快照,可以通过请求-响应模式使用。

StreamInsight 查询为现有查询。随着新输入事件的到达,查询不断响应,并且根据需要创建新的输出事件。

本文中的查询示例来自可供下载的示例解决方案。这些示例开始较简单,但随着查询语言新功能的引入,功能变得更加强大。所有查询都使用同一负载类。以下是一个简单类的定义,该类具有 Region 属性和 Value 属性:

  1.  public class EventPayload  
  2.  {   
  3.    public string Region { get; set; }  
  4.   public double Value { get; set; }  
  5.     public override string ToString()   
  6.    {   
  7.      return string.Format("{0}\t{1:F4}", Region, Value);  
  8.   }  
  9.  } 

示例应用程序中的查询使用一台输入适配器和一台输出适配器来进行,输入适配器可随机生成数据,输出适配器只需将各事件写入控制台。为清晰起见,对示例应用程序中的适配器进行了简化。

若要运行每个查询,请在示例解决方案中取消注释 Program.cs 文件中的行,该示例解决方案可将查询分配给称为“template”的本地变量。

以下是一个基本查询,它通过 Value 属性来筛选事件:

  1. var filtered =  
  2.   from i in inputStream  
  3.   where i.Value > 0.5  
  4.   select i; 

具有使用 LINQ 经验的任何开发人员应该非常熟悉此查询。因为 StreamInsight 使用 LINQ 作为它的查询语言,因此此查询与 LINQ to SQL 查询类似,访问数据库或对 IList 进行内存中筛选。当事件从输入适配器到达时,其负载将受到检查,并且如果 Value 属性的值大于 0.5,事件将被传递到输出适配器,并在此将其打印到控制台。

应用程序运行时,可以看到事件不断到达输出中。这实际上是一个推模型。当事件到达时,StreamInsight 会计算来自输入的新输出事件,这与数据库等拉模型不同,在拉模型中,应用程序必须定期轮询数据源,以查看新数据是否已经到达。这能与 Microsoft .NET Framework 4 中可用的 IObservable 支持完美结合,我们将在后续章节中对此进行介绍。

使用推模型代替轮询来处理连续数据是个非常好的主意,但是 StreamInsight 的真正功能体现在查询时间相关的属性上。当事件通过输入适配器到达时,它们获得了一个时间戳。该时间戳可能来自数据源本身(假设事件表示历史数据,且带有用于存储时间的显示列),或者可以设置为事件到达的时间。实际上,时间是 StreamInsight 查询语言中的第一个类。

查询通常与标准数据库查询类似,标准数据库查询在尾部粘贴有时间限制符,如“每五秒”或“五秒的时间跨度上每三秒”。例如,以下是一个简单查询,它每五秒查询一次 Value 属性的平均值:

  1. var aggregated =  
  2.    from i in inputStream.TumblingWindow(TimeSpan.FromSeconds(5),   
  3.    HoppingWindowOutputPolicy.ClipToWindowEnd)  
  4.    select new { Avg = i.Avg(p => p.Value)}; 

数据窗口

因为时间概念是复杂事件处理系统的基础必需概念,因此应以简单的方式来使用系统中查询逻辑的时间组件,这点非常重要。StreamInsight 使用窗口概念来表示按时间分组。之前的查询使用翻转窗口。应用程序运行时,查询将每五秒生成单个输出事件(窗口的大小)。输出事件表示前五秒的平均值。像 LINQ to SQL 或 LINQ to Object 一样,聚合方法(如 Sum 和 Average)能够将按时间分组的事件汇总为单个值,或可以使用 Select 将输出投影成不同格式。

翻转窗口只是另一种窗口类型的特例:跳跃窗口。跳跃窗口也有大小,但是它们也具有不等于其窗口大小的跳跃大小。这表示跳跃窗口可以互相重叠。

例如,窗口大小为五秒、跳跃大小为三秒的跳跃窗口将每三秒生成输出(跳跃大小),提供前五秒的平均值(窗口大小)。它一次向前跳跃三秒,且持续五秒。图 2 显示分组为翻转窗口和跳跃窗口的事件流。

利用Microsoft StreamInsight控制较大数据流详解

图 2 翻转窗口和跳跃窗口

请注意,翻转窗口并不重叠,但是对于跳跃窗口,如果跳跃大小小于窗口大小,则可以重叠。如果窗口重叠,事件将可能在多个窗口中结束,如同时存在于窗口 1 和窗口 2 中的第三个事件。边缘事件(具有持续时间)也可能在窗口边缘重叠,并在多个窗口中结束,如翻转窗口中的倒数第二个事件。

另一种常见窗口类型为计数窗口。计数窗口包含特定数量的事件,而不是某一时间点或时间段内的事件。要查询最后三个到达的事件的平均数,可能需要使用计数窗口。计数窗口当前的一个限制是不支持 Sum 和 Average 等内置聚合方法。您必须创建用户定义的聚合。下文会对这一简单流程进行介绍。

最后一种窗口类型为快照窗口。在边缘事件的环境下,快照窗口最容易理解。每次事件的开始或结束即表示当前窗口的完成和新窗口的开始。图 3 显示如何将边缘事件分组为快照窗口。请注意每个事件边界触发窗口边界的方式。E1 开始,w1 也开始。当 E2 开始时,w1 完成,而 w2 开始。下个边缘是 E1 结束,使得 w2 完成,而 w3 开始。结果为三个窗口:包含 E1 的 w1,包含 E1 和 E2 的 w2 以及包含 E3 的 w3。事件分组为窗口后,它们会受到拉伸,从而使事件的开始与结束时间与窗口的相同。

利用Microsoft StreamInsight控制较大数据流详解

图 3 快照窗口

更多复杂查询

在提供可用窗口与基本查询方法(如地点、分组依据和排序依据)的情况下,可以进行多种查询。以下是一个查询,其将输入事件按地区分组,然后使用跳跃窗口来输出最后一分钟各个 Region 的负载 Value 的总和:

  1. var payloadByRegion =   
  2.    from i in inputStream   
  3.    group i by i.Region into byRegion   
  4. from c in byRegion.HoppingWindow(   
  5.   TimeSpan.FromMinutes(1),  
  6.   TimeSpan.FromSeconds(2),   
  7.    HoppingWindowOutputPolicy.ClipToWindowEnd)  
  8.    select new {  
  9.   Region = byRegion.Key,   
  10.   Sum = c.Sum(p => p.Value)}; 

这些窗口使用两秒的跳跃大小,因此引擎每两秒发送输出事件。

因为查询运算符是在 IQueryable 接口中定义的,因此可以撰写查询。以下代码使用上一个查询,其按地区查找总和,并计算总和最高的地区。快照窗口允许事件流按总和分类,因此可以使用 Take 方法获取总和最高的地区:

  1. var highestRegion =   
  2.  // Uses groupBy query   
  3.    (from i in payloadByRegion.SnapshotWindow(  
  4.    SnapshotWindowOutputPolicy.Clip)  
  5.     from sumByRegion in i  
  6.    orderby sumByRegion.Sum descending  
  7.    select sumByRegion).Take(1); 

一般情况是有关快速移动事件(如传感器中的读数)到慢速移动或静态参考数据(如传感器的固定位置)流的查询。查询使用联接来实现此目的。

StreamInsight 联接语法与任何其他 LINQ 联接相同,但有一点需要注意:当事件的持续时间重叠时,它们才会联接在一起。如果传感器 1 在时间 t1 报告了一个值,但是有关传感器 1 位置的参考数据仅对时间 t2 到 t3 有效,那么联接将不匹配。持续时间的联接条件并没有明确写入查询定义中;这是 StreamInsight 引擎的基本属性。使用静态数据时,通常情况下,输入适配器实际上将数据处理为带有无限持续时间的边缘事件。这样将能成功完成到快速移动事件流的所有联接。

通过联接来关联多个事件流是一个非常强大的概念。装配线、石油生产设施或高容量网站通常不会因为隔离的事件而发生故障。一个用于触发温度警报的设备部件通常不会导致生产线瘫痪;生产线瘫痪可能由于多个原因造成,如温度在某一持续时间段内过高,同时某一工具使用过多,而操作员正在换班。

如果没有联接,隔离事件将不会有这么多的商业价值。通过对历史数据使用联接和 StreamInsight 查询,用户可以将隔离流与非常具体的监控条件相关联,然后进行实时监控。现有查询能够查找可能导致故障的情况,并自动生成可路由至系统的输出事件,该系统知道如何使过热的设备部件脱机,而不是等到该部件造成整条生产线停产。

在零售情况中,有关某段时间按项目划分的销售量的事件可以输入到定价系统和客户订单历史记录中,从而确保每个项目具有最佳的定价,或决定在用户结账前向其推荐的项目。由于查询易于创建、修改和撰写,因此您可以从简单的情况开始,并随时间的流逝进行优化,从而增加业务价值。

用户定义的聚合

StreamInsight 附带最常见的聚合函数,包括 Count、Sum 和 Average。当这些函数不够时(或您需要在前文提到的计数窗口进行聚合),StreamInsight 支持用户定义的聚合函数。

要创建用户定义的聚合,其流程包括两个步骤:编写实际聚合方法,然后通过扩展方法将该方法公布到 LINQ。

进行第一步时,如果聚合与时间无关,则从 CepAggregate<TInput, TOutput> 继承,如果聚合与时间有关,则从 CepTimeSensitiveAggregate<TInput,TOutput> 继承。这些抽象类具有单独的实现方法,称为 GenerateOutput。

  1.  public class EveryOtherSum :  
  2.    CepAggregate<double, double> {  
  3.      public override double GenerateOutput(  
  4.        IEnumerable<double> payloads) {  
  5.          var sum = default(double);  
  6.          var include = true;  
  7.          foreach (var d in payloads) {  
  8.            if (include) sum += d;  
  9.           include = !include;  
  10.          }  
  11.          return sum;  
  12.        }  
  13.     } 

进行第二步时,需要在 CepWindow<TPayload> 上创建扩展方法,以便可以在查询中使用您的聚合。CepUserDefinedAggregateAttribute 适用于扩展方法,以便通知 StreamInsight 在哪里可以找到聚合的实现(在这种情况下,类是在第一步中创建的)。在可下载的示例应用程序中,本流程两个步骤的代码均可在 EveryOtherSum.cs 文件中找到。

关于利用Microsoft StreamInsight控制较大数据流的相关知识就介绍到这里了,希望本次的介绍能够对您有所收获!

【编辑推荐】

  1. 初学SQL Server数据库的一些常用操作总结
  2. SQL Server数据库创建数据仓库已分区表详解
  3. SQL Server与Access数据库ASP代码的比较详解
  4. SQL Server数据库中bit字段类型使用时的注意事项
  5. SQL Server数据库timestamp数据类型相关知识介绍
责任编辑:赵鹏 来源: 博客园
相关推荐

2009-08-19 10:41:12

Java输入数据流

2019-06-18 13:51:08

大数据流处理新兴市场

2019-07-05 12:16:26

大数据IT互联网

2016-11-08 11:07:07

大数据流StreamSets

2023-11-13 11:01:25

数据技术

2014-11-11 10:47:19

hadoop数据流

2011-12-14 15:57:13

javanio

2022-03-18 08:57:17

前端数据流选型

2016-11-14 19:01:36

数据流聊天系统web

2023-08-18 09:29:59

Java数据流

2009-04-13 16:35:25

TSQL查询SQL Server

2020-04-14 15:18:16

SparkFlink框架

2013-10-21 10:58:50

微软大数据SQL Server

2017-11-16 19:26:34

海量数据算法计算机

2021-10-27 10:43:36

数据流中位数偶数

2009-07-15 09:06:11

Linux图形系统X11的CS架构

2014-02-11 08:51:15

亚马逊PaaSAppStream

2010-02-22 17:51:46

WCF传较大数据

2011-04-14 14:43:38

SSISTransformat

2009-02-05 10:13:00

局域网流量控制数据流量
点赞
收藏

51CTO技术栈公众号