深入解读 Elasticsearch 磁盘水位设置
本文将带你通过查看 Elasticsearch 源码来了解磁盘使用阈值在达到每个阶段的处理情况。
跳转文章末尾获取答案

环境
本文使用 Macos 系统测试,512M 的磁盘,目前剩余空间还有 60G 左右,所以按照 Elasticsearch 的设定,ES 中分片应该是无法分配的。
- MacOS 14.1.1
- Elasticsearch 8.1 源码启动
启动的源码已经上传 GitHub:https://github.com/zuiyu-main/elasticsearch

一、场景复现
1.1、启动 Elasticsearch
打印日志中出现如下提示:已经超过95%的洪水水位设置,当前节点的全部索引都将是只读状态。
[2024-02-28T21:55:08,682][WARN ][o.e.c.r.a.DiskThresholdMonitor] [node-1] flood stage disk watermark [95%] exceeded on [t5hKtM6PT3amCCT7xzqgMg][node-1][/cxt/codework/github/elasticsearch/8.1/home/data] free: 15gb[3.2%], all indices on this node will be marked read-only

1.2、当前节点索引状态

可以看到,当前 Elasticsearch 集群是单节点,且只有一个普通索引与一个geo的索引。
1.3、发送创建索引请求
发送 http 请求,创建一篇文档,如果当前索引不存在时自动创建索引。

http://127.0.0.1:9200/index1/_doc/1{"name": "zuiyu1","title": "title1","cn": "测试"
}
1.4、查看日志输出
提示集群健康状态从黄色变为红色,磁盘已经超过洪水水位 95%。
[2024-02-28T22:01:55,921][INFO ][o.e.c.r.a.AllocationService] [node-1] current.health="RED" message="Cluster health status changed from [YELLOW] to [RED] (reason: [auto-create])." previous.health="YELLOW" reason="auto-create"
[2024-02-28T22:02:08,996][WARN ][o.e.c.r.a.DiskThresholdMonitor] [node-1] flood stage disk watermark [95%] exceeded on [t5hKtM6PT3amCCT7xzqgMg][node-1][/cxt/codework/github/elasticsearch/8.1/home/data] free: 14.9gb[3.2%], all indices on this node will be marked read-only
源码中关于水位相关的三个参数默认值见下图。

1.5、查看索引分片状态
通过查看当前集群索引状态,可以看出,我们刚刚新增的索引 index1 分片是没有进行分配的。

到了这,还记得我们的问题吗,就是说 Elasticsearch 是怎么判定的磁盘超出设定的阈值的呢?既然复现了我们的场景,下面就让我们一起去源码中查找答案吧。
二、源码中获取答案
2.1、定位代码位置
首先我们还是根据打印的日志,定位到输出这行日志的类,也就是DiskThresholdMonitor,然后根据打印日志中的关键字flood stage disk watermark,可以看到,当前类中出现了两次,根据日志打印的其他信息不难发现,对于此处就是205行。

2.2、跟踪代码获取值
顺着这句代码往上走,看到 189 行有个 if 判断,相信就是这了,我的感觉来了,没想到这个找起来这么简单。
下面我们逐个参数进行分析。
usage.getFreeBytes()
进入 getFreeBytes 这个方法,在本类搜索 freeBytes ,找到 set 此参数的位置或者构造函数给值的位置

往上看到是在 39 行的 DiskUsage 方法中设定的值,那么我们在 37 行方法的开头打一个断点,重启之后,进入断点之后的值如下。

然后在看左下角的 debugger 处,此处就是我们的调用栈。
是的你没猜错,通过这个位置你就可以知道是哪个方法调用的这,我们点一下fillDiskUsagePerNode。

就进入了 InternalClusterInfoService 的 fillDiskUsagePerNode 处,从这基本就可以看出来 usage.getFreeBytes()就是获取了当前磁盘的可用空间。

顺着代码往上走,就可以找到在哪里给leastAvailablePath赋值的地方了,感兴趣的可以按照此方法找一下。

