ES 在舆情搜索中的实践- Elastic Stack 实战手册-阿里云开发者社区

开发者社区> Elasticsearch 技术团队> 正文
登录阅读全文

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

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

970X90.png

· 更多精彩内容,请下载阅读全本《Elastic Stack实战手册》

· 加入创作人行列,一起交流碰撞,参与技术圈年度盛事吧

创作人:王欢
审稿人:杨振涛

业务背景

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

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

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

1.png

舆情系统多维度检索

索引设计

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

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

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

2.png

索引划分示意图

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

分词器设计

索引膨胀对比

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

3.png

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

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

  • 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倍 左右。

检索性能对比

4.png

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

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

  • 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 分词器。

基于 Elasticsearch 的数据中台

5.png

系统架构图

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

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

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

数据索引层

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

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

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

智能网关层

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

1、并发控制

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

2、权限控制

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

3、SQL 查询

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

4、动态路由

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

5、降低升级成本

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

典型业务场景

情绪走势

6.png

情绪走势图

通过“情绪走势”图,可以看出一个舆情事件,在一段时间,不同情感表达上的数据分布情况,为了方便使用 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 语句,就可以快速获取到不同情绪分类下,每个小时段的数据量。

热门主题词

7.png

热门主题词

通过一个事件的热门主题词,可以直观的了解到一个事件的大概内容。这里也是通过 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 语句,可以快速统计出高频词以及与其相关的文档数量。

创作人简介:
王欢,近 10 年内容大数据领域从业经验,安徽云计算产业促进会开发者工作委员会发起
人之一,阿里云 MVP。擅长高并发系统设计、数据中台构建等,目前在一家人工智能企
业担任技术 VP,主要关注 AI 算法平台构建、AI 算法在内容分析领域落地等。
博客:https://juejin.cn/user/2981531263175213/posts

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

分享: