【Elasticsearch】Elasticsearch中FST的Off-Heap优化详解

转自:https://www.easyice.cn/archives/346

前言

一直以来,Elasticsearch(ES)堆内存中占据比重最大的是 FST,即 .tip(terms index)文件。这些文件占据的空间很大,1TB 的索引大约需要 2GB 或更多的内存。为了确保节点稳定运行,业界通常认为一个节点打开的索引不应超过 5TB。

从 ES 7.3 版本开始,.tip 文件被修改为通过 mmap 的方式加载,这使得 FST 占据的内存从堆内转移到了堆外,由操作系统的 page cache 管理。

参考 ES 7.3 的 release notes:

Also mmap terms index (.tip) files for hybridfs #43150 (issue: #42838)

现在,我们来深入探讨其中的一些细节。

hybridfs 的工作原理

hybridfs 是索引默认的 store 类型,它根据操作系统类型自动选择 nio 或者 mmap。那么究竟哪些文件被 mmap 方式打开呢?手册中提到:

Currently only the Lucene term dictionary, norms and doc values files are memory mapped. All other files are opened using Lucene NIOFSDirectory.

对应到文件扩展名,就是 .nvd(norms)、.dvd(doc values)、.tim(term dictionary)、.tip(term index)、.cfs(compound)类型的文件使用 mmap 方式加载,其余使用 nio

switch(extension) {case "nvd":case "dvd":case "tim":case "tip":case "cfs":return true;default:return false;
}

为什么使用 mmap 实现 Off-Heap

你可能会问,为什么把 .tip 文件通过 mmap 方式读取就实现了 Off-Heap?像 HBase 实现 Off-Heap 需要将数据转移到堆外的数据结构,为什么 ES 不需要?

FST 的查找过程

在堆内存(On-Heap)的情况下,Lucene 将 .tip 文件的数据读进一个数组。在 FST 查找时,seek 到某个位置,读取一些字节,然后再次 seek,再读取,相当于边读取边解析。

private Arc<T> findTargetArc(BytesReader in, ...) {// ...in.setPosition(follow.target);arc.numArcs = in.readVInt();arc.bytesPerArc = in.readVInt();arc.posArcsStart = in.getPosition();arc.nextArc = arc.posArcsStart;// ...
}

在 On-Heap 的情况下,这个 BytesReader 的初始化就是简单地将文件读进数组:

public void init(DataInput in, long numBytes) {bytesArray = new byte[(int) numBytes];in.readBytes(bytesArray, 0, bytesArray.length);
}

因此,在 Off-Heap 的情况下,mmap 像数组一样读取就可以了。

如何查看文件的缓存情况

如果想要查看文件被 page cache 缓存的百分比,可以使用以下工具:

  • vmtouch(推荐)
  • pcstat
  • hcache
  • fincore

要确认某个 .tip 文件是否被 mmap 方式读取的,可以使用 pmap 命令,被 mmap 映射的文件会在这里列出来。

Off-Heap 后的效果

使用 geonames 数据集写入索引 1TB,使用 _cat/segments API 查看 segments.memory 内存占用量,对比 Off-Heap 后的内存占用效果:

store.typesegments.memory
niofs4.7GB
hybridfs1.06GB

JVM 内存占用量降低了约 78%。不同数据样本结果不同,其他的可能会降低更多。

通过 _cat/segments 观测到的 segments.memory 指标,会比实际占用的 JVM 内存少一些,不过相差不大,上述结果可作为参考。

Page Cache 的管理

由于 Off-Heap 后的堆外内存由操作系统的 page cache 管理,什么时候被驱逐出去由操作系统决定,进程无法控制。如果 .tip 文件的内容被驱逐出 page cache,对 FST 的查找会涉及到磁盘 IO,对查询延迟有比较大的影响。

Page Cache 的回收策略

Linux 系统的 page cache 回收有两种情况:

  1. 系统内存不足时的自动回收:当系统可用内存不足时,系统会自动回收 page cache 缓存的数据,其中可能包括 mmap 映射的 .tip 文件。
  2. 手工回收:通过改写 /proc/sys/vm/drop_cachesposix_fadvise 调用来手工回收。

