当前位置:主页 > 查看内容

Elasticsearch 在舆情搜索中的实践- Elastic Stack 实战手册

发布时间:2021-05-19 00:00| 位朋友查看

简介:作者:朱祝元 业务背景 网络舆情监测,主要是利用互联网信息采集技术,以及自然语言处理等智能信息处理技术,通过对互联网公开数据进行自动化抓取,然后对信息进行结构化、自动分类、文本聚类、主题发现与跟踪等,提供信息检索、多维度统计、敏感信息预警、……

作者:朱祝元

业务背景

网络舆情监测,主要是利用互联网信息采集技术,以及自然语言处理等智能信息处理技术,通过对互联网公开数据进行自动化抓取,然后对信息进行结构化、自动分类、文本聚类、主题发现与跟踪等,提供信息检索、多维度统计、敏感信息预警、信息简报、自动化报告等功能,帮助用户及时发现危害品牌形象的观点,并为用户分析关注对象在网络中的形象提供依据。

在舆情 SAAS 系统(以下简称:舆情系统)中,用户设置关注的关键词,就可以快速检索对应的舆情数据,以及对提及关键词的数据提供统计图表,包括舆情走势、词云图、情感分布、情绪走势等。

这里的信息检索与统计,都离不开 Elasticsearch(以下简称:ES)的 Query 以及 aggregation功能,下面详细介绍如何使用 Elasticsearch 实现这些功能,以及在实践过程中遇到的一些问题及解决方案


舆情系统多维度检索

索引设计

采集的数据源包括微博、微信、新闻网页、论坛、自媒体平台、短视频等平台的数据,每天新增去重数据量在 1亿+,每条数据在经过结构化,以及经过 NLP(自然语言处理)之后,超过150 个字段,比如,文章标题、发布时间、发布作者、发布平台、新闻分类、新闻提及地域、新闻情绪等。由于业务端需要对这些数据进行实时检索,对不同平台的数据实时聚合,各平台的数据量分布也有很大的差异,所以按照平台进行拆分,而不是把所有的数据放到一个大的索引里面。

由于不同平台的数据量差异很大,一般地,微博占每日总采集量的 80%,而新闻网页、微信、自媒体平台的占比相对较少。为了避免由于索引的大小不一样,导致每个shard的差异过大,最终导致落在不同节点上 shard 占用空间分布不均匀而出现数据倾斜。

所以,在实现上对微博的索引按照日期做了进一步拆分,微博每日一个索引,而自媒体平台每月一个索引。

索引划分示意图

为了方便业务检索,对按天分索引的微博设置别名,比如 alias weibo_202101对应weibo_20210101,weibo_20210102,...,weibo_20210131

分词器设计索引膨胀对比

不同于英文分词器,大部分使用空格作为分隔符。针对不同的检索场景,中文有更多的分词器可供选择,不同中文分词器的选择,会有索引大小,检索性能,以及检索数据的召回率与准确率上的不同。

不同分词器的磁盘占用对比

在同样的数据条件下,通过对不同分词器下索引占用磁盘空间对比,我们发现:

IK(ik_max_word)分词器,占用磁盘空间最小Standard分词器,与 ik_max_word 相差不大,比 ik_max_word 分词方式只增加了 5% 左右N-gram 占用空间比较大,相对于 ik_max_word, 当 n=3,4,5 时,占用空间,分别是ik_max_word 的 2倍、3倍、4倍 左右。检索性能对比

不同分词器的检索耗时对比

在同样的数据条件下,通过对不同的分词下检索性能的对比,我们发现:

IK(ik_max_word)分词器,检索性能是 standard 分词器的 2-3倍 左右N-gram(n=5)分词器,检索性能是 standard 分词器的 7倍 左右,是 ik_max_word 分词器的 3倍 左右

通过综合对比,虽然 n-gram(n=5)分词器具备更高的检索性能,但是占用更多磁盘空间,在舆情业务上,索引是百亿级别(保留近3个月),基于成本考虑,这里选择了 ik_max_word 分词器。

基于 ES 的数据中台

系统架构

整个数据中台也是分层的架构体系,分为:

数据接入层消息总线数据处理与存储层数据索引层(ES 集群)智能网关层业务接入层

这里重点介绍数据索引层与智能网关层。

数据索引层

在数据索引层,按照业务特点,以及成本综合考虑。分为近 2年 数据的冷数据集群,以及近 3个月的热数据集群。

