热门标签 | 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这个缓冲区。


推荐阅读
  • 1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ... [详细]
  • PHP 编程疑难解析与知识点汇总
    本文详细解答了 PHP 编程中的常见问题,并提供了丰富的代码示例和解决方案,帮助开发者更好地理解和应用 PHP 知识。 ... [详细]
  • 如何在PHPCMS V9中实现多站点功能并配置独立域名与动态URL
    本文介绍如何在PHPCMS V9中创建和管理多个站点,包括配置独立域名、设置动态URL,并确保各子站能够正常运行。我们将详细讲解从新建站点到最终配置路由的每一步骤。 ... [详细]
  • 本文详细介绍了优化DB2数据库性能的多种方法,涵盖统计信息更新、缓冲池调整、日志缓冲区配置、应用程序堆大小设置、排序堆参数调整、代理程序管理、锁机制优化、活动应用程序限制、页清除程序配置、I/O服务器数量设定以及编入组提交数调整等方面。通过这些技术手段,可以显著提升数据库的运行效率和响应速度。 ... [详细]
  • 全面解析运维监控:白盒与黑盒监控及四大黄金指标
    本文深入探讨了白盒和黑盒监控的概念,以及它们在系统监控中的应用。通过详细分析基础监控和业务监控的不同采集方法,结合四个黄金指标的解读,帮助读者更好地理解和实施有效的监控策略。 ... [详细]
  • ElasticSearch 集群监控与优化
    本文详细介绍了如何有效地监控 ElasticSearch 集群,涵盖了关键性能指标、集群健康状况、统计信息以及内存和垃圾回收的监控方法。 ... [详细]
  • 本文将详细介绍如何在没有显示器的情况下,使用Raspberry Pi Imager为树莓派4B安装操作系统,并进行基本配置,包括设置SSH、WiFi连接以及更新软件源。 ... [详细]
  • 使用Vultr云服务器和Namesilo域名搭建个人网站
    本文详细介绍了如何通过Vultr云服务器和Namesilo域名搭建一个功能齐全的个人网站,包括购买、配置服务器以及绑定域名的具体步骤。文章还提供了详细的命令行操作指南,帮助读者顺利完成建站过程。 ... [详细]
  • 深入探讨CPU虚拟化与KVM内存管理
    本文详细介绍了现代服务器架构中的CPU虚拟化技术,包括SMP、NUMA和MPP三种多处理器结构,并深入探讨了KVM的内存虚拟化机制。通过对比不同架构的特点和应用场景,帮助读者理解如何选择最适合的架构以优化性能。 ... [详细]
  • 本文探讨了如何在 PHP 的 Eloquent ORM 中实现数据表之间的关联查询,并通过具体示例详细解释了如何将关联数据嵌入到查询结果中。这不仅提高了数据查询的效率,还简化了代码逻辑。 ... [详细]
  • 本文详细介绍了Python编程语言的学习路径,涵盖基础语法、常用组件、开发工具、数据库管理、Web服务开发、大数据分析、人工智能、爬虫开发及办公自动化等多个方向。通过系统化的学习计划,帮助初学者快速掌握Python的核心技能。 ... [详细]
  • 本文深入探讨了HTTP请求和响应对象的使用,详细介绍了如何通过响应对象向客户端发送数据、处理中文乱码问题以及常见的HTTP状态码。此外,还涵盖了文件下载、请求重定向、请求转发等高级功能。 ... [详细]
  • 在安装Oracle 11g时,CentOS 6.5系统提示交换空间不足。本文详细介绍了如何通过两种方法增加交换空间,并提供了具体步骤和命令,帮助用户解决这一问题。 ... [详细]
  • 在高并发需求的C++项目中,我们最初选择了JsonCpp进行JSON解析和序列化。然而,在处理大数据量时,JsonCpp频繁抛出异常,尤其是在多线程环境下问题更为突出。通过分析发现,旧版本的JsonCpp存在多线程安全性和性能瓶颈。经过评估,我们最终选择了RapidJSON作为替代方案,并实现了显著的性能提升。 ... [详细]
  • 深入理解Java多线程并发处理:基础与实践
    本文探讨了Java中的多线程并发处理机制,从基本概念到实际应用,帮助读者全面理解并掌握多线程编程技巧。通过实例解析和理论阐述,确保初学者也能轻松入门。 ... [详细]
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社区 版权所有