按照上面该方法,继续查询剩下三个参数的值。
diskThresholdSettings.getFreeBytesThresholdFloodStage().getBytes()
获取当前系统磁盘可用空间洪水水位阈值。

usage.getFreeDiskAsPercentage()
获取磁盘可用空间占用总磁盘空间的百分比。

diskThresholdSettings.getFreeDiskThresholdFloodStage()
根据洪水阈值百分比阈值设置,获取当前磁盘可用空间占用总磁盘空间的百分比。

2.3、逻辑判断
其实上面的代码很简单就是一个 if-else ,所以我们很轻松的就看到了判断逻辑:
当磁盘可用空间 小于 设定的可用磁盘空间洪水水位阈值时(byte)或者磁盘可用空间占用总磁盘的百分比 小于 设定的可用空间占用总磁盘的百分比(double)阈值。
对于百分比不了解的看下图。
可用空间百分比 = 100 - 洪水水位阈值设定的百分比(已用空间占用百分比)

需要注意的是:我们可以看到
if判断是两个或条件,支持byte与double两种形式,但是yml文件中指定值时需要固定一种格式,都是百分比形式或者都是byte形式。byte是可用磁盘空间,double是已用磁盘空间。
cluster.routing.allocation.disk.watermark.low: 400g
cluster.routing.allocation.disk.watermark.high: 350g
cluster.routing.allocation.disk.watermark.flood_stage: 10g// 两种配置形式固定一种cluster.routing.allocation.disk.watermark.low: 85%
cluster.routing.allocation.disk.watermark.high: 90%
cluster.routing.allocation.disk.watermark.flood_stage: 95%
对于另外的两个参数
cluster.routing.allocation.disk.watermark.high与cluster.routing.allocation.disk.watermark.low,也可以按照上述方式查找。
下面我们就一起来看看 Elasticsearch 对这些值做了判断之后究竟做了什么
?
源码图中的注释来源于翻译,未修正,仅供参考
low

默认 85%,也就是说 Elasticsearch 不会将分片分配给超过 85% 的节点。
该设置对新创建的索引主分片不生效,只会影响副本分片的分配。
high

默认 90%,Elasticsearch 会将磁盘使用率高于 90% 的节点上的分片重新分配。
不管之前分片是否分配过,该设置会影响所有分片的分配。
flood

默认 95%,Elasticsearch 会将磁盘使用率超过 95%节点上的分片设置为只读索引。
防止磁盘空间耗尽最后的手段。当磁盘低于
high水位时,索引块自动释放。
官网中是这样说的。

