Elasticsearch为什么快?

这篇具有很好参考价值的文章主要介绍了Elasticsearch为什么快?。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1、搜索引擎为什么快?

倒排索引核心原理

概括的说,一个优秀的搜索引擎的设计,至少应该具备以下几点要求:

  • 高效的压缩算法

  • 快速的编码和解码算法

  • 合理的数据结构

  • 通用最小化算法

结合以上几点,后面我将通过一个案例来讲解,倒排索引的基本原理是什么。在了解“倒排索引”之前,我们先来看一下何为“索引”。

一本汉语字典,如果我们想要从中找到某个字,通常我们会通过字典最前面的拼音检索或者是部首检索来查找。其实汉语字典的正文本身就是一个索引,比如我们要查找“吴”字,很自然的就想到了“吴”的拼音是“wu”,w在26个字母中在很靠后的位置,基本上就可以确定“吴”字的大致位置,然后按照字典序可以在w字母的汉字里精确的找到这个字,因为汉字本身就是按照字典序排列的,这种按照一定规则排序的目录在关系型数据库中一般叫做“聚集索引”

除了这种索引,通常我们还了解一种类似于“偏旁部首”的检索方式称之为“非聚集索引”,我们这里不展开来讨论什么是聚集索引和非聚集索引。但是我们可以确定的是,不管是什么索引,它的目的都是帮助我们快速检索数据的。

在数据库领域里,索引可以概括为一种帮助我们快速检索数据的以文件形式落地的数据结构

以MySQL为例,如图1-1所示:

es为什么查询速度快,记录,elasticsearch,大数据,Powered by 金山文档

左侧是MySql安装文件的data目录,右侧使我们使用数据库客户端打开数据库后的样式,左侧文件分别对应了右侧数据库中的数据库名,我们以“mysql”这个数据库为例,文件夹中每个文件都有若干个不同后缀的同名文件,分别对应右侧某个数据表,不同的后缀代表不同的数据类型,其中.frm文件代表当前文件存储的是数据表的表结构,.MYD和.MYI文件则代表了当前文件是myisam存储引擎下的数据文件和索引文件,.ibd则代表当前文件是innodb存储引擎下的索引文件,只不过innodb的数据和索引使用了同一个文件。

不管是元数据还是索引数据,他们最终都是以“文件”的形式存储在磁盘中的,只不过不同的文件内部使用的数据结构各不相同。而MySql使用的数据结构是B+Trees。但是这种数据结构并不适用于倒排索引,原因我们会在后面的文章中提到。

ES倒排原理

假设需要对下面两个工地的信息进行倒排索引的创建:

文档ID为001,工地名称为“北京海淀花园小区”;
文档ID为002,工地名称为“北京朝阳星空小区”。

首先,ES将文档交给分析器进行处理,处理的过程包括字符过滤、分词和分词过滤,最终的处理结果是文档内容被表示为一系列关键词信息(关键词本身以及它在文档中出现的位置信息和词性信息)的集合。如下图所示。

es为什么查询速度快,记录,elasticsearch,大数据,Powered by 金山文档

3、其次,ES根据分析结果建立文档-词语矩阵,用以表示词语和文档的包含关系,如图所示。

es为什么查询速度快,记录,elasticsearch,大数据,Powered by 金山文档

4、文档-词语矩阵建立完成之后,接着需要建立基于词语的倒排索引。ES会遍历文档词语矩阵中的每一个词语,然后将包含该词语的文档信息与该词语建立一种映射关系。映射关系中的词语集合叫作Term Dictionary。映射中的文档集合信息不仅包含文档ID,还包含词语在文档中的位置和词频信息,包含这些文档信息的结构叫作Posting List。对于一个规模很大的文档集合来说,可能包含几十万甚至上百万的词语集合,能否快速定位某个词语,直接影响搜索时的响应速度。因此需要一种高效的数据结构对映射关系中的词语集合进行索引,这种结构叫作Term Index。上述3种结构结合在一起就构成了ES的倒排索引结构,逻辑关系如图所示。

es为什么查询速度快,记录,elasticsearch,大数据,Powered by 金山文档

本例中的倒排索引结构如图所示。

es为什么查询速度快,记录,elasticsearch,大数据,Powered by 金山文档

2、实际es中倒排索引的存储结构

es为什么查询速度快,记录,elasticsearch,大数据,Powered by 金山文档

2.1 倒排表(Posting List)

