Elasticsearch最近一段时间非常火,以致于背后的公司都改名为Elastic了,因为Elasticsearch已经不仅限于搜索,反而更多的用在大数据分析场景,所以在公司品牌上开始“去Search化”。这得益于其强大的支持聚合分析的Query DSL,虽然这个DSL的语法有点复杂,但底层的技术确实牛B,分布式的快速分析引擎,Elasticsearch已经占有一席之地。

大家知道,搜索引擎的基本数据结构是反向索引,也就是为每个关键词建立了到文档的映射,然后所有的关键词是一个有序列表。搜索的时候,只要先从有序列表中匹配到关键词,就能搜索到包含该关键词的所有文档,反向索引的数据结构对于关键词搜索的场景是非常高效的。

但聚合分析和搜索有很大的不同。典型的场景,比如计算某个文档中每个关键词的出现次数,反向索引就无能为力了,需要先扫描整个关键词映射表,才能找到该文档包含的所有关键词,然后再进行聚合统计(这个例子其实不太准确,因为Lucene在反向索引中冗余了词频的信息,用于计算搜索相关度),也就是要对整个反向索引做全扫描,在数据量大的时候,性能当然好不到哪里去。

所以,Elasticsearch为聚合计算引入了名为fielddata的数据结构,其实就是根据反向索引再次反向出来的一个正向索引,也就是文档到关键词的映射。因为聚合计算也好,排序也好,通常是针对某些列的,实际上生成的是文档到field的多个列式索引,所以叫做fielddata。这样对文档内的关键词做聚合计算的时候,就只要从fielddata中根据文档ID查找就好。而且,fielddata是保存在内存中的,好处是不占用存储,坏处么,当然上内存不够用啦。而且这个内存是从JVM的Heap上分配的,因为JVM对于大内存的垃圾收集的影响,不能不说对稳定性有很大的挑战,数据量大的时候,时不时的OutOfMemory也不是闹着玩的。因为内存是有限的,所以不可能预先为所有的字段都建立fielddata,只能是由具体的搜索需求来触发。如果是未命中的搜索,还需要先在内存中建立fielddata,这会影响到响应时间。

fielddata的问题在于内存的有限性和JVM对于大内存的垃圾收集对系统带来的稳定性挑战。所以后来又引入了一个新的机制,就是DocValues,从数据结构上来说,它和fielddata是一样的按列的正向索引,但是实现方式不同,DocValues是持久化存储在文件中,并且是预先构建的,也就是数据进入到Elasticsearch时,就会同时生成反向索引和DocValues,这会消耗额外的存储空间,但对于JVM的内存需求会大幅度减少,剩余的内存可以留给操作系统的文件缓存使用。加上DocValues是预先构建的,查询时也免去了不命中时构建fielddata的时间,所以总体来看,DocValues只比内存fielddata慢大概10~25%,稳定性则有了大幅度提升。从Elasticsearch2.0开始,除了分词过的字符串字段,其他字段已经默认生成DocValues了(可以在索引的Mapping中通过doc_values布尔值来设置)。

简单的说,Elasticsearch通过反向索引做搜索,通过DocValues列式存储做分析,将搜索和分析的场景统一到了通一个分布式系统中,还是很有搞头的。不过分析不仅仅是聚合,这也是Elasticsearch还需要继续努力的方向,目前通过Elasticsearch-Hadoop项目,可以将Elasticsearch的搜索结果做为Spark的RDD,利用Spark做更深度的分析。未来如果分布式计算这一层能够和Spark这样的计算框架再进一步做深度的融合,恐怕有可能成为大数据领域内的另外一个大杀器。

袋鼠云正在基于Elasticsearch+Spark来做一些有意思的大数据产品,欢迎对Elasticsearch和Spark有深入研究的大牛们加入或者交流。