三、总结
通过上面的实验,我们知道了当磁盘水位达到low阈值时,对于新创建的索引主分片不影响,副本分片受影响;当磁盘水位达到high时,会影响所有分片的分配;当磁盘水位达到flood时,会将所有的索引设置为只读。
对于上面的分片未分配的可以查看历史文章
索引分片未分配解决
Reroute Api 使用
索引分片分配策略
对于 Elasticsearch 中怎么设置索引为只读的?如何取消主分片、副本分片分配的?
感觉写的还可以欢迎点个关注,后面为你揭秘。
如果写的有误,欢迎指出,你的建议就是大家前进的动力。
四、参考链接
https://www.elastic.co/guide/en/elasticsearch/reference/8.1/modules-cluster.html#disk-based-shard-allocation
https://www.elastic.co/guide/en/elasticsearch/reference/8.1/modules-cluster.html
相关文章:
深入解读 Elasticsearch 磁盘水位设置
本文将带你通过查看 Elasticsearch 源码来了解磁盘使用阈值在达到每个阶段的处理情况。 跳转文章末尾获取答案 环境 本文使用 Macos 系统测试,512M 的磁盘,目前剩余空间还有 60G 左右,所以按照 Elasticsearch 的设定,ES 中分片应…...
M1电脑 Xcode15升级遇到的问题
遇到四个问题 一、模拟器下载经常报错。 二、Xcode15报错: SDK does not contain libarclite 三、报错coreAudioTypes not found 四、xcode模拟器运行一次下次必定死机 一、模拟器下载经常报错。 可以https://developer.apple.com/download/all/?qios 下载最新的模拟器&…...
软考 系统架构设计师之回归及知识点回顾(3)
接前一篇文章:软考 系统架构设计师之回归及知识点回顾(2) 继续回顾一下之前已经介绍和讲解过的系统架构设计师中的知识点: 7. 净室软件工程 净室(Cleaning Room)软件工程是一种应用数学与统计学理论&…...
探索stable diffusion的奇妙世界--01
目录 1. 理解prompt提示词: 2. Prompt中的技术参数: 3. Prompt中的Negative提示词: 4. Prompt中的特殊元素: 5. Prompt在stable diffusion中的应用: 6. 作品展示: 在AI艺术领域,stable di…...
C语言数组的维数该如何理解?
一、问题 什么叫做维,维是不是数组中数的个数呢? 二、解答 维数是数组元素的下标个数。使⽤数组的时候,如果只有⼀个下标,则称为⼀维数组,⼀维数组⼀般表示⼀种线性数据的组合。⼆维数组则是有两个下标,可…...
opencv解析系列 - 基于DOM提取大面积植被(如森林)
Note:简单提取,不考虑后处理(填充空洞、平滑边界等) #include <iostream> #include "opencv2/imgproc.hpp" #include "opencv2/highgui.hpp" #include <opencv2/opencv.hpp> using namespace cv…...
【Leetcode】299. 猜数字游戏
文章目录 题目思路代码结果 题目 题目链接 你在和朋友一起玩 猜数字(Bulls and Cows)游戏,该游戏规则如下: 写出一个秘密数字,并请朋友猜这个数字是多少。朋友每猜测一次,你就会给他一个包含下述信息的提…...
JWT身份验证
在实际项目中一般会使用jwt鉴权方式。 JWT知识点 jwt,全称json web token ,JSON Web令牌是一种开放的行业标准RFC 7519方法,用于在两方安全地表示声明。具体网上有许多文章介绍,这里做简单的使用。 1.数据结构 JSON Web Token…...
IOS面试题object-c 71-80
71. 简单介绍下NSURLConnection类及 sendSynchronousRequest:returningResponse:error:与– initWithRequest:delegate:两个方法的区别?NSURLConnection 主要用于网络访问,其中 sendSynchronousRequest:returningResponse:error:是同步访问数据,即当前…...
计算机mfc140.dll文件缺失的修复方法分析,一键修复mfc140.dll
电脑显示mfc140.dll文件缺失信息时,不必担心,这通常是个容易解决的小问题。接下来让我们详细探究并解决mfc140.dll文件缺失的状况。以下将详述相应的解决方案,从而帮助您轻松克服这一技术难题。通过几个简单步骤,即可恢复正常使用…...
web前端框架
目前比较火热的几门框架: React React是由Facebook(脸书)开发和创建的开源框架。React 用于开发丰富的用户界面,特别是当您需要构建单页应用程序时。它是最强大的前端框架。 弊端: 您不具备 JavaScript 的实践知识,则建议不要使用 React。同样&#x…...
关于playbook中when条件过滤报The conditional check ‘result|failed‘ failed的问题
问题现象 在使用plabook中的when做过滤脚本如下: --- - hosts: realserversremote_user: roottasks:- name: Check if httpd service is runningcommand: systemctl status httpdregister: resultignore_errors: True- name: Handle failed service checkdebug:ms…...
【设计模式专题之抽象工厂模式】3. 家具工厂
题目描述 小明家新开了两个工厂用来生产家具,一个生产现代风格的沙发和椅子,一个生产古典风格的沙发和椅子,现在工厂收到了一笔订单,请你帮他设计一个系统,描述订单需要生产家具的信息。 输入描述 输入的第一行是一…...
架构:Apache Kafka Connect实现sqlserver数据实时同步
实现Apache Kafka Connect与SQL Server之间的实时数据同步,您可以使用Kafka Connect的JDBC Source Connector。以下是一个基本的步骤: 1. 安装Kafka Connect:确保您已经安装了Apache Kafka 和 Kafka Connect。您可以从Apache Kafka的官方网站…...
C语言:深入补码计算原理
C语言:深入补码计算原理 有符号整数存储原码、反码、补码转换规则数据与内存的关系 补码原理 有符号整数存储 原码、反码、补码 有符号整数的2进制表示方法有三种,即原码、反码和补码 三种表示方法均有符号位和数值位两部分,符号位用0表示“…...
【Pytorch】新手入门:基于sklearn实现鸢尾花数据集的加载
【Pytorch】新手入门:基于sklearn实现鸢尾花数据集的加载 🌈 个人主页:高斯小哥 🔥 高质量专栏:Matplotlib之旅:零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教程👈 希望…...
maven项目引入私有jar,并打包到java.jar中
私有jar存放位置 maven依赖 <dependency><groupId>com.hikvision.ga</groupId><artifactId>artemis-http-client</artifactId><version>1.1.10</version><scope>system</scope><systemPath>${project.basedir}/s…...
Django中的Cookie和Session
文章目录 cookie是什么Django中如何使用cookieCookie使用示例session是什么Django中如何使用会话sessionSession使用示例小结 HTTP协议本身是”无状态”的,在一次请求和下一次请求之间没有任何状态保持,服务器无法识别来自同一用户的连续请求。有了cooki…...
Git-安装与使用(快速上手图文教程)
Git-安装与使用(快速上手图文教程) - 知乎 克隆: 首先你进去你要存放代码的位置,比如将代码存放到D盘,然后在D盘中右键,点击Git Bash Here,就是说本地仓库要在D盘建立。然后出现git 命令行界面…...
VBA_NZ系列工具NZ02:VBA读取PDF使用说明
我的教程一共九套及VBA汉英手册一部,分为初级、中级、高级三大部分。是对VBA的系统讲解,从简单的入门,到数据库,到字典,到高级的网抓及类的应用。大家在学习的过程中可能会存在困惑,这么多知识点该如何组织…...
UE5 学习系列(二)用户操作界面及介绍
这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…...
376. Wiggle Subsequence
376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...
Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...
Linux --进程控制
本文从以下五个方面来初步认识进程控制: 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程,创建出来的进程就是子进程,原来的进程为父进程。…...
安卓基础(aar)
重新设置java21的环境,临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的: MyApp/ ├── app/ …...
push [特殊字符] present
push 🆚 present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中,push 和 present 是两种不同的视图控制器切换方式,它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...
毫米波雷达基础理论(3D+4D)
3D、4D毫米波雷达基础知识及厂商选型 PreView : https://mp.weixin.qq.com/s/bQkju4r6med7I3TBGJI_bQ 1. FMCW毫米波雷达基础知识 主要参考博文: 一文入门汽车毫米波雷达基本原理 :https://mp.weixin.qq.com/s/_EN7A5lKcz2Eh8dLnjE19w 毫米波雷达基础…...
【WebSocket】SpringBoot项目中使用WebSocket
1. 导入坐标 如果springboot父工程没有加入websocket的起步依赖,添加它的坐标的时候需要带上版本号。 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId> </dep…...
规则与人性的天平——由高考迟到事件引发的思考
当那位身着校服的考生在考场关闭1分钟后狂奔而至,他涨红的脸上写满绝望。铁门内秒针划过的弧度,成为改变人生的残酷抛物线。家长声嘶力竭的哀求与考务人员机械的"这是规定",构成当代中国教育最尖锐的隐喻。 一、刚性规则的必要性 …...
ThreadLocal 源码
ThreadLocal 源码 此类提供线程局部变量。这些变量不同于它们的普通对应物,因为每个访问一个线程局部变量的线程(通过其 get 或 set 方法)都有自己独立初始化的变量副本。ThreadLocal 实例通常是类中的私有静态字段,这些类希望将…...