索引文件中分别存储了不同的数据

其中倒排表包含某个词项的所有id的数据存储了在.doc文件中;

2.2 词项字典(Term Dictionary)

词项字典包含了index field的所有经过normalization token filters处理之后的词项数据,最终存储在.tim文件中。

所谓normalization其实是一个如去重、时态统一、大小写统一、近义词处理等类似的相关操作;词项索引就是为了加速词项字典检索的一种数据结构,落地文件为.tip。.tip文件和.tim文件的数据结构如下图2-2所示

es为什么查询速度快,记录,elasticsearch,大数据,Powered by 金山文档

2.3 词项索引(Term Index)

需要一种高效的数据结构对映射关系中的词语集合也就是Term Dictionary进行索引,这种结构叫作Term Index。Term Index最开始是用字典树实现,luncence4.0之后采用FST来优化。

3、字典树:Trie(Prefix Tree)原理

Lucene中对倒排索引Term DIctionary以及Term Index的数据压缩和优化算法,最简单的理解,Term Index 就像一本词典的目录一样

但是实际上Term可以是任意的 byte 数组,而不仅仅是英文字符,因此实际的 Term Index 是一棵 Trie Tree:

es为什么查询速度快,记录,elasticsearch,大数据,Powered by 金山文档

如图所示是一棵 Trie Tree。这棵 Trie Tree 不会包含所有的 term,它包含的是 term 的一些前缀。通过 Term Index 可以快速地定位到 Term Dictionary 的某个 offset,然后从这个位置再往后顺序查找。再加上一些压缩技术 e.g. FST,Term Index 需要的存储空间非常小,可能只有所有 term 占用空间的几十分之一,因此 Term Index 被完全缓存在内存中是没有问题的。

使用了 Term Index 后,ES的倒排索引整体效果如下

es为什么查询速度快,记录,elasticsearch,大数据,Powered by 金山文档

现在我们可以很清楚地知道为什么ES的检索要比MySQL快得多了。在MySQL中,即使建立了索引,但索引是以B+ Tree的形式存储在磁盘上的,在数据量比较大的情况下,想要检索到一条记录,需要若干次的random access的磁盘操作。而ES在Term Dictionary(相当于MySQL中的索引)的基础上,又添加了Term Index这一结构,并且直接以Trie Tree的形式缓存在内存中。在检索一个term时,只需要从Term Index查找到对应的Term Dictionary的block的位置,再到磁盘上去访问对应的数据,大大减少了对磁盘的random access操作的次数。

2.4减小Term Index存储空间 —— FST

Term Index要被直接缓存在内存中以提升查找速度,那么就必然要采用某种结构来压缩Term Index。Term Index在内存中就是以FST(Finite State Transducers,有限状态转换机)的形式来存储的。

FST是一种类Trie Tree,使用FSM作为数据结构,可以理解为key -> value形式。

  • 空间占用小:通过对前缀和后缀的重复利用,压缩了存储空间;

  • 查询速度快:时间复杂度为O(len(str));

3、Elasticsearch其它优化

Elasticsearch 的基础是 Lucene,所有的索引和文档数据是存储在本地的磁盘中,具体的路径可在 ES 的配置文件…/config/elasticsearch.yml中配置,如下:

#
# Path to directory where to store the data (separate multiple locations by comma):
#
path.data: /path/to/data
#
# Path to log files:
#
path.logs: /path/to/logs

磁盘在现代服务器上通常都是瓶颈。Elasticsearch重度使用磁盘,你的磁盘能处理的吞吐量越大,你的节点就越稳定。这里有一些优化磁盘I/O的技巧:

  • 使用SSD就像其他地方提过的,他们比机械磁盘优秀多了。

  • 使用RAID0。条带化RAID会提高磁盘IO,代价显然就是当一块硬盘故障时整个就故障了。不要使用镜像或者奇偶校验RAID,因为副本已经提供了这个功能。

  • 另外,使用多块硬盘,并允许Elasticsearch 通过多个path data目录配置把数据条带化分配到它们上面。

  • 不要使用远程挂载的存储,比如NFS或者SMB/CIFS。这个引入的延迟对性能来说完全是背道而驰的。

优化-分片策略

合理设置分片数

分片和副本的设计为 ES 提供了支持分布式和故障转移的特性,但并不意味着分片和副本是可以无限分配的。而且索引的分片完成分配后由于索引的路由机制,我们是不能重新修改分片数的。

可能有人会说,我不知道这个索引将来会变得多大,并且过后我也不能更改索引的大小,所以为了保险起见,还是给它设为 1000 个分片吧。但是需要知道的是,一个分片并不是没有代价的。需要了解:

  • 一个分片的底层即为一个 Lucene 索引,会消耗一定文件句柄、内存、以及 CPU运转。

  • 每一个搜索请求都需要命中索引中的每一个分片,如果每一个分片都处于不同的节点还好, 但如果多个分片都需要在同一个节点上竞争使用相同的资源就有些糟糕了。

  • 用于计算相关度的词项统计信息是基于分片的。如果有许多分片,每一个都只有很少的数据会导致很低的相关度。

一个业务索引具体需要分配多少分片可能需要架构师和技术人员对业务的增长有个预先的判断,横向扩展应当分阶段进行。为下一阶段准备好足够的资源。 只有当你进入到下一个阶段,你才有时间思考需要作出哪些改变来达到这个阶段。一般来说,我们遵循一些原则:

  • 控制每个分片占用的硬盘容量不超过 ES 的最大 JVM 的堆空间设置(一般设置不超过 32G,参考下文的 JVM 设置原则),因此,如果索引的总容量在 500G 左右,那分片大小在 16 个左右即可;当然,最好同时考虑原则 2。

  • 考虑一下 node 数量,一般一个节点有时候就是一台物理机,如果分片数过多,大大超过了节点数,很可能会导致一个节点上存在多个分片,一旦该节点故障,即使保持了 1 个以上的副本,同样有可能会导致数据丢失,集群无法恢复。所以, 一般都设置分片数不超过节点数的 3 倍。

  • 主分片,副本和节点最大数之间数量,我们分配的时候可以参考以下关系:

节点数<=主分片数 *(副本数+1)

推迟分片分配

对于节点瞬时中断的问题,默认情况,集群会等待一分钟来查看节点是否会重新加入,如果这个节点在此期间重新加入,重新加入的节点会保持其现有的分片数据,不会触发新的分片分配。这样就可以减少 ES 在自动再平衡可用分片时所带来的极大开销。

通过修改参数 delayed_timeout ,可以延长再均衡的时间,可以全局设置也可以在索引级别进行修改:

#PUT /_all/_settings
{
    "settings": {
        "index.unassigned.node_left.delayed_timeout": "5m"
    }
}

优化-路由选择

当我们查询文档的时候, Elasticsearch 如何知道一个文档应该存放到哪个分片中呢?它其实是通过下面这个公式来计算出来:

shard = hash(routing) % number_of_primary_shards

routing 默认值是文档的 id,也可以采用自定义值,比如用户 id。

不带routing查询

在查询的时候因为不知道要查询的数据具体在哪个分片上,所以整个过程分为2个步骤

  • 分发:请求到达协调节点后,协调节点将查询请求分发到每个分片上。

  • 聚合:协调节点搜集到每个分片上查询结果,在将查询的结果进行排序,之后给用户返回结果。

带routing查询

查询的时候,可以直接根据routing 信息定位到某个分配查询,不需要查询所有的分配,经过协调节点排序。向上面自定义的用户查询,如果routing 设置为userid 的话,就可以直接查询出数据来,效率提升很多。

写入速度优化

ES 的默认配置,是综合了数据可靠性、写入速度、搜索实时性等因素。实际使用时,我们需要根据公司要求,进行偏向性的优化。

针对于搜索性能要求不高,但是对写入要求较高的场景,我们需要尽可能的选择恰当写优化策略。综合来说,可以考虑以下几个方面来提升写索引的性能.

  • 加大Translog Flush,目的是降低Iops、Writeblock。

  • 增加Index Refesh间隔,目的是减少Segment Merge的次数。

  • 调整Bulk 线程池和队列。

  • 优化节点间的任务分布。

  • 优化Lucene层的索引建立,目的是降低CPU及IO

优化存储设备

ES 是一种密集使用磁盘的应用,在段合并的时候会频繁操作磁盘,所以对磁盘要求较高,当磁盘速度提升之后,集群的整体性能会大幅度提高。

合理使用合并

Lucene 以段的形式存储数据。当有新的数据写入索引时, Lucene 就会自动创建一个新的段。

随着数据量的变化,段的数量会越来越多,消耗的多文件句柄数及 CPU 就越多,查询效率就会下降。

由于 Lucene 段合并的计算量庞大,会消耗大量的 I/O,所以 ES 默认采用较保守的策略,让后台定期进行段合并。

减少 Refresh 的次数

Lucene 在新增数据时,采用了延迟写入的策略,默认情况下索引的refresh_interval 为1 秒。

Lucene 将待写入的数据先写到内存中,超过 1 秒(默认)时就会触发一次 Refresh,然后 Refresh 会把内存中的的数据刷新到操作系统的文件缓存系统中。

如果我们对搜索的实效性要求不高,可以将 Refresh 周期延长,例如 30 秒。

这样还可以有效地减少段刷新次数,但这同时意味着需要消耗更多的 Heap 内存。

加大 Flush 设置

Flush 的主要目的是把文件缓存系统中的段持久化到硬盘,当 Translog 的数据量达到 512MB 或者 30 分钟时,会触发一次 Flush。

index.translog.flush_threshold_size 参数的默认值是 512MB,我们进行修改。

增加参数值意味着文件缓存系统中可能需要存储更多的数据,所以我们需要为操作系统的文件缓存系统留下足够的空间。

减少副本的数量

ES 为了保证集群的可用性,提供了 Replicas(副本)支持,然而每个副本也会执行分析、索引及可能的合并过程,所以 Replicas 的数量会严重影响写索引的效率。

当写索引时,需要把写入的数据都同步到副本节点,副本节点越多,写索引的效率就越慢。

如果我们需要大批量进行写入操作,可以先禁止Replica复制,设置

index.number_of_replicas: 0 关闭副本。在写入完成后, Replica 修改回正常的状态。

内存设置

ES 默认安装后设置的内存是 1GB,对于任何一个现实业务来说,这个设置都太小了。如果是通过解压安装的 ES,则在 ES 安装文件中包含一个 jvm.option 文件,添加如下命令来设置 ES 的堆大小, Xms 表示堆的初始大小, Xmx 表示可分配的最大内存,都是 1GB。

确保 Xmx 和 Xms 的大小是相同的,其目的是为了能够在 Java 垃圾回收机制清理完堆区后不需要重新分隔计算堆区的大小而浪费资源,可以减轻伸缩堆大小带来的压力。

假设你有一个 64G 内存的机器,按照正常思维思考,你可能会认为把 64G 内存都给ES 比较好,但现实是这样吗, 越大越好?虽然内存对 ES 来说是非常重要的,但是答案是否定的!

因为 ES 堆内存的分配需要满足以下两个原则:

  • 不要超过物理内存的 50%: Lucene 的设计目的是把底层 OS 里的数据缓存到内存中。Lucene 的段是分别存储到单个文件中的,这些文件都是不会变化的,所以很利于缓存,同时操作系统也会把这些段文件缓存起来,以便更快的访问。如果我们设置的堆内存过大, Lucene 可用的内存将会减少,就会严重影响降低 Lucene 的全文本查询性能。

  • 堆内存的大小最好不要超过 32GB:在 Java 中,所有对象都分配在堆上,然后有一个 Klass Pointer 指针指向它的类元数据。这个指针在 64 位的操作系统上为 64 位, 64 位的操作系统可以使用更多的内存(2^64)。在 32 位的系统上为 32 位, 32 位的操作系统的最大寻址空间为 4GB(2^32)。但是 64 位的指针意味着更大的浪费,因为你的指针本身大了。浪费内存不算,更糟糕的是,更大的指针在主内存和缓存器(例如 LLC, L1 等)之间移动数据的时候,会占用更多的带宽。

最终我们都会采用 31 G 设置

-Xms 31g

-Xmx 31g

假设你有个机器有 128 GB 的内存,你可以创建两个节点,每个节点内存分配不超过 32 GB。也就是说不超过 64 GB 内存给 ES 的堆内存,剩下的超过 64 GB 的内存给 Lucene。文章来源地址https://www.toymoban.com/news/detail-758816.html

重要配置

es为什么查询速度快,记录,elasticsearch,大数据,Powered by 金山文档

巧用缓存

es为什么查询速度快,记录,elasticsearch,大数据,Powered by 金山文档

到了这里,关于Elasticsearch为什么快?的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Kafka必须掌握的核心技术:为什么吞吐量大、速度快?

    如果不删除硬盘肯定会被撑满,所以Kakfa提供了两种策略来删除数据。一是基于时间,二是基于partition文件大小。具体配置可以参看它的配置文档。 二、Page Cache 为了优化读写性能,Kafka利用了操作系统本身的Page Cache,就是利用操作系统自身的内存而不是JVM空间内存。这样做

    2024年04月08日
    浏览(41)
  • 入门ElasticSearch :为什么选择ES作为搜索引擎?

    随着数据量的不断增长,搜索和分析大规模数据集变得越来越重要。传统数据库在面对这种需求时往往表现不佳,这时候就需要一种专门用于搜索和分析的引擎。ElasticSearch (简称ES)就是这样一款强大的搜索引擎,它具有许多优势,使得它成为许多企业和开发者的首选。 简

    2024年02月09日
    浏览(36)
  • Windows 程序开机自启动速度优化,为什么腾讯会议自启动速度那么高?

    目录 一、问题的说明和定义 二、问题的分析 1.问题初步分析 2.详细的分析: 2.1Windows常见的自启动方式 2.2Windows常见的自启动方式的细节分析 三、问题的解决方案 1、为什么腾讯会议Rooms那么快 2.我们是否可以跟腾讯会议一样快 这两天有个优化项需要做个技术调研,就是我们

    2024年02月02日
    浏览(78)
  • 为什么有时候ADSL访问速度会很慢

      为什么有时候ADSL访问速度会很慢        1.网卡绑定的协议太多。上网速度慢,在局域网用户中很常见,原因是网卡绑定的协议太多。网卡上如果绑定了许多协议,当数据通过网卡时,计算机就要花费很多时间来确定这个数据使用哪种协议来传送,这时用户就会感觉上网慢

    2024年02月08日
    浏览(36)
  • 阿里云3M固定带宽是什么意思?速度快吗?

    阿里云服务器3M固定带宽是什么意思?速度快吗?3M固定带宽是指云服务器的公网带宽,用于在外网提供服务的,3M带宽的下载速度是384KB/秒,上传速度是1280KB/秒 ,对于个人博客或流量不多的企业官网速度还是挺快的,阿里云服务器网aliyunfuwuqi.com如果是Web网站应用,网站如果

    2024年02月03日
    浏览(28)
  • 为什么删除Windows 11上的Bloatware可以帮助加快你的电脑速度

    如果你感觉你的电脑迟钝,彻底清除软件会有所帮助,而且这个过程对Windows用户来说越来越容易。 微软正在使删除以前难以删除的其他预装Windows应用程序成为可能。专家表示,这项新功能可能会改变用户的游戏规则。 科技公司Infatica的主管Vladimir Fomenko在接受Lifewire电子邮件

    2024年02月10日
    浏览(44)
  • Kafka为什么在消息积压时不能直接通过消费者水平扩容来提升消费速度?

    我们知道当消息生产者生产的速度快于消费者的消费速度时,会产生大量的消息积压,大多数人的想法是增加消费者的数量来提升消费速度,这个想法在RocketMQ中是可行的,但是在Kafka中不一定可行。为了更方便地分析问题,我们先忽略消费者组的设计,在增加消费者之前,架

    2024年01月22日
    浏览(35)
  • 为什么说es是近实时搜索

    首先要理解es的存储结构: 一个index的数据,分散在多个shard(分片),一个分片又有很多segment(段),es是数据不可变模型,更新数据只是新增一个版本。 es是怎么写数据的? 每次写的时候,首先会写到es的内存(每个分片的内存),这时写的数据是不可搜索的;然后每个分片默认每

    2024年02月11日
    浏览(40)
  • Elasticsearch为什么快?

    概括的说,一个优秀的搜索引擎的设计,至少应该具备以下几点要求: 高效的压缩算法 快速的编码和解码算法 合理的数据结构 通用最小化算法 结合以上几点,后面我将通过一个案例来讲解,倒排索引的基本原理是什么。在了解“倒排索引”之前,我们先来看一下何为“索

    2024年02月04日
    浏览(30)
  • 大数据面试题:HBase为什么查询快

    面试题来源: 《大数据面试题 V4.0》 大数据面试题V3.0,523道题,679页,46w字 可回答:1)HBase为什么读快;2)HBase是根据rowkey查询,当数据量相当大的时候,是怎么读的很快的 参考答案: 1、基于LSM树的存储方式 HBase采用基于LSM树的存储方式,这种存储方式将数据分为内存和

    2024年02月12日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包