前言
互联网的飞速发展促进了很多新媒体的发展,不论是知名的大V,明星还是围观群众都可以通过手机在微博,朋友圈或者点评网站上发表状态,分享自己的所见所想,使得“人人都有了麦克风”。不论是热点新闻还是娱乐八卦,传播速度远超我们的想象。可以在短短数分钟内,有数万计转发,数百万的阅读。如此海量的资讯可以得到爆炸式的传播,如何能够实时的把握民情并作出对应的处理对很多企业来说都是至关重要的。大资料时代,除了媒体资讯以外,商品在各类电商平台的订单量,使用者的购买评论也都对后续的消费者产生很大的影响。商家的产品设计者需要汇总统计和分析各类平台的资料做为依据,决定后续的产品发展,公司的公关和市场部门也需要根据舆情作出相应的及时处理,而这一切也意味着传统的舆情系统升级成为大资料舆情采集和分析系统。
分析完舆情场景后,我们再来具体细化看下大资料舆情系统,对我们的资料储存和计算系统提出哪些需求:
海量原始资料的实时入库:为了实现一整套舆情系统,需要有上游原始输出的采集,也就是爬虫系统。爬虫需要采集各类门户,自媒体的网页内容。在抓取前需要去重,抓取后还需要分析提取,例如进行子网页的抓取。
原始网页资料的处理:不论是主流门户还是自媒体的网页资讯,抓取后我们需要做一定的资料提取,把原始的网页内容转化为结构化资料,例如文章的标题,摘要等,如果是商品点评类讯息也需要提取有效的点评。
结构化资料的舆情分析:当各类原始输出变成结构化的资料后,我们需要有一个实时的计算产品把各类输出做合理的分类,进一步对分类后的内容进行情感打标。根据业务的需求这里可能会产生不同的输出,例如品牌当下是否有热点话题,舆情影响力分析,转播路径分析,参与使用者统计和画像,舆论情感分析或者是否有重大预警。
舆情分析系统中间和结果资料的储存,互动分析查询:从网页原始资料清洗到最终的舆情报表这中间会产生很多型别的资料。这些资料有的会提供给资料分析同学进行舆情分析系统的调优,有的资料会提供给业务部门根据舆情结果进行决策。这些查询可能会很灵活,需要我们的储存系统具备全文检索,多字段组合灵活的互动分析能力。
重大舆情事件的实时预警:对于舆情的结果除了正常的搜寻和展示需求以外,当有重大事件出现我们需要能做到实时的预警。
我们计划分两篇介绍完整的舆情新架构,第一篇主要是提供架构设计,会先介绍时下主流的大资料计算架构,并分析一些优缺点,然后引入舆情大资料架构。第二篇会有完整的数据库表设计和部分示例程式码。大家敬请期待。
系统设计
需求分析
结合文章开头对舆情系统的描述,海量大资料舆情分析系统流程图大体如下:

图1 舆情系统业务流程
原始网页储存库,这个库需要能支援海量资料,低成本,低延时写入。网页资料写入后,要做实时结构化提取,提取出来的资料再进行降噪,分词,图片ocr处理等。对分词文字,图片进行情感识别产生舆情资料结果集。传统的离线全量计算很难满足舆情系统的时效性需求。
计算引擎在做资料处理时,可能还需要从储存库中获取一些元资料,例如使用者资讯,情感词元资料资讯等。
除了实时的计算链路,对存量资料定期要做一些聚类,优化我们的情感词识别库,或者上游根据业务需要触发情感处理规则更新,根据新的情感打标库对存量资料做一次舆情计算。
舆情的结果资料集有不同类的使用需求。对于重大舆情,需要做实时的预警。完整的舆情结果资料展示层需要支援全文检索,灵活的属性字段组合查询。业务上可能根据属性字段中的置信度,舆情时间,或者关键词组合进行分析。
根据前面的介绍,舆情大资料分析系统需要两类计算,一类是实时计算包括海量网页内容实时抽取,情感词分析并进行网页舆情结果储存。另一类是离线计算,系统需要对历史资料进行回溯,结合人工标注等方式优化情感词库,对一些实时计算的结果进行矫正等。所以在系统设计上,需要选择一套既可以做实时计算又能做批量离线计算的系统。在开源大资料解决方案中,Lambda架构恰好可以满足这些需求,下面我们来介绍下Lambda的架构。
Lambda架构 (wiki)