冷数据集群,选择价格相对低廉的 SAS 盘作为索引的存储介质, 提供离线的数据下载,以及对响应时间不敏感,且时间周期跨度较长的检索、聚合统计等。热数据集群,选择 SSD 盘作为索引的存储介质,每个节点 16C、64G 内存, 为了降低运维成本,以及动态扩缩容,我们选择了 阿里云Elasticsearch 服务

在索引设计方面,根据业务特点,经常要检索特定平台的数据,对索引按照文章发布平台,以及发布日期做了拆分,使每个索引不至于过大,以及导致每个节点上的数据分布不均匀。提高磁盘的利用率与检索性能。

智能网关层

智能网关层避免了业务端直连 ES,无法做到访问并发限制,以细粒度的权限限制。智能网关主要解决了一下几个痛点:

1、并发控制

网关为每个业务分配对应的独立的 TOKEN,并且设置相应的 QPS,防止某个业务的高频访问,影响了其他业务的访问,最终因为级联效应, 导致整个 ES 集群无法提供服务。另外, 网关提供了熔断限流的功能,在ES集群负载比较高的况下,对低优先级的 TOKEN 进行限流。

2、权限控制

网关为业务分配对应的权限,比如,读写权限、访问特定索引权限、查询时间跨度权限等,对查询语句进行解析,禁止访问超出权限的数据。

3、SQL 查询

网关提供了 SQL 转换成 DSL 的功能,访问业务端通过标准的 SQL 进行快速的查询对应的数据,提高业务开发效率,降低使用ES的门槛。

4、动态路由

在索引设计阶段,把索引按天、按照发文平台进行了拆分,为了方便业务端查询,根据业务端查询的时间段、发文平台,自动定位到对应的索引,业务端不用关心具体的索引名称,提高业务端的开发效率, 同时,根据查询时间范围,动态查找对应的索引,并在查询时指定到具体的索引,提高查询的速度,避免无效的索引扫描。

5、降低升级成本

由于业务不是直连 ES,后端切换 ES 集群,可做到业务端无感知,降低了 ES 集群的升级切换对业务端的影响, 降低了升级带来的开发成本。

典型业务场景情绪走势

情绪走势图

通过“情绪走势”图,可以看出一个舆情事件,在一段时间,不同情感表达上的数据分布情况,为了方便使用 ES 的聚合统计功能,对每篇文档的发布时间,设置了news_posthour(文档发布时间所在的小时)冗余字段,文档的情绪news_mood_pri字段,通过在 DSL 中嵌套使用 aggregation ,就可以在一次查询中获得对应的图表数据。

比如查询在微博上与疫情相关的博文在某一天每小时的情绪走势,查询语法如下:

GET weibo_2021-04-08/_search
 "query": {"bool": {"must": [
 {"match_phrase": {
 "news_title": "疫情"
 ]}},
 "size": 0,
 "aggs": {
 "NAME": {
 "terms": {
 "field": "news_mood_pri",
 "size": 10
 "aggs": {
 "NAME": {
 "terms": {
 "field": "news_posthour",
 "size": 24
}

通过上面的嵌套查询 DSL 语句,就可以快速获取到不同情绪分类下,每个小时段的数据量。

热门主题词

热门主题词

通过一个事件的热门主题词,可以直观的了解到一个事件的大概内容。这里也是通过 ES 的聚合功能实时获取主题词的统计数据。为了能够实时获取主题词的统计数据,这里用一个事件中提到每个主题词的文档数量,来当作主题词的数量(相当于默认每个主题词在文档中只出现一次),并没有用每篇文档的主题词的绝对量。这样做有一个好处,可以使用 ES 的 aggregation 功能实时聚合获取统计数据,再配合 TF-IDF 算法,计算每个词的相对权重。

在设置索引 schema 时,定义了news_keywords_list字段, 用于保存单篇文档的分词结果列表,然后使用如下的语法,就可以快速统计每个词对应的文档数量:

GET weibo_2021-04-08/_search
 "query": {"bool": {"must": [
 {"match_phrase": {
 "news_title": "疫情"
 ]}},
 "size": 0,
 "aggs": {
 "NAME": {
 "terms": {
 "field": "news_keywords_list",
 "size": 10
}

通过上面的 DSL 语句,可以快速统计出高频词以及与其相关的文档数量。


本文转自网络,原文链接:https://developer.aliyun.com/article/784159
本站部分内容转载于网络,版权归原作者所有,转载之目的在于传播更多优秀技术内容,如有侵权请联系QQ/微信:153890879删除,谢谢!

推荐图文


随机推荐