搭建沟通BI与SOA的桥梁

简介

我们都知道商业智能(Business Intelligence,BI)能给组织带来许多优势。通过整理、聚集和分析数据,BI能帮助我们洞悉组织内正在发生的事情,以及将要发生的事情。BI让我们识别出组织前进的方向或者应该前进的方向。BI的过程通常从提取、转换和加载数据(Extract、Transform、Load,ETL)开始。一般来说,ETL是数据仓库(Data Warehouse)中的一个过程,其中包括:

  • 从外部和内部数据源提取数据。
  • 转换数据以符合业务的需要。
  • 将转换后的数据加载到数据仓库(或者数据集市,Data Mart)

基本上,我们要达到BI的圆满境界,“只”需要一样东西:数据。BI需要隐藏在组织系统中的数据。

走进SOA

在过去的数年间,我们已经看到了面向服务架构(Service-Oriented Architecture,SOA)在IT架构前沿的进步。随着夸大的宣传渐渐平息,而各个组织逐渐完成向SOA的过渡,突然之间人们发现BI所需的数据被分散到了各个服务之中,被隐藏到了各种接口契约之后。

请看图1所示的SOA组件(来自我的论文《到底什么是SOA?》),我们可以看到除了最主要的组件——服务——之外,SOA还有若干与服务接口相关的其它组件:

  • 契约,服务所实现的契约
  • 端点,与服务建立联系的所在
  • 消息,在服务与其用户之间来回传递的消息
  • 策略,服务遵循的策略
  • 用户,与服务交互的用户

这些组件,以及SOA的“共享数据定义(Scheme)而非数据”和“服务应当是自治的”等信条,都告诉我们SOA对其接口的重视。正是通过这种对严密定义的接口通信的强调,给SOA在松耦合、灵活性和敏捷性等方面带来了技术和业务上的优势。

搭建沟通BI与SOA的桥梁_第1张图片

图1:SOA组件及其关系

