加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

ES in BI

发布时间:2020-12-14 01:30:18 所属栏目:大数据 来源:网络整理
导读:一直想找一个用于大数据平台实时OLAP(甚至是实时计算)的框架,之前调研的Druid(druid.io)太过复杂,整个Druid由5、6个服务组成,而且加载数据也不太方便,性能一般,亦或是我还不太会用它。后来发现使用ElasticSearch就可以满足海量数据实时OLAP的需求。

一直想找一个用于大数据平台实时OLAP(甚至是实时计算)的框架,之前调研的Druid(druid.io)太过复杂,整个Druid由5、6个服务组成,而且加载数据也不太方便,性能一般,亦或是我还不太会用它。后来发现使用ElasticSearch就可以满足海量数据实时OLAP的需求。
ElasticSearch相信大家都很熟悉了,它在搜索领域已经有了举足轻重的地位,而且也支持越来越多的聚合统计功能,还和YARN、Hadoop、Hive、Spark、Pig、Flume等大数据框架兼容的越来越好,比如:可以将ElasticSearch跑在YARN上,还可以在Hive中建立外部表映射到ElasticSearch的Index中,直接在Hive中执行INSERT语句,将数据加载进ElasticSearch。
所谓OLAP,其实就是从事实表中统计任意组合维度的指标,也就是过滤、分组、聚合,其中,聚合除了一般的SUM、COUNT、AVG、MAX、MIN等,还有一个重要的COUNT(DISTINCT),看上去这些操作在SQL中是非常简单的统计,但在海量数据、低延迟的要求下,并不是那么容易做的。
ElasticSearch本来就是做实时搜索的,过滤自然不是问题,现在也支持各种聚合以及Pipeline aggregations(相当于SQL子查询的功能),而且ElasticSearch的安装部署也非常简单,一个节点只有一个服务进程,关于安装配置可参考:http://lxw1234.com/archives/2015/12/582.htm
本文以两个业务场景的例子,看一下ElasticSearch是如何满足我们的需求的。

例子1:网站流量报告

在我们的报表平台有这样一张报表,用于查看每个网站每天的流量指标:

elasticsearch

其中,维度有:天、小时、网站,指标有:PV、UV、访问次数、跳出率、平均停留时间、回访率等。另外,还有一张报表是地域报告,维度多了省份和城市,指标一样。目前的做法是将可选的维度组合及对应的指标先在Hive中分析好,再将结果同步至MySQL,供报表展现。

真正意义上的OLAP做法,我是这样做的:在Hive分析好一张最细粒度为visit_id(session_id)的事实表,字段及数据如下:

elasticsearch

然后将这张事实表的数据加载到ElasticSearch中的logs2/sitelog1211中。查看数据:

 
 
  1. curl -XGET 'http://localhost:9200/logs2/sitelog1211/_search?pretty'
  2. {
  3. "took" : 1015,
  4. "timed_out" false"_shards"{
  5. "total"10"successful""failed"0
  6. },
  7. "hits"{
  8. 3356328"max_score"1.0[{
  9. "_index""logs2""_type""sitelog1211""_id""AVGkoWowd8ibEMoyOhve""_score""_source":{"cookieid""8F97E07300BC7655F6945A""siteid""633""visit_id""feaa25e6-3208-4801-b7ed-6fa45f11ff42""pv"2"is_return_cookie"0"is_bounce_visit""visit_stay_times"34"visit_view_page_cnt""region""浙江""city""绍兴"}
  10. ……

该天事实表中总记录数为3356328
接着使用下面的查询,完成了上图中网站ID为1127,日期为2015-12-11的流量报告:

d '

  
  
  • {
  • "size": 0,
  • "aggs" : {
  • "pv" : {"sum" : { "field" : "pv" } },
  • "uv" : {"cardinality" : {"field" : "cookieid","precision_threshold": 40000}},
  • "return_uv" : {
  • "filter" : {"term" : {"is_return_cookie" : 1}},
  • "aggs" : {
  • "total_return_uv" : {"cardinality" : {"field" : "cookieid","precision_threshold": 40000}}
  • }
  • },
  • "visits" : {"cardinality" : {"field" : "visit_id",91)"> "total_stay_times" : {"sum" : { "field" : "visit_stay_times" }},
  • "bounce_visits" : {
  • "filter" : {"term" : {"is_bounce_visit" : 1}},91)"> "aggs" : {
  • "total_bounce_visits" : {"cardinality" : {"field" : "visit_id","precision_threshold": 40000}}
  • }
  • }
  • }'
  • 基本上1~2秒就可以返回结果:

     接着是地域报告中维度为省份的指标统计,查询语句为:

     因为要根据省份分组,比之前的查询慢一点,但也是秒级返回:

     这里需要说明一下,在ElasticSearch中,对于去重计数(COUNT DISTINCT)是基于计数估计(Cardinality),因此如果去重记录数比较大(超过40000),便可能会有误差,误差范围是0~2%。

    例子2:用户标签的搜索统计

    有一张数据表,存储了每个用户ID对应的标签,同样加载到ElasticSearch中,数据格式如下:

    
      
      
  • 220820165"lxw1234""user_tags""222222222222222""sex""女性""age""27到30岁""income""5000到10000""edu""本科" "appcategory""娱乐类|1.0""interest""""onlinetime""9:00~12:00|1.0""os""IOS|1.0""hobby""游戏|28.57,房产|8.57,服饰鞋帽箱包|28.57,互联网/电子产品|5.71,家居|8.57,餐饮美食|5.71,体育运动|14.29""河南省"}
  • ......
  • 每个用户都有性别、年龄、收入、教育程度、兴趣、地域等标签,其中使用_id来存储用户ID,也是主键。

    查询1:SELECT count(1) FROM user_tags WHERE sex = ‘女性’ AND appcategory LIKE ‘%游戏类%';

     "filter" : {
      
      
  • "and" : [
  • {"term" : {"sex" : "女性"}},91)"> {"match_phrase" : {"appcategory" : "游戏类"}}
  • ]
  • }
  • 查询2:先筛选,再分组统计:

     
    
  • AND appcategory LIKE '%游戏类%'
  • GROUP BY edu
  • ORDER BY cnt DESC
  • limit ;
  • 查询语句:

     
      
      
  • "filter" : {
  • "and" : [
  • {"match_phrase" : {"appcategory" : "游戏类"}}
  • ]
  • "edu_count" : {
  • "terms" : {
  • "field" : "edu",91)"> "size" : 10
  • }
  • 479"edu_count"802670
  • "硕士研究生"16032
  • "专科"1433
  • "博士研究生"25
  • "初中及以下"4
  • "中专/高中"1
  • }]
  • }
  • (编辑:李大同)

    【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

      推荐文章
        热点阅读