热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Elasticsearch基础概念之基本原理

ES基本原理名词解释In-memorybuffer:ES内存缓冲区,新建的document写入的地方document:索引和搜索的
ES基本原理

名词解释

In-memory buffer: ES内存缓冲区,新建的document写入的地方

document:索引和搜索的主要数据载体,对应写入到ES中的一个doc

Segment: Lucene里面的一个数据集概念,前边提到的document最终就是存放在这里边,一个Segment包含多个document

Refresh:将In-memory buffer中的数据生成一个segment并放入系统缓存区,同时清空In-memory buffer

Translog: 新建的document也会写入到这个里边,记录这些日志,并用于回放

Flush:会先执行一次refresh操作,之后将系统缓存区中的一个一个Segment拷贝到磁盘中,之后清空translog

Refresh过程

新建的document会先写进ES内存缓冲区中,但是这个区域是不可见的,不能被搜索到,所以Refresh的过程就是产生一个segment放入系统缓存区,这部分区域是可读的,可以被搜索到。在默认情况下ES每隔1秒钟,会自动Refresh,保证数据可见。

Refersh的执行条件:

  1. 手动触发,通过GET查询以及index、bulk写入时指定refresh
  2. 自动触发,配置refresh_interval
  3. In-memory buffer满了

可以更改这个配置

改为10秒

POST /index/_settings
{“refresh_interval”: “10s”}

改为不自动更新

POST /index/_settings
{“refresh_interval”: “-1″}

Segment合并

由于每一次refresh都会新建一个Segment,那么随着refresh次数越来越多,segment文件也会越来越多,而每一次查询最终都会检索segment文件,每一个segment都会占用操作系统的CPU、文件句柄和内存资源,而且,在查询的时候,需要在每个segment上都执行一次查询,这样是很消耗性能的。

为了解决这个问题,es会自动定期的将多个小segment合并为一个大的segment,这次合并是真正意义上的物理删除。

当新合并后的segment完全写入磁盘之后,es就会自动删除掉那些零碎的segment,之后的查询都在新合并的segment上执行。Segment的合并会消耗大量的IO和cpu资源,这会影响查询性能。

下面是几个常用配置项

  1. index.merge.policy.floor_segment:该属性用于阻止碎片段的频繁刷新。小于或者等于该设定值的段将考虑被合并。默认值为2M。
  2. index.merge.policy.max_merge_at_once:该属性指定了索引过程中同一时刻用于合并的段的最大数量,默认为10。如果将值设置得更大,一次合并操作将合并更多的段,同时合并过程也需要更多的I/O资源。
  3. index.merge.policy.max_merged_segment:默认值为5GB,该属性指定了索引过程中单个段的最大容量。这个值是一个近似值,因为合并操作中,段的大小等于待合并段的总大小减去各个段中删除文档的大小。
  4. index.merge.policy.segments_per_tier:该属性指定了每层段的数量。较小的值带来较少的段。这意味着更多的合并操作,和更低索引性能。默认值为10,其值应该不低于index.merge.policy.max_merge_at_once属性值,否则就会使合并次数过多,引起性能问题。

Translog与Flush

由于Refresh操作将数据放入到内存中,而内存中的不保险,所以就会把每一条document新建和更新记录得translog中,这样如果出现意外情况,可以从translog中找到这部分数据,并进行恢复。然后会通过Flush操作,将这部分数据内存中的数据,写入磁盘里,也为了避免translog太大,同时情空该部分数据。

Flush的具体流程:

  1. 将系统缓存区里的一个一个segment写入到磁盘中
  2. 执行一次refresh操作
  3. 清空translog日志

具体源码如下:

// Only flush if (1) Lucene has uncommitted docs, or (2) forced by caller, or (3) the
// newly created commit points to a different translog generation (can free translog)
if (indexWriter.hasUncommittedChanges() || force || shouldPeriodicallyFlush()) {
    ensureCanFlush();
        try {
            translog.rollGeneration();
            logger.trace("starting commit for flush; commitTranslog=true");
            //将系统缓存区里的一个一个segment写入到磁盘中
            commitIndexWriter(indexWriter, translog, null);
            logger.trace("finished commit for flush");
            //执行一次refresh操作
            refresh("version_table_flush", SearcherScope.INTERNAL);
            //清空translog日志
            translog.trimUnreferencedReaders();
        } catch (AlreadyClosedException e) {
            throw e;
        } catch (Exception e) {
            throw new FlushFailedEngineException(shardId, e);
        }
         refreshLastCommittedSegmentInfos();

}

该段源码很好解释了执行flush的三个内部条件

  1. Lucene中有未提交的文档
  2. 强制调用
  3. 定期执行

ES默认配置中,translog的配置同flush进行绑定,每一次index、bulk这些写入更新操作,都会先flush然后返回200,但是这种配置会牺牲很大的性能,可以采用异步刷新的方式,并配置每隔几秒进行刷新,来提高写入性能。

注意:该操作要先关闭索引,才能执行

PUT /index/_settings
{
    "index.translog.durability": "async",
    "index.translog.sync_interval": "5s"
}

Flush执行条件:

  1. 默认配置下(index.translog.flush_threshold_period),每30分钟进行一次
  2. 当translog的大小超过设定值(index.translog.flush_threshold_size),默认是512MB
  3. 多少时间间隔内(index.translog.interval:多少时间间隔内会检查一次translog,来进行一次flush操作。es会随机的在这个值到这个值的2倍大小之间进行一次操作,默认是5s。)会检查一次translog,来进行一次flush操作。es会随机的在这个值到这个值的2倍大小之间进行一次操作,默认是5s。

近实时搜索与实时搜索

看过上边的Refresh操作,可以得知,在默认情况下,每隔一秒进行一次refresh操作,写入的docment才可以搜索出来,这是准实时的原因。但是ES也提供了实时搜索的功能。下面就是两种实时搜索的操作。

  1. GET查询
  2. 写入时同步执行refresh操作再返回200

这两种操作的原理都是手动执行refresh操作,保证数据从In-memory buffer写入到系统缓存区,但是这种操作,相比每秒或者定时刷新refresh,在性能上的开销是很大的,相当于每一次请求就会执行一次refresh操作,生成一个新的segment,完全没有用到In-memory buffer这个缓冲区。


推荐阅读
  • Spring Boot与Graylog集成实现微服务日志聚合与分析
    本文介绍了如何在Graylog中配置输入源,并详细说明了Spring Boot项目中集成Graylog的日志聚合和分析方法,包括logback.xml的多环境配置。 ... [详细]
  • 本文将介绍如何编写一些有趣的VBScript脚本,这些脚本可以在朋友之间进行无害的恶作剧。通过简单的代码示例,帮助您了解VBScript的基本语法和功能。 ... [详细]
  • 1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ... [详细]
  • 本文详细介绍了优化DB2数据库性能的多种方法,涵盖统计信息更新、缓冲池调整、日志缓冲区配置、应用程序堆大小设置、排序堆参数调整、代理程序管理、锁机制优化、活动应用程序限制、页清除程序配置、I/O服务器数量设定以及编入组提交数调整等方面。通过这些技术手段,可以显著提升数据库的运行效率和响应速度。 ... [详细]
  • 本文将详细介绍如何在没有显示器的情况下,使用Raspberry Pi Imager为树莓派4B安装操作系统,并进行基本配置,包括设置SSH、WiFi连接以及更新软件源。 ... [详细]
  • 本文介绍如何使用Java实现AC自动机(Aho-Corasick算法),以实现高效的多模式字符串匹配。文章涵盖了Trie树和KMP算法的基础知识,并提供了一个详细的代码示例,包括构建Trie树、设置失败指针以及执行搜索的过程。 ... [详细]
  • 在安装并配置了Elasticsearch后,我在尝试通过GET /_nodes请求获取节点信息时遇到了问题,收到了错误消息。为了确保请求的正确性和安全性,我需要进一步排查配置和网络设置,以确保Elasticsearch集群能够正常响应。此外,还需要检查安全设置,如防火墙规则和认证机制,以防止未经授权的访问。 ... [详细]
  • 如何在PHPCMS V9中实现多站点功能并配置独立域名与动态URL
    本文介绍如何在PHPCMS V9中创建和管理多个站点,包括配置独立域名、设置动态URL,并确保各子站能够正常运行。我们将详细讲解从新建站点到最终配置路由的每一步骤。 ... [详细]
  • 本文详细解析了Python中的os和sys模块,介绍了它们的功能、常用方法及其在实际编程中的应用。 ... [详细]
  • 本文详细介绍了macOS系统的核心组件,包括如何管理其安全特性——系统完整性保护(SIP),并探讨了不同版本的更新亮点。对于使用macOS系统的用户来说,了解这些信息有助于更好地管理和优化系统性能。 ... [详细]
  • 使用Vultr云服务器和Namesilo域名搭建个人网站
    本文详细介绍了如何通过Vultr云服务器和Namesilo域名搭建一个功能齐全的个人网站,包括购买、配置服务器以及绑定域名的具体步骤。文章还提供了详细的命令行操作指南,帮助读者顺利完成建站过程。 ... [详细]
  • Hadoop入门与核心组件详解
    本文详细介绍了Hadoop的基础知识及其核心组件,包括HDFS、MapReduce和YARN。通过本文,读者可以全面了解Hadoop的生态系统及应用场景。 ... [详细]
  • 本文详细分析了在设计留言管理系统时,如何利用Lucene进行索引和搜索的需求分析。主要内容包括索引目标、索引对象以及搜索业务需求。 ... [详细]
  • (1)XML预处理读取test.xml并修改url节点下的localhost信息,以保证预览和下载用户所需正确资源。过程如下: ... [详细]
  • 性能优化_多索引下的Lucene性能优化
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了多索引下的Lucene性能优化相关的知识,希望对你有一定的参考价值。 ... [详细]
author-avatar
huateng
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有