1、应用场景

实时数据流通过kafka后,根据业务需求,一部分直接借助kafka-connector入Elasticsearch不同的索引中。

另外一部分,则需要先做聚类、分类处理,将聚合出的分类结果存入ES集群的聚类索引中。如下图所示:

业务系统的分层结构可分为:接入层、数据处理层、数据存储层、接口层。

那么问题来了?

我们需要基于聚合(数据处理层)的结果实现检索和聚合分析操作,如何实现更快的检索和更高效的聚合分析效果呢?

2、方案选型

方案一:

只建立一个索引,aggs_index。

数据处理层的聚合结果存入ES中的指定索引,同时将每个聚合主题相关的数据存入每个document下面的某个field下。如下示意图所示:

方案一示意图

方案二:

新建两个索引:aggs_index以及aggs_detail_index。

其中:

1)aggs_index存储事件列表信息。

2)aggs_detail_index存储事件关联的文章内容信息。

如下图所示:

方案二示意图

3、方案对比

方案一优点:节省存储空间,只存储关联文章id,数据没有重复存储。

方案一缺点:检索、聚合慢,性能不能达标。

方案一后续的所有操作,都需要先遍历检索这一堆IDs,然后再进行检索、聚合分析操作。

操作实例如下(实际比这要复杂):

第一步:通过事件id,获取关联文章id列表;

第二步:基于关联文章id列表,进行检索和聚合操作。

POST  aggs_index/_search
{
"_source": {
"includes":[
"title",
"abstract",
"publish_time",
"author"
]},
"query":{
"terms":{
"_id":"["789b4cb872be00a04560d95bf13ec8f42c",
"792d9610b03676dc5644c2ff4db372dec4",
"817f5cff3dd0ec3564d45615f940cb7437",
"....."]
}
}
}

步骤2当id数量很多时,会有如下的错误提示:

{
"error": {
"root_cause": [
{
"type": "too_many_clauses",
"reason": "too_many_clauses:
maxClauseCount is set to 1024"
},

。。。

方案二优点:分开存储,便于一个索引中进行检索、聚合分析操作。

空间换时间,极大的提升检索效率、聚合速度。

方案二缺点:同样的数据,多存储了一份。

其对应的检索操作如下:

POST  aggs_index/_search
{
"_source": {
"includes":[
"title",
"abstract",
"publish_time",
"author"
]},
"query":{
"term":{
"topic_id":"WIAEgRbI0k9s1D2JrXPC"
}
}
}

是真的吗?

用事实说话:

以下响应时间的单位为:ms。

方案一要在N个(N接近10)索引,每个索引近千万级别的数据中检索。

两方案对比

两方案响应时间对比效果图

4、小结

  • 由以上图示,对比可知,方案二采取了空间换时间的策略,数据量多存储了一份,但是性能提升了10余倍。

  • 在实战开发中,我们要理性的选择存储方案,在磁盘成本日渐低廉的当下,把性能放在第一位,用户才能用的"爽“!

推荐阅读:

《深入理解 Java 内存模型》读书笔记

面试-基础篇

Spring Boot 2.0 迁移指南

SpringBoot使用Docker快速部署项目

为什么选择 Spring 作为 Java 框架?

SpringBoot RocketMQ 整合使用和监控

Spring Boot 面试的十个问题

使用 Spring Framework 时常犯的十大错误

SpringBoot Admin 使用指南

SpringBoot Kafka 整合使用

SpringBoot RabbitMQ 整合使用

使用Arthas 获取Spring ApplicationContext还原问题现场

上篇好文:

Elasticsearch索引增量统计及定时邮件实现

Elasticsearch实战 | 必要的时候,还得空间换时间!的更多相关文章

  1. JDK1.8 LongAdder 空间换时间: 比AtomicLong还高效的无锁实现

    我们知道,AtomicLong的实现方式是内部有个value 变量,当多线程并发自增,自减时,均通过CAS 指令从机器指令级别操作保证并发的原子性. // setup to use Unsafe.co ...

  2. Redis学习笔记~关于空间换时间的查询案例

    回到目录 空间与时间 空间换时间是在数据库中经常出现的术语,简单说就是把查询需要的条件进行索引的存储,然后查询时为O(1)的时间复杂度来快速获取数据,从而达到了使用空间存储来换快速的时间响应!对于re ...

  3. Redis基础知识之————空间换时间的查询案例

    空间与时间 空间换时间是在数据库中经常出现的术语,简单说就是把查询需要的条件进行索引的存储,然后查询时为O(1)的时间复杂度来快速获取数据,从而达到了使用空间存储来换快速的时间响应!对于redis这个 ...

  4. 你好,C++(28)用空间换时间 5.2 内联函数 5.3 重载函数

    5.2  内联函数 通过5.1节的学习我们知道,系统为了实现函数调用会做很多额外的幕后工作:保存现场.对参数进行赋值.恢复现场等等.如果函数在程序内被多次调用,且其本身比较短小,可以很快执行完毕,那么 ...

  5. 【C语言学习笔记】空间换时间,查表法的经典例子!知识就是这么学到的~

    我们怎么衡量一个函数/代码块/算法的优劣呢?这需要从多个角度看待.本篇笔记我们先不考虑代码可读性.规范性.可移植性那些角度. 在我们嵌入式中,我们需要根据实际资源的情况来设计我们的代码.比如当我们能用 ...

  6. 计数排序(O(n+k)的排序算法,空间换时间)

    计数排序就是利用空间换时间,时间复杂度O(n+k) n是元素个数,k是最大数的个数: 统计每个数比他小的有多少,比如比a[i]小的有x个,那么a[i]应该排在x+1的位置 代码: /* * @Auth ...

  7. leetcode-383-Ransom Note(以空间换时间)

    题目描述: Given an arbitrary ransom note string and another string containing letters from all the magaz ...

  8. HDU4548美素数——筛选法与空间换时间

    对于数论的学习比较的碎片化,所以开了一篇随笔来记录一下学习中遇到的一些坑,主要通过题目来讲解 本题围绕:素数筛选法与空间换时间 HDU4548美素数 题目描述 小明对数的研究比较热爱,一谈到数,脑子里 ...

  9. 图解Skip List——本质是空间换时间的数据结构,在lucene的倒排列表,bigtable,hbase,cassandra的memtable,redis中sorted set中均用到

    Skip List的提出已有二十多年[Pugh, W. (1990)],却依旧应用广泛(Redis.LevelDB等).作为平衡树(AVL.红黑树.伸展树.树堆)的替代方案,虽然它性能不如平衡树稳定, ...

随机推荐

  1. Z点餐系统项目下期改进计划

    随着计算机应用范围的日益广泛深人,应用软件的规模及复杂程度也日趋大型化.复杂化,这就导致软件开发的方式也从早期的单兵作战式或手工作坊式渐渐转变为集团化.工厂流水 问题: (一)缺乏项目管理系统培训.项 ...

  2. 关于过两级mux的时序约束的添加(一个非常经典的时序约束问题)

    非常开心自己的微信公众号: <数字集成电路设计及EDA教程> 关注者超过了1700 里面主要讲解数字IC前端.后端.DFT.低功耗设计以及验证等相关知识,并且讲解了其中用到的各种EDA工具 ...

  3. linux修改时间显示格式

    1. 问题描述 Linux下经常使用 "ls - ll"命令查看文件夹或文件创建及权限信息,但是满屏的Mar .May.Jul有点小难受. 2. 解决方案 修改bash_profi ...

  4. Gin 框架 - 安装和路由配置

    目录 概述 Gin 安装 路由配置 推荐阅读 概述 看下 Gin 框架的官方介绍: Gin 是一个用 Go (Golang) 编写的 web 框架. 它是一个类似于 martini 但拥有更好性能的 ...

  5. ES6中的解构

    数组中的解构: 输出 : 白板 幺鸡 二条 对象的解构: 输出: 老王 12 数组的结构用[];对象的解构用{}:一定要区分它是数组还是解构. 区分方法:看 它是在赋值还是在拿值,等号左边,都为解构, ...

  6. Java EE核心框架实战(1)

    内容前言:本书适合具有一定Java编程基础的读者阅读,增强其项目实战能力. 2014年9月第1版 下载本书所有源代码可通过  http://pan.baidu.com/s/1i3sshXr 本书配套的 ...

  7. MySql 命令(命令行)

    1.连接Mysql 格式: mysql -h主机地址 -u用户名 -p用户密码1.连接到本机上的MYSQL. 首先打开DOS窗口,然后进入目录mysql\bin,再键入命令mysql -u root ...

  8. Java中使用 foreach 操作数组

    foreach 并不是 Java 中的关键字,是 for 语句的特殊简化版本,在遍历数组.集合时, foreach 更简单便捷.从英文字面意思理解 foreach 也就是" for 每一个& ...

  9. IT界的复仇者联盟解读

    漫威宇宙应用到IT界也是可以解读的,自从编程语言分了派系后,故事就多了,今天我们就用漫威宇宙的故事来解读一下IT界的故事. 漫威宇宙其实也就讲了一件事,整个宇宙就好比一个Java项目,其中有一群叫做美 ...

  10. linux初学者-系统启动故障篇

    linux初学者-系统启动故障篇 在系统的操作中,有时会不小心误删或者操作失误使得系统启动不起来,下文将列举几种常见的系统启动失败的情况及解决的办法. 1.删除或者覆盖mbr的446个字节 mbr的4 ...