当索引处于打开(open)状态时,由 mmap 映射到 page cache 的 .tip 数据并不会被回收;而如果索引处于关闭(close)状态,则会被完全回收。

Page Cache 的回收算法

在 Linux 2.6.34 的内核中,对 page cache 的回收策略使用双链策略,参考《Linux 内核设计与实现(第三版)》。算法描述大致如下:

  • 引入两个链表:active listinactive list
  • 两个链表都是从尾部加入,头部移出。
  • 页面换出操作只在 inactive list 执行。
  • 对于文件缓存,当第一次访问的时候加入到 inactive list,再次访问的时候把它提升到 active list
  • active list 大小大于 inactive list,就将 active list 头部的页面降级到 inactive list

更多 page cache 的信息可以参考 Linux MM Page Replacement Design。

mmap 的原理

依据 mmap 的原理,文件描述符(fd)被映射为指针(或者说字节数组)供进程直接访问,仅在进程访问到相应位置的时候才去读取磁盘,是根据内容按需读取磁盘。

你可能会想,既然如此,_open 索引是不是变快了?原来 nio 需要把整个文件读进堆内存,现在 mmap 一下就结束了,那么等索引首次被查询的时候才会加载到 page cache?实际上,_open 索引并没变快,因为在 _open 索引的过程中,Lucene 会检查文件的校验和,把整个文件读取一遍:

// BlockTreeTermsReader constructor
CodecUtil.checksumEntireFile(indexIn);
ChecksumIndexInput in = new BufferedChecksumIndexInput(clone);
// 读取文件到目标位置,并更新校验和
in.seek(in.length() - footerLength());
return checkFooter(in);

关于 _id 字段的 Off-Heap 问题

Lucene 支持字段级的 Off-Heap 设置。ES 7.3 中将 .tip Off-Heap 时并不包含 _id 字段,#52518 中提到,这是因为担心降低写入速度。不过在经历了一些测试之后发现影响并不大。

一般来说,只有在使用显式 IDs 时,索引速率才会受到影响,因为否则 Elasticsearch 几乎不会在索引过程中查找 terms dictionary。因此,强制将 _id 字段的 terms index 保持在堆内存中,对于那些具有仅追加工作负载的用户来说是相当浪费的。此外,我使用 http_logs 数据集在索引时进行了基准测试,结果表明,即使在使用显式 IDs 的情况下,速度下降也足够小,可能不值得强制将 terms index 保持在堆内存中。

题外话:这段内容提到,使用外部 doc id 方式入库时需要从 term dictionary 中查询,这是因为使用外部 ID 写入时,ES 需要判断该 ID 是否存在,以便执行更新(update)或追加(append)操作。因此在分片中对 _id 字段执行 Lucene 的 seekExact 查询来判断此 ID 是否存在,所以使用外部 ID 入库时写入速度会降低一些(约 20%)。这也是 _id 字段需要写入 FST 的一个原因。

在将 _id 字段 Off-Heap 之后,使用 http_logs 数据集和外部 ID 的方式执行写入测试,写入速度降低了 1.8%,JVM 内存降低了 100 倍。

因此,在 ES 7.7 版本中,会将 _id 字段也放到堆外。

结语

把 FST 放到堆外可以让节点能够持有更多的数据,这对 ES 集群能处理的数据规模有重大提升,意义重大。但是 .tip 文件需要加载到内存的意义比 .tim 等文件要重要得多,page cache 总会有需要回收的时候,谁能保证 .tip 不被回收呢?所以总体来说,可能会让查询延迟增加不确定性,且不便重现和诊断。不过也不用太担心,这种情况一般很少发生。

参考资料

  • Elasticsearch Issue #38390
  • Elasticsearch Pull Request #42838
  • Elasticsearch Pull Request #43150
  • Elasticsearch Pull Request #52518
  • Elasticsearch 7.3.0 Release Notes
  • Linux MM Page Replacement Design

转自:https://www.easyice.cn/archives/346

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/883642.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Mybatis-14.XML映射文件

一.XML映射文件 除了使用注解的方式完成mybatis基础的增删改查操作以外&#xff0c;还可以使用基于XML文件配置SQL语句。 二.配置XML映射文件 首先在resources中新建文件夹com/域名/mapper用来和java源代码中的包名保持一致&#xff0c;这是同包。 然后在mapper文件夹中新建x…

详解Pectra升级:如何影响以太坊价值及利益相关者

Pectra很可能是最后几个会直接影响用户和ETH持有者的升级之一。 原文&#xff1a;Galaxy Research&#xff1b;编译&#xff1a;Golem&#xff1b;编辑&#xff1a;郝方舟 出品 | Odaily星球日报&#xff08;ID&#xff1a;o-daily&#xff09; 编者按&#xff1a;以太坊 Pectr…

「C/C++」C++17 之 std::variant 安全的联合体(变体)

#1024程序员节&#xff5c;征文# ✨博客主页何曾参静谧的博客&#x1f4cc;文章专栏「C/C」C/C程序设计&#x1f4da;全部专栏「VS」Visual Studio「C/C」C/C程序设计「UG/NX」BlockUI集合「Win」Windows程序设计「DSA」数据结构与算法「UG/NX」NX二次开发「QT」QT5程序设计…

windows 训练yolov8官方数据集

第一步&#xff1a;安装Anaconda3-2024.06-1-Windows-x86_64.exe 下载地址&#xff1a;https://repo.anaconda.com/archive/ 第二步&#xff1a;创建环境 打开Anaconda Prompt 输入 conda info -e 打印&#xff1a; 已经安装了一些环境&#xff0c;然后我们创建新的环境&a…

Linux(kali)换源操作

apt换源 &#xff08;切换到国内源&#xff09; 阿里云Kali镜像源 deb http://mirrors.aliyun.com/kali kali-rolling main non-free non-free-firmware contrib deb-src http://mirrors.aliyun.com/kali kali-rolling main non-free non-free-firmware contrib 1.切换为root用…

springboot095学生宿舍信息的系统--论文pf(论文+源码)_kaic

学生宿舍信息管理系统 摘要 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的实施在技术上已逐步成熟。本文介绍了学生宿舍信息管理系统的开发全过程。通过分析学生宿舍信息管理系统管理的不足&#xff0c;创建了一个计算机管理学生宿舍信息管理系统的方…

lstio微服务治理-概述

一、Service Mesh介绍 Service Mesh 的中文译为&#xff1a;服务网格&#xff0c;是一个用于处理服务和服务之间通信的基础设施层。它负责为构建复杂的云原生应用传递可靠的网络请求&#xff0c;并为服务通信实现了微服务所需要的基本组件功能&#xff0c;如&#xff1a;服务发…

哈尔滨银行难以摆脱低估值,不良贷款突破100亿元,何时回A?

撰稿 | 芋圆 来源 | 贝多财经 在经济缓慢恢复的步调中&#xff0c;多数理财者倾向于选择更为保守的资产分配策略&#xff0c;但部分银行在竞争加剧&#xff0c;净息差持续收窄的压力下&#xff0c;却将业务转型的矛头对准了风险更高的金融投资领域&#xff0c;哈尔滨银行就是…

基础知识-因果分析-daythree-独立性检验

我们经常需要观察一个事件的发生对另一个事件的发生是否有影响。有时候&#xff0c;我们可以观察到一个事件的发生对另一个事件发生的概率有影响。比如&#xff0c;你驾车超速这个事件的发生会增加你发生交通事故的概率。但是&#xff0c;有时候我们也可以观察到&#xff0c;一…

SpringMVC6-SpringMVC的视图

目录 ThymeleafView 转发视图 重定向视图 视图控制器view-controller SpringMVC中的视图是View接口&#xff0c;视图的作用&#xff1a;渲染数据&#xff0c;将模型Model中的数据展示给用户 SpringMVC视图的种类很多&#xff0c;默认有转发视图InternalResourceView 和重定…

【再谈设计模式】单例模式~唯一性的守护者

