小试牛刀ElasticSearch大数据聚合统计
ElasticSearch相信有不少朋友都了解,即使没有了解过它那相信对ELK也有所认识E即是ElasticSearch。ElasticSearch最开始更多用于检索,作为一搜索的集群产品简单易用绝对是一个非常不错的选择,其实本人早在ElasticSearch v0.2的时候就使用,一转眼数年过去现在都7.X了。
其实ElasticSearch除了提供强大的集群化搜索服务外,它提供一个aggregation功能会再一次让你受到它的强大,aggregation是一个数据统计汇总功能,表面上这功能在关系数据库上也可以做,但结合分词建维度就更能体现出它的灵活之处。
关系数据库问题
拿产品订单为例,它有产品分类,不同的规格,销售人,客户和地区等;然而这些信息在设计上都是归纳到不同的表中,如果要针对这些不同的信息来统计订单销售情况那相信是一件非常繁琐和效率极其低下的工作(先不说数据数千万了上亿或更大规模,就算几十上百万数据这个关系数据的SQL查询也够受了)。即便可以把数据抽取并归纳起来做统计,但随着新的数据维度增加新的维度字段重新调用。
无维度字段?
在数据统计每个维度都对一个信息列来存储,这样加入维度必须就需要添加信息列。如果用一个字段存储所有维度信息呢?显然这种想法在传统关系数据库中也不可能的,因为无法做表的关联和维度区分,其实不要说传统数据库很多数据库都无法在一个字符中拆分出不同的维度出来,除非加入程序来切分,但这种法在数据规模大的情况必然是不可取的!
如果用一个字段就能存储所有维度,那就意味着以后加入新的维度数据也无须调整结构和程序就实现新维护度数据的统计处理。这看上去多么美好,似乎也很难实现,但ElasticSearch能解决这一问题。
试验
首先ElasticSearch是一个搜索引擎,它最擅长的工作是对内容进行分词并构建索引;在这机制下可以对一个字段的信息进行拆分并存储到索引上。通过这一特性同样可以把一个字段的信息切分成N个维度的信息,然后存储到索引;只要有了单一的维度索引那接下来针对不同维护的汇总统计就简单了。
在单节点的ElasticSearch上创建了5千万条产品销售数据;然后Tag字段存储对应的维度信息,每个维度通过/来区分,分别有:customer,employee,country和category.有了这些信息,接下来的工作是尝试使用Aggr功能来完成相应的汇总
var query = db.Index.CreateQuery();
query.Prefix("Tag", "客户");
var aggs = db.Index.CreateAggs("customer_group",
Elasticsearch.Search.AggsType.terms, "Tag");
aggs.SubAggs("sum_quantity", Elasticsearch.Search.AggsType.sum, "Quantity");
aggs.SubAggs("sum_total", Elasticsearch.Search.AggsType.sum, "Total");
aggs.Size(5);
aggs.Query = query;
var items = await aggs.Execute<OrderRecord>();
代码并不复杂,查询Tag标签存在customer的数据,并对它们进行一个分组,最后再汇总出对应的Quantity和Total信息;最后获取排在最前面的5条数据。
效率
ElasticSearch做这方面的效率怎样呢?部署在一个节点上,分别汇总了客户,国家和员工。
5千万条(单机单节点)
5千万条(单机双节点)
这个时间是在不停更新索引下同时做统计的结果,当在索引不更新的情况其二次处理效率会高上几倍。
静态历史数据
上面绍了ElasticSearch对大数据一个聚合效率做了一个测试,那测试是基于动态数据测试,即在聚合测试的过程中同时大量更新索引数据;接下来做的测试则是针对固定的历史数据,在聚合测试过程中不进行数据更新。
测试数据环境
5千万条件产品销售数据,分布在2000-2020间,所有数据部署在单机双节点的服务中。
测试过程
分别汇总每一年的员工,国家和分类数据,并显示最前面的3条记录。
int top = 3;
for (int i = 2000; i < 2020; i++)
{
DateTime start = new DateTime(i, 1, 1);
DateTime end = new DateTime(i + 1, 1, 1);
var result = await db.AggsTag("国家", top, start, end, null);
Console.WriteLine($"| {result.Title} use {result.UseTime:###,###.00}ms");
Console.WriteLine($"|-{"".PadLeft(89, '-')}|");
foreach (SummaryItem item in result.Items)
{
Print(item);
} result = await db.AggsTag("分类", top, start, end, null);
Console.WriteLine($"| {result.Title} use {result.UseTime:###,###.00}ms");
Console.WriteLine($"|-{"".PadLeft(89, '-')}|");
foreach (SummaryItem item in result.Items)
{
Print(item);
} result = await db.AggsTag("员工", top, start, end, null);
Console.WriteLine($"| {result.Title} use {result.UseTime:###,###.00}ms");
Console.WriteLine($"|-{"".PadLeft(89, '-')}|");
foreach (SummaryItem item in result.Items)
{
Print(item);
}
}
测试结果
从测试结果来看效率非常出色,每个年分类聚合统计所损耗的时候大概在0.1秒。
小试牛刀ElasticSearch大数据聚合统计的更多相关文章
- SQL大数据操作统计
SQL大数据操作统计 1:select count(*) from table的区别SELECT object_name(id) as TableName,indid,rows,rowcnt FROM ...
- ElasticSearch大数据分布式弹性搜索引擎使用
阅读目录: 背景 安装 查找.下载rpm包 .执行rpm包安装 配置elasticsearch专属账户和组 设置elasticsearch文件所有者 切换到elasticsearch专属账户测试能否成 ...
- ElasticSearch大数据分布式弹性搜索引擎使用—从0到1
阅读目录: 背景 安装 查找.下载rpm包 .执行rpm包安装 配置elasticsearch专属账户和组 设置elasticsearch文件所有者 切换到elasticsearch专属账户测试能否成 ...
- Spark 大数据文本统计
此程序功能: 1.完成对10.4G.csv文件各个元素频率的统计 2.获得最大的统计个数 3.对获取到的统计个数进行降序排列 4.对各个元素出现次数频率的统计 import org.apache.sp ...
- 【大数据】了解Hadoop框架的基础知识
介绍 此Refcard提供了Apache Hadoop,这是最流行的软件框架,可使用简单的高级编程模型实现大型数据集的分布式存储和处理.我们将介绍Hadoop最重要的概念,描述其架构,指导您如何开始使 ...
- Elasticsearch 聚合统计与SQL聚合统计语法对比(一)
Es相比关系型数据库在数据检索方面有着极大的优势,在处理亿级数据时,可谓是毫秒级响应,我们在使用Es时不仅仅进行简单的查询,有时候会做一些数据统计与分析,如果你以前是使用的关系型数据库,那么Es的数据 ...
- 用logstash 作数据的聚合统计
用logstash 作数据的聚合统计 以spark-streaming 处理消费数据,统计日志经spark sql存储在mysql中 日志写入方式为append val wordsDataFrame ...
- 大数据篇:ElasticSearch
ElasticSearch ElasticSearch是什么 ElasticSearch是一个基于Lucene的搜索服务器.它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口. ...
- Elasticsearch 第六篇:聚合统计查询
h2.post_title { background-color: rgba(43, 102, 149, 1); color: rgba(255, 255, 255, 1); font-size: 1 ...
随机推荐
- # spring boot + mybatis 读取数据库
spring boot + mybatis 读取数据库 创建数据库 use testdb; drop table if exists t_city; create table t_city( id i ...
- [日常摸鱼]poj2778 DNA Sequence
这题太神啦 题意:求长度为$n$的不包含给定DNA序列的DNA序列个数,给定的不超过10个 构建出Trie图,用$danger[i]$来表示不能走到$i$,对于DNA序列结尾的结点$danger$设为 ...
- SpringBoot2 整合OAuth2组件,模拟第三方授权访问
本文源码:GitHub·点这里 || GitEE·点这里 一.模式描述 授权服务 验证第三方服务的身份,验证邮箱用户的身份,记录和管理认证Token,为资源服务器提供Token校验.场景:第三方网站借 ...
- CSS鼠标指针cursor样式
参考来源:W3SCHOOL 有时我们需要在CSS布局时设定特定的鼠标指针样式,这时可以通过设定cursor来实现: url: 需使用的自定义光标的 URL. 注释:请在此列表的末端始终定义一种普通的光 ...
- Asp.Net Core仓储模式+工作单元
仓储模式+工作单元 仓储模式 仓储(Repository)模式自2004年首次作为领域驱动模型DDD设计的一部分引入,仓储本质上是提供提供数据的抽象,以便应用程序可以使用具有接口的相似的简单抽象集合. ...
- IIS重写2.0 IIS伪静态 下载地址
IIS重写2.0 IIS伪静态 下载地址 https://www.iis.net/downloads/microsoft/url-rewrite#additionalDownloads Downloa ...
- Mybatis Generator 最完整配置详解
这是从CSDN找到的一篇翻译文章,尝试重新排版后转载. 1. < generatorConfiguration > 标签 1.1 可以用于加载配置项或者配置文件,在整个配置文件中就可以使用 ...
- libzip开发笔记(一):libzip库介绍、编译和工程模板
前言 Qt使用一些压缩解压功能,选择libzip库,libzip库比较原始,也是很多其他库的基础支撑库. libzip libzip是一个C库,用于读取,创建和修改zip档案.可以从数 ...
- hashmap有一个loadFactory为什么是0.75从泊松分布解析看看
简述: 写这篇文章是看到网上的一篇面试题,有面试官问hashmap有一个loadFactory为什么是0.75 我先解释一下 0.75上下文,当一个hashmap初始数组大小暂时不考虑扩容情况,初始 ...
- git fork , git pull request那回事
git fork 原理 相当于你在原项目的主分支上又建立了一个分支,你可以在该分支上任意修改,如果想将你的修改合并到原项目中时,可以pull request,这样原项目的作者就可以将你修改的东西合并到 ...