图2 Lambda架构图
Lambda架构可以说是Hadoop,Spark体系下最火的大资料架构。这套架构的最大优势就是在支援海量资料批量计算处理(也就是离线处理)同时也支援流式的实时处理(即热资料处理)。
具体是如何实现的呢,首先上游一般是一个伫列服务例如kafka,实时储存资料的写入。kafka伫列会有两个订阅者,一个是全量资料即图片中上半部分,全量资料会被储存在类似HDFS这样的储存介质上。当有离线计算任务到来,计算资源(例如Hadoop)会访问储存系统上的全量资料,进行全量批计算的处理逻辑。经过map/reduce环节后全量的结果会被写入一个结构化的储存引擎例如Hbase中,提供给业务方查询。伫列的另一个消费订阅方是流计算引擎,流计算引擎往往会实时的消费伫列中的资料进行计算处理,例如Spark Streaming实时订阅Kafka的资料,流计算结果也会写入一个结构化资料引擎。批量计算和流计算的结果写入的结构化储存引擎即上图标注3的Serving Layer,这一层主要提供结果资料的展示和查询。
在这套架构中,批量计算的特点是需要支援处理海量的资料,并根据业务的需求,关联一些其他业务指标进行计算。批量计算的好处是计算逻辑可以根据业务需求灵活调整,同时计算结果可以反复重算,同样的计算逻辑多次计算结果不会改变。批量计算的缺点是计算周期相对较长,很难满足实时出结果的需求,所以随着大资料计算的演进,提出了实时计算的需求。实时计算在Lambda架构中是通过实时资料流来实现,相比批处理,资料增量流的处理方式决定了资料往往是最近新产生的资料,也就是热资料。正因为热资料这一特点,流计算可以满足业务对计算的低延时需求,例如在舆情分析系统中,我们往往希望舆情资讯可以在网页抓取下来后,分钟级别拿到计算结果,给业务方充足的时间进行舆情反馈。下面我们就来具体看一下,基于Lambda架构的思想如何实现一套完整的舆情大资料架构。
开源舆情大资料方案
通过这个流程图,让我们了解了整个舆情系统的建设过程中,需要经过不同的储存和计算系统。对资料的组织和查询有不同的需求。在业界基于开源的大资料系统并结合Lambda架构,整套系统可以设计如下:

图3 开源舆情架构图
系统的最上游是分散式的爬虫引擎,根据抓取任务抓取订阅的网页原文内容。爬虫会把抓取到的网页内容实时写入Kafka伫列,进入Kafka伫列的资料根据前面描述的计算需求,会实时流入流计算引擎(例如Spark或者Flink),也会持久化储存在Hbase,进行全量资料的储存。全量网页的储存可以满足网页爬取去重,批量离线计算的需求。
流计算会对原始网页进行结构化提取,将非结构化网页内容转化为结构资料并进行分词,例如提取出网页的标题,作者,摘要等,对正文和摘要内容进行分词。提取和分词结果会写回Hbase。结构化提取和分词后,流计算引擎会结合情感词库进行网页情感分析,判断是否有舆情产生。
流计算引擎分析的舆情结果储存Mysql或者Hbase数据库中,为了方便结果集的搜寻检视,需要把资料同步到一个搜索引擎例如Elasticsearch,方便进行属性字段的组合查询。如果是重大的舆情时间,需要写入Kafka伫列触发舆情报警。
全量的结构化资料会定期通过Spark系统进行离线计算,更新情感词库或者接受新的计算策略重新计算历史资料修正实时计算的结果。
开源架构分析
上面的舆情大资料架构,通过Kafka对接流计算,Hbase对接批计算来实现Lambda架构中的“batch view”和“real-time view”,整套架构还是比较清晰的,可以很好的满足线上和离线两类计算需求。但是把这一套系统应用在生产并不是一件容易的事情,主要有下面一些原因。
整套架构涉及到非常多的储存和计算系统包括:Kafka,Hbase,Spark,Flink,Elasticsearch。资料会在不同的储存和计算系统中流动,运维好整套架构中的每一个开源产品都是一个很大的挑战。任何一个产品或者是产品间的通道出现故障,对整个舆情分析结果的时效性都会产生影响。
为了实现批计算和流计算,原始的网页需要分别储存在Kafka和Hbase中,离线计算是消费hbase中的资料,流计算消费Kafka的资料,这样会带来储存资源的冗余,同时也导致需要维护两套计算逻辑,计算程式码开发和维护成本也会上升。
舆情的计算结果储存在Mysql或者Hbase,为了丰富组合查询语句,需要把资料同步构建到Elasticsearch中。查询的时候可能需要组合Mysql和Elasticsearch的查询结果。这里没有跳过数据库,直接把结果资料写入Elasticsearch这类搜寻系统,是因为搜寻系统的资料实时写入能力和资料可靠性不如数据库,业界通常是把数据库和搜寻系统整合,整合下的系统兼备了数据库和搜寻系统的优势,但是两个引擎之间资料的同步和跨系统查询对运维和开发带来很多额外的成本。
新的大资料架构Lambda plus
通过前面的分析,相信大家都会有一个疑问,有没有简化的的大资料架构,在可以满足Lambda对计算需求的假设,又能减少储存计算以及模组的个数呢。Linkedin的Jay Kreps提出了Kappa架构,关于Lambda和Kappa的对比可以参考云上大资料方案这篇,这里不展开详细对比,简单说下,Kappa为了简化两份储存,取消了全量的资料储存库,通过在Kafka保留更长日志,当有回溯重新计算需求到来时,重新从伫列的头部开始订阅资料,再一次用流的方式处理Kafka伫列中储存的所有资料。这样设计的好处是解决了需要维护两份储存和两套计算逻辑的痛点,美中不足的地方是伫列可以保留的历史资料毕竟有限,难以做到无时间限制的回溯。分析到这里,我们沿着Kappa针对Lambda的改进思路,向前多思考一些:假如有一个储存引擎,既满足数据库可以高效的写入和随机查询,又能像伫列服务,满足先进先出,是不是就可以把Lambda和Kappa架构揉合在一起,打造一个Lambda plus架构呢?
新架构在Lambda的基础上可以提升以下几点:
在支援流计算和批计算的同时,让计算逻辑可以复用,实现“一套程式码两类需求”。
统一历史资料全量和线上实时增量资料的储存,实现“一份储存两类计算”。
为了方便舆情结果查询需求,“batch view”和“real-time view”储存在既可以支援高吞吐的实时写入,也可以支援多字段组合搜寻和全文检索。
总结起来就是整套新架构的核心是解决储存的问题,以及如何灵活的对接计算。我们希望整套方案是类似下面的架构:

图4 Lambda Plus架构
资料流实时写入一个分散式的数据库,借助于数据库查询能力,全量资料可以轻松的对接批量计算系统进行离线处理。
数据库通过数据库日志界面,支援增量读取,实现对接流计算引擎进行实时计算。
批计算和流计算的结果写回分散式数据库,分散式数据库提供丰富的查询语意,实现计算结果的互动式查询。
整套架构中,储存层面通过结合数据库主表资料和数据库日志来取代大资料架构中的伫列服务,计算系统选取天然支援批和流的计算引擎例如Flink或者Spark。这样一来,我们既可以像Lambda进行无限制的历史资料回溯,又可以像Kappa架构一样一套逻辑,储存处理两类计算任务。这样的一套架构我们取名为“Lambda plus”,下面就详细展开如何在阿里云上打造这样的一套大资料架构。
云上舆情系统架构
在阿里云众多储存和计算产品中,贴合上述大资料架构的需求,我们选用两款产品来实现整套舆情大资料系统。储存层面使用阿里云自研的分散式多模型数据库Tablestore,计算层选用Blink来实现流批一体计算。

图5 云上舆情大资料架构
这套架构在储存层面,全部基于Tablestore,一个数据库解决不同储存需求,根据之前舆情系统的介绍,网页爬虫资料在系统流动中会有四个阶段分别是原始网页内容,网页结构化资料,分析规则元资料和舆情结果,舆情结果索引。我们利用Tablestore宽行和schema free的特性,合并原始网页和网页结构化资料成一张网页资料。网页资料表和计算系统通过Tablestore新功能通道服务进行对接。通道服务基于数据库日志,资料的组织结构按照资料的写入顺序进行储存,正是这一特性,赋能数据库具备了伫列流式消费能力。使得储存引擎既可以具备数据库的随机访问,也可以具备伫列的按照写入顺序访问,这也就满足我们上面提到整合Lambda和kappa架构的需求。分析规则元资料表由分析规则,情感词库组层,对应实时计算中的维表。
计算系统这里选用阿里云实时流计算产品Blink,Blink是一款支援流计算和批计算一体的实时计算产品。并且类似Tablestore可以很容易的做到分散式水平扩充套件,让计算资源随着业务资料增长弹性扩容。使用Tablestore + Blink的优势有以下几点:
Tablestore已经深度和Blink进行整合,支援源表,维表和目的表,业务无需为资料流动开发程式码。
整套架构大幅降低组建个数,从开源产品的6~7个组建减少到2个,Tablestore和Blink都是全托管0运维的产品,并且都能做到很好的水平弹性,业务峰值扩充套件无压力,使得大资料架构的运维成本大幅降低。
业务方只需要关注资料的处理部分逻辑,和Tablestore的互动逻辑都已经整合在Blink中。
开源方案中,如果数据库源希望对接实时计算,还需要双写一个伫列,让流计算引擎消费伫列中的资料。我们的架构中数据库既作为资料表,又是伫列通道可以实时增量资料消费。大大简化了架构的开发和使用成本。
流批一体,在舆情系统中实时性是至关重要的,所以我们需要一个实时计算引擎,而Blink除了实时计算以外,也支援批处理Tablestore的资料, 在业务低峰期,往往也需要批量处理一些资料并作为反馈结果写回Tablestore,例如情感分析反馈等。那么一套架构既可以支援流处理又可以支援批处理是再好不过。
整个计算流程会产生实时的舆情计算结果。重大舆情事件的预警,通过Tablestore和函式计算触发器对接来实现。Tablestore和函式计算做了增量资料的无缝对接,通过结果表写入事件,可以轻松的通过函式计算触发简讯或者邮件通知。完整的舆情分析结果和展示搜寻利用了Tablestore的新功能多元索引,彻底解决了开源Hbase+Solr多引擎的痛点:
运维复杂,需要有运维hbase和solr两套系统的能力,同时还需要维护资料同步的链路。
Solr资料一致性不如Hbase,在Hbase和Solr资料语意并不是完全一致,加上Solr/Elasticsearch在资料一致性很难做到像数据库那么严格。在一些极端情况下会出现资料不一致的问题,开源方案也很难做到跨系统的一致性比对。
查询界面需要维护两套API,需要同时使用Hbase client和Solr client,索引中没有的字段需要主动反查Hbase,易用性较差。





