一、引言 在软件工程中&#xff0c;软件开发&#xff0c;设计模式是提高代码复用性和可维护性的有效工具。单例模式&#xff08;Singleton Pattern&#xff09;作为一种创建型设计模式&#xff0c;旨在确保一个类只有一个实例&#xff0c;并提供对该实例的全局访问。这一模式在…

Spring Boot 实现文件上传下载功能

文章目录 一、原理分析1.1 请求类型1.2 服务器解析 二、功能实现2.1 创建项目并导入依赖2.2 文件上传功能实现2.2.1 文件上传 Service2.2.2 文件上传 Controller 2.3 文件下载功能实现2.3.1 文件下载 Service2.3.2 文件下载 Controller 2.4 文件上传前端代码(可选)2.4.1 上传文…

HarmonyOS Next API12最新版 端云一体化开发-云函数篇

一、新建一个端云一体化项目 见文章&#xff1a; HarmonyOS NEXT API12最新版 端云一体化开发-创建端云一体化项目流程_鸿蒙appapi-CSDN博客 二、官方文档 使用限制-云函数 - 华为HarmonyOS开发者 (huawei.com) Cloud Foundation Kit简介-Cloud Foundation Kit&#xff0…

深度学习:SGD的缺点

首先看下述函数&#xff1a; 最小值为x0&#xff0c;y0处 先了解下它的梯度特征。了理解其梯度特征&#xff0c;我们需要计算其梯度向量。 梯度向量 ∇f 是函数 f 在每个变量方向上的偏导数组成的向量。具体来说&#xff1a; ∇f(∂f/∂x,∂f∂/y) 首先&#xff0c;我们计算 f …

【北京迅为】《STM32MP157开发板嵌入式开发指南》-第六十七章 Trusted Firmware-A 移植

iTOP-STM32MP157开发板采用ST推出的双核cortex-A7单核cortex-M4异构处理器&#xff0c;既可用Linux、又可以用于STM32单片机开发。开发板采用核心板底板结构&#xff0c;主频650M、1G内存、8G存储&#xff0c;核心板采用工业级板对板连接器&#xff0c;高可靠&#xff0c;牢固耐…

Qt | windows视频播放器小项目

点击上方"蓝字"关注我们 01、前言 >>> Windows平台如果播放不了视频,记得下载编解码工具:https://www.mediaplayercodecpack.com/#google_vignette media.player.codec.pack.v4.6.0.setup.exe 下载后双击安装。 02、videowidget.pro >>> (.pro…

Android Activity SingleTop启动模式使用场景

通知栏 当用户点击通知栏中的通知时,可以使用单顶启动模式来打开对应的活动,并确保只有一个实例存在。 简单集成极光推送 创建应用 获取appkey参数 切换到极光工作台 极光sdk集成 Project 根目录的主 gradle 配置 Module 的 gradle 配置 Jpush依赖配置 配置推送必须…

ssm基于vue框架和elementui组件的手机官网+vue

系统包含&#xff1a;源码论文 所用技术&#xff1a;SpringBootVueSSMMybatisMysql 免费提供给大家参考或者学习&#xff0c;获取源码请私聊我 需要定制请私聊 目 录 目 录 III 1 绪论 1 1.1 研究背景 1 1.2 目的和意义 1 1.3 论文结构安排 2 2 相关技术 3 2.1 SSM框…

【Android】perfetto使用学习

在开发者选项中的系统跟踪里抓取的perfetto文件是保存在/data/local/traces 里的 adb pull /data/local/traces ./ 主线程中的执行是受vsync信号控制的&#xff0c;即间隔调用的 如果写一个while线程&#xff0c;一直使用cpu&#xff0c;是怎样的呢&#xff0c;这里我们来试验一…

技术周总结 10.21~10.27周日

文章目录 一、10.24 周四 程序员节2.1&#xff09;问题01&#xff1a; Memory Analysis Tool的使用方法 二、10.27 周日2.1&#xff09; J2EE架构J2EE 的核心组件与技术J2EE 的多层架构J2EE 的优缺点J2EE 的应用场景 2.2&#xff09;web应用开发中的 "web服务器" 和 …