一方面BI着力在对数据的深入理解,另一方面SOA着力在将内部数据隔离到接口之后,目标冲突是真实存在的。正如Pat Helland在《外部数据vs.内部数据》中所说,服务的内部数据绝不应该暴露到服务的外部,而这些数据正是BI所需要的。正是出于这个原因,根据最近Ventana Research 进行的一项调查(由Dan Everett在Dr. Dobb's Journal上发表),只有1/3的调查对象认为他们的内部IT人员有知识和能力去实现BI服务,这个结果并不令我们感到惊讶。

我们似乎面对两个选项:要么直接获得数据而无视某些SOA原则(比如“共享数据定义而非数据”),要么遵循眼前的接口契约而盲目地期望BI能获得足够的数据。(第三个选项则跟第一个选项等效,我稍后会讨论到,即创建特定于BI需要的契约。)

直接获取数据,或者……

第一个选项是直接获取BI所需的数据,其过程则按照过去已经充分证明有效的ETL。

SOA给ETL带来了一点挑战,你必须从许多分散的位置(服务)将数据集中起来。不过,从多个资源中汇集数据对BI或者ETL来说都不是什么新问题。大企业中已经存在许多数据源:ERP、CRM、分散在各个部门的数据竖井(data silos),诸如此类。有了SOA,ETL反而可能更容易,如果考虑到SOA承诺把企业数据编织成高内聚的组织结构,而不是意大利面条式的点对点集成。(请注意“承诺”这个词,事实上要达到高内聚的服务组织结构不是一件容易的事。不过这是题外话了,这个问题要用另一篇文章甚至一本书才能解释清楚。)

前面我已经说过,ETL已经很成熟,也已经被证明是成功构建BI解决方案的基础。然而,使用ETL基本上就意味着抹杀大部分当初让我们追寻SOA的那些好处。在SOA史前时代,我们面对的主要问题(在许多组织中这个问题仍然存在)之一是,企业系统的意大利面条式集成。请考虑图2所示的情形。由于历史的原因,每个部门都建立了自己的系统。随着新的业务需求的显现,其结果就是一堆各自为营的、条块分割的系统。然后,当系统间需要共享数据时,就加入新的点对点的接口来解决系统集成的需要。随着人们使用系统,他们发现自己需要另一个系统的数据,结果又是一个点对点的集成。图2展示了四种类型的点对点集成:ETL(提取、转换和加载),这是一种数据库间的关系;线上集成和基于文件的集成,两者都是应用间的关系;到数据库的直接连接,这是应用到数据库的关系。这里列举的关系并不完整;还存在更多的关系类型,如复制(replication)、基于消息的关系等等,都没有在图2中表示出来。

最终的结果就是意大利面条式的系统。对一个系统的改动会波及到其他系统,其结果是不可预测的。SOA强调通用的接口和自治性就是为了解决这些问题。

搭建沟通BI与SOA的桥梁_第2张图片

图2:典型的意大利面条式企业系统集成

把ETL作为获取服务数据的直接管道就等于加入了一个新的点对点接口——这就破坏了SOA的“接口防御机制”,并在BI与服务间引入了依赖关系。同时也为其他绕过SOA契约的做法打开了大门。(如果BI可以这样做,为什么其他应用、服务或系统不可以这样做?)

实行ETL的一个变通做法可以先将SOA数据复制到一个外部的数据库,然后对这些复制的数据进行ETL。然而,这跟直接对服务的数据库进行ETL并没有什么两样,我们仍然绕过了SOA的契约,我们仍然和内部数据的结构耦合到了一起。

好吧,使用ETL可能并不是最好的方案。让我们试试第二个选项,看按照SOA的原则运用契约来集成BI和SOA结果如何。

抽取SOA数据(请求/响应)

集成SOA和BI的最简单的方案是不为BI过程做任何特殊的调整。如果我们采用契约,那些按照SOA的基本精神而拟就的契约,结果又会如何呢?为了满足BI的需求,我们需要周期性地轮询服务的接口,以便能够获得趋势性的和有历史意义的数据。

这种方法大致有两个问题。其一是网络带宽的问题。轮询我们需要的每个接口会产生非常大的数据流量。要解决这个问题,我们可能要增大轮询的时间间隔。然而,这样做会导致我们遇到第二个问题:我们面临着错失在轮询间隔期间发生的重要事件的风险。就好像我们在早晨和傍晚观察天空,而完全错过了在中午发生的日食。因此,不幸地,这种方法虽然聊胜于无,但看起来并不是特别有前途。

采用SOA契约的另一种方式是为BI的需要定制特殊的契约;也就是说,让契约允许从服务的内部结构中获取数据,以供BI使用。不过,这跟使用标准的ETL基本上是一回事;你仍然建立了一个点对点的集成,并为特殊用途的特殊契约树立了一个先例。

现在的情况看起来不太乐观。我们发现自己陷进了前有狼后有虎的一个处境;要么我们放弃一些SOA的原则和优点,要么我们屈就一个不好的BI方案。

嘿,等一下:可能还有第三条路……

转变SOA思路:转向“推”模型(Push Model)

第三个选项的基础是将SOA向前推进,超越我们习惯的简单的请求/响应模型,将SOA与另一种架构风格——事件驱动的架构(Event-Driven Architecture,EDA)相结合。

简而言之,EDA跟SOA类似,是一种建立在“推”模型上的架构风格。EDA组件向外发布事件。从逻辑上说,事件是发布该事件的组件中发生的任何值得注意的变化。该变化可以是正常行为的结果,比如一份订单已被处理;也可以是一个错误,比如数据库宕机;也可以是系统超过了一个阈值,比如第一百万名顾客做出购买行为;或者任何你认为重要的事情。从物理上来说,事件是带有描述该事件的元数据的头部和包含事件内容的正文的一个消息。

一旦事件被产生,就被传播到订阅了该事件的组件。在处理了该事件之后,这些组件也可以产生新的事件,以此类推。以航空公司为例,事件可以是一份航班延误的通知。这个事件会触发另一个负责转机的组件,试图为延误航班上的旅客寻找候补航班。(是是,如果真的有就好了。)相较于其他推技术,EDA独具的特色是它的事件流处理(Event Stream Processing,ESP)和复杂事件处理(Complex Event Processing,CEP)的概念。我们将事件看作是相互关联的链条,而不是一个个孤立的。通过观察事件链——或者更进一步,观察结合在一起的若干事件链(即事件云)——我们可以做到在时间上的追溯分析,以及其他对事件模式的高级分析。

EDA的运用可以独立于SOA;但融合两者可以带来更多的好处。

当SOA遇上EDA

如果我们把消息发布加入到契约会怎么样?“发布消息”的意思是服务将其状态发布给任何监听者,可以是周期性地,也可以是每个事件都发布。我喜欢将这种服务通讯模式叫做“通讯倒置(Inversion of Communications)”,因为它反转了SOA通常的请求/响应的通讯模式。看上去好像这种方式的网络负载跟服务轮询差不多,但实际上要少很多。另一方面,当采用通讯倒置时,关注服务的每个消费者每个事件最多只会得到一次,而轮询时消费者会多次得到状态变化的信息(或者错过该数据)。

为了使方案完整,你可以增加额外的请求/响应或者请求/反应消息,让服务的消费者能够获得初始的快照。通过这种方式,你获得了服务内部变化的一个事件流,而且这种方式并不是专门针对BI的。实际上,让其他服务也对事件流作反应可以降低系统整体的耦合程度;比如,你可以缓存其他服务的状态,从而减轻服务间的临时耦合。而且,通过实现汇总报告模式(Aggregated-Reporting Pattern),将EDA加入SOA可以作为解决SOA的报告问题的基础。

EDA加上SOA解决了BI的问题;只要你在网络中准备好了事件流,BI组件就可以抓取数据,按照它们的需要操纵数据,将数据塞进它们的数据集市或者数据仓库。而且,数据流还可以让BI更上一层楼,数据流让BI得以对实时事件和实时的趋向性数据进行更复杂更有意义的分析,并运用复杂事件处理(CEP)工具取得实时的业务活动监控(Business-Activity Monitoring,BAM)。事件处理到底是什么样子的呢?想象你有一个订单服务,它发布的事件以XML的形式描述了她所处理的每个订单,如列表1所示:

<ORDER ID="1234-5679"
OrderDate="2007-04-02T00:00:00"
DueDate="2007-05-15T00:00:00">
<OrderLine SKU="ipdshfl-123" ProductName="Apple 1 GB iPod Shuffle
AAC/MP3 Player - Metal (2nd Generation)" Price="85.99" Quantity="4"/>
<OrderLine SKU="mszn-456" ProductName="Zune 30GB MP3 / Video Player
- Black" Price="245.99" Quantity="2"/>
</ORDER>

列表1:订单汇总的XML片断

我们可以用ESP或CEP工具来监控这个事件流,并持续从中抽取感兴趣的事件供进一步分析和行动。例如,列表2展示了一个查询,该查询用来在订单流中查找超过$100,000的订单。请注意,虽然这个查询看起来非常像是SQL(确实是从SQL发展而来),它仍然有相当不一样的地方;该查询不间断地对一个非持久化(non-persistent)的事件流进行操作。

 INSERT INTO LargeOrders
SELECT
orderid as orderid,
SUM(Ords.price * Ords.qty) AS TotalValue,

FROM
OrdersStream AS Ords XMLTable (val
ROWS '//OrderLine'
COLUMNS
Orderid as orderid,
TO_FLOAT (XMLExtractValue ('@Price')) AS price,
TO_FLOAT (XMLExtractValue ('@Quantity')) AS qty );
WHERE
TotalCost>100000

列表2:Coral8的持续计算语言(Continuous Computation Language)查询,用来从订单流中查找超过$100,000的订单,并将其插入LargeOrders数据表

CEP工具要迈向主流仍然有很长的路要走,不过已经有一些厂商在实现这方面的解决方案。即便我们不使用CEP,我们仍然能够从访问这些事件流中获得许多好处。例如,数据仓库中的一个库存管理服务可以监听订单服务的订单处理事件流,从而快速妥当地完成订购新库存,管理现有货物的工作。

当我们用EDA加SOA来构建BI,基本上我们是将BI作为服务的Mash-up来构建。我们可以更进一步,让BI组件将它的趋势数据或者其他分析结果作为服务暴露出来。这样我们就可以在其他应用中使用这些数据。比如,如果我们让列表2的CEP查询每当遇到超过$100,000的订单都生成一个事件,我们就可以在CEO的门户上显示一个漂亮的面板,上面实时显示了组织中每小时或每天处理了多少个大订单,以及其他类似的有意义的图表。

图3:用Mash-up的形式显示BI

不过,我们还没有回答一个问题:我们的服务如何产生这些事件?

请求/响应模型怎么了?

从实现的角度来看,我们可以看到所需的基础设施已经出现或者已经存在。如果你在ESB的基础上实现SOA,实现是很简单的,因为大多数ESB都直接支持事件的发布。在WS-*协议栈中,你可以采用WS-BaseNotification、WS-BrokeredNotification、WS-Topic等一整套标准。

如果你是在REST的阵营,或者不想被前述相对不成熟的WS协议的复杂性所困扰,我想你需要自行实现发布/订阅模型。不过,这个问题也已经被解决了:就是RSS。当某人在他的博客上发表文章,你的RSS阅读器通过同步的请求/响应模型访问该博客,并获取自上次请求后增加的新文章。怎么样,不错吧:RSS给了我们松耦合的发布/订阅模型,以及主题(分类),而且都是建立在同步请求/响应模型的基础上的。

你的服务可以用feed的方式来发布事件流,就跟你的博客一样,同时还获得了一些架构上的好处。比如说,服务不需要再管理订阅者。第二,当事件发生时消费者不必在场也可以消费该事件。而且,管理和配置比起队列引擎或者任何我能想到的技术都要简单容易。

结论

结合运用EDA和SOA给了我们一个不必打破SOA原则同时又能满足BI需求的解决方案。不过,结合EDA和SOA的方法面临两个困难。其一是用EDA和SOA来解决BI问题还没有很多实践经验(跟久经考验的ETL相比)。其二是这种方式需要做更多的工作甚至重做,因为第一波的SOA实现是建立在更简单的同步消息方式的基础上。在现有的SOA方案上加入EDA不是一件简单的工作。不过,在SOA中采用ETL也同样不简单,因为我们需要从许多来源抽取数据,而每个服务都有自己的内部数据,并且对任何普通大小的SOA方案来说,服务的数目都不会少。

我的观点是,几乎从任何方面看,EDA和SOA都要胜过采用ETL。

从SOA的角度来看,在SOA中加入EDA对整个SOA方案都有好处。EDA对于建立更加自治的服务来说是一件有价值的工具。例如,服务可以缓存从其他服务中获得的相关数据,并在数据变更时得到通知。因此,作为消费者的服务可以从时间上与它所依赖的服务解耦,它不再依赖其它服务的可用性——当采用同步的请求/响应模型时就要面临这个问题。

从BI的角度来看,好处就更多了。利用EDA可以让我们获得传统BI机制难以达到的目标——实时的洞察力。运用EDA产生的事件流,我们现在可以实时地获得数据,并且通过CEP工具,我们可以实时地处理数据,并在趋势浮现时实时地采取行动。

总而言之,采用EDA和SOA来实现BI胜过采用传统的ETL。我们不光能得到基本的BI,我们还可以做得更好——实时BI,更不用说对SOA整体质量的提高了。

关于作者

Arnon Rotem-Gal-Oz是一位经理和架构师,他对在各种平台(从HP-UX、Solaris到AS400和Windows)上构建大型、复杂的分布式系统有着非常丰富的经验。Arnon的博客在www.rgoarchitects.com/blog,他还在Dr. Dobb's Portal撰写软件架构和设计方面的内容,请见www.ddj.com/dept/architect。你可以通过[email protected]联系Arnon。

查看英文原文: Bridging the gap between BI & SOA

你可能感兴趣的:(搭建沟通BI与SOA的桥梁)