Elasticsearch中的DocValues的更多相关文章

  1. Solr 中的 docValues=true

    前言:  在Lucene4.x之后,出现一个重大的特性,就是索引支持DocValues,这对于广大的solr和elasticsearch用户,无疑来说是一个福音,这玩意的出现通过牺牲一定的磁盘空间带来 ...

  2. ElasticSearch中倒排索引和正向索引

    ElasticSearch搜索使用的是倒排索引,但是排序.聚合等不适合倒排索引使用的是正向索引 倒排索引 倒排索引表以字或词为关键字进行索引,表中关键字所对应的记录项记录了出现这个字或词的所有文档,每 ...

  3. 如何在Elasticsearch中安装中文分词器(IK+pinyin)

    如果直接使用Elasticsearch的朋友在处理中文内容的搜索时,肯定会遇到很尴尬的问题--中文词语被分成了一个一个的汉字,当用Kibana作图的时候,按照term来分组,结果一个汉字被分成了一组. ...

  4. elasticsearch中常用的API

    elasticsearch中常用的API分类如下: 文档API: 提供对文档的增删改查操作 搜索API: 提供对文档进行某个字段的查询 索引API: 提供对索引进行操作,查看索引信息等 查看API: ...

  5. 在Elasticsearch中查询Term Vectors词条向量信息

    这篇文章有点深度,可能需要一些Lucene或者全文检索的背景.由于我也很久没有看过Lucene了,有些地方理解的不对还请多多指正. 更多内容还请参考整理的ELK教程 关于Term Vectors 额, ...

  6. elasticsearch中的API

    elasticsearch中的API es中的API按照大类分为下面几种: 文档API: 提供对文档的增删改查操作 搜索API: 提供对文档进行某个字段的查询 索引API: 提供对索引进行操作 查看A ...

  7. 使用Hive或Impala执行SQL语句,对存储在Elasticsearch中的数据操作(二)

    CSSDesk body { background-color: #2574b0; } /*! zybuluo */ article,aside,details,figcaption,figure,f ...

  8. 使用Hive或Impala执行SQL语句,对存储在Elasticsearch中的数据操作

    http://www.cnblogs.com/wgp13x/p/4934521.html 内容一样,样式好的版本. 使用Hive或Impala执行SQL语句,对存储在Elasticsearch中的数据 ...

  9. ElasticSearch中的简单查询

    前言 最近修改项目,又看了下ElasticSearch中的搜索,所以简单整理一下其中的查询语句等.都是比较基础的.PS,好久没写博客了..大概就是因为懒吧.闲言少叙书归正传. 查询示例 http:// ...

随机推荐

  1. 学大伟业 Day 4 培训总结

    今天讲的全是dp... 不多废话,先看一道经典的模板LIS(最长不下降子序列) 一.LIS 给定一个长度为N的数列,求最长上升子序列 例:1 7 2 8 3 4 答案:1 2 3 4 代码: #inc ...

  2. Mybatis自动生成的BO对象继承公共父类(BO中过滤掉公共属性)

    使用mybatis的代码生成工具:mybatis-generator,如果自动生成的BO都有公共的属性,则可以指定这些BO继承父类(父类中定义公共属性) 1.定义父类 注意:属性public,不要使用 ...

  3. ios 判断用户是否开启权限---并跳转设置

    ios 判断用户是否开启权限---并跳转设置 ios 判断用户是否开启权限---并跳转“系统设置” 1.判断 访问相册 或 相机 权限是否开启 2.检测是否开启定位 后面将持续更新 只有在应用请求过位 ...

  4. TabbarController进行模块分类和管理

    iOS-CYLTabBarController[好用的TabbarController]   用TabbarController进行模块分类和管理,这里推荐一个CYLTabBarController, ...

  5. java程序员所必须掌握的内容

    以下内容有待细化,并用于考察员工的水平! 从低的往高级的说. 初级 1.掌握java语法 oop+io+网络 2.基本的数据结构 3.基本的算法-例如排序,合并 4.基本的几个javaee框架 spr ...

  6. 路由器基础配置之广播多路访问链路上的ospf

    我们将以上面的拓扑图进行实验,因为是要以不断广播的形式进行ospf,所有中间加了一个集线器,这种ospf和前一种不同,路由器之间会在配置好ospf之后选举出一个老大,DR,一个备份,BDR,而其他路由 ...

  7. JavaScript--Dom操作元素的样式

    在前端开发中,有时候需要动态修改的网页元素的样式,这里将使用JS动态修改元素样式的方法做个小结: 网页结构: 按钮: 标签:input    类型:button     id:btn          ...

  8. js实现区县联动

    1. 引入区县联动函数如下,将provinceList中数据改为需要联动的数据信息 var addressInit = function(_cmbProvince, _cmbCity, _cmbAre ...

  9. Laravel-admin 当使用Form组件hasMany的时候 进行编辑出现错误 foreach错误的时候解决方案

    我的关联关系原名是 goodImage 修改成 image 之后解决问题 分析得出应该是  laravel会将goodImage 转成 good_image字段  这样就foreach会报错  所以出 ...

  10. Windows使用Node.js自动生成Vue.js模版环境部署步骤-----记录

    node.js官网下载并安装node 进入node文档目录下,运行cmd 输入 node -v 查看node版本 出现表示安装完成 输入 npm -v 显示npm版本信息 安装cnpm 输入 npm ...