【实战 ES】实战 Elasticsearch:快速上手与深度实践-2.2.2线程池配置与写入限流

👉 点击关注不迷路
👉 点击关注不迷路
👉 点击关注不迷路


文章大纲

  • Elasticsearch批量写入性能调优:2.2.2 线程池配置与写入限流深度实践
    • 1. 线程池核心机制解析
      • 1.1 `Elasticsearch`线程池架构
      • 1.2 `Bulk`线程池工作模型
    • 2. 写入场景线程池调优
      • 2.1 硬件资源与线程数关系
      • 2.2 队列深度优化策略
    • 3. 动态限流策略实现
      • 3.1 写入压力识别指标
      • 3.2 分级限流方案
    • 4. 性能压测与效果验证
      • 4.1 测试环境
      • 4.2 调优前后对比
    • 5. 生产环境最佳实践
      • 5.1 参数配置黄金法则
      • 5.2 监控预警方案
      • 5.3 故障应急处理流程
    • 总结

Elasticsearch批量写入性能调优:2.2.2 线程池配置与写入限流深度实践


1. 线程池核心机制解析

1.1 Elasticsearch线程池架构

Elasticsearch采用分层线程池设计,不同操作类型使用独立线程池,下表是ES主要线程池配置对比:

线程池类型默认配置主要职责
bulk线程数=CPU核心数,队列=200处理批量写入请求
index线程数=CPU核心数,队列=200处理单文档写入请求
search线程数=round(CPU*1.5)+1处理查询请求
refresh线程数=1,队列=1000处理索引刷新操作

1.2 Bulk线程池工作模型

  • 适用场景:处理批量索引/更新/删除请求,具有高吞吐量特性
  • 设计原则:在CPU密集型IO密集型任务间取得平衡
// 默认Bulk线程池配置源码ThreadPool.Names.BULK: // 核心线程数(保持活跃的最小线程数)// 默认值:与CPU物理核心数相同(Runtime.getRuntime().availableProcessors()// 调优建议:在纯SSD/NVMe环境中可设置为CPU核心数×1.5core = number_of_processors// 最大线程数(线程池扩容上限)// 默认值:与核心线程数相同(Elasticsearch默认不动态扩容)// 调优建议:在存在IO等待的场景可设为CPU核心数×2max = number_of_processors// 线程空闲存活时间(超时后回收多余线程)// 重要性:平衡资源利用与线程创建开销// 计算公式:max(5, min(1, (core threads)/2)) 单位秒(实际默认30秒)keep_alive = 30s// 任务队列容量(等待执行的bulk请求数)// ~~警告:队列过大会导致内存压力,过小易触发拒绝~~ // 计算公式:min(200, max(10, core threads × 10)) queue_size = 200// 自动队列调整(7.x+版本特性)// 工作机制:根据拒绝率动态调整队列容量(初始200,最大1e5// 启用条件:需配合"xpack.ml.enabled: true"使用// 注意:生产环境建议关闭(设置为false)并手动管理队列auto_queue = true
  • 关键参数说明:
    • core/max:线程数动态调整范围
    • auto_queue:自动队列调整策略(7.x+版本特性)
    • queue_size:队列积压容量阈值

2. 写入场景线程池调优

2.1 硬件资源与线程数关系

  • 通过压力测试得出不同硬件配置下的最佳线程数:
CPU核心数内存磁盘类型最佳bulk线程数平均吞吐量(docs/s)
416GBHDD412,000
832GBSSD845,000
1664GBNVMe12112,000
32128GBNVMe16235,000
  • 调整公式推导:
    • 最佳线程数 = CPU核心数 × (1 + (IO等待时间/CPU时间))
    • 当使用SSD/NVMe时,建议取CPU核心数的1-1.5倍

2.2 队列深度优化策略

// 此请求用于更新 Elasticsearch 集群的设置
// PUT 请求方式用于向指定的端点发送数据,以修改或创建资源
// 这里的端点是 /_cluster/settings,表示对集群的设置进行操作PUT /_cluster/settings
{// "persistent" 表示这些设置是持久化的// 持久化设置会在集群重启后仍然生效// 与之相对的是 "transient" 设置,它只在当前集群会话中有效,重启后会丢失"persistent": {// "thread_pool.bulk.queue_size"  Elasticsearch 中用于控制批量操作线程池队列大小的设置项// 批量操作(如 bulk API)是 Elasticsearch 中用于一次性处理多个文档的操作方式// 当有大量的批量操作请求进入系统时,这些请求会被放入一个队列中等待处理// 此设置项的值决定了这个队列最多可以容纳多少个请求// 这里将队列大小设置为 1000,意味着当队列中的请求数量达到 1000 个时,新的批量操作请求将被阻塞,直到队列中有请求被处理完毕"thread_pool.bulk.queue_size": 1000}
}
  • 队列设置黄金法则:
      1. 总内存压力不超过JVM堆的50%
      1. 每个bulk请求平均大小控制在5-15MB
      1. 监控指标:thread_pool.bulk.rejected需保持为0,出现拒绝需立即扩容

3. 动态限流策略实现

3.1 写入压力识别指标

  • 线程池状态监控示例
// 此请求用于获取 Elasticsearch 集群中所有节点的线程池统计信息,并仅过滤出与批量操作(bulk)相关的信息
// GET 请求方式用于从指定的端点获取数据
// 端点 /_nodes/stats/thread_pool 表示获取所有节点的线程池统计信息
// filter_path=**.bulk 参数用于过滤响应结果,只返回与批量操作相关的统计信息GET /_nodes/stats/thread_pool?filter_path=**.bulk{// "threads" 表示当前批量操作线程池中的线程数量// 这些线程负责处理批量操作请求,线程数量的多少会影响批量操作的处理能力"threads" : 16,// "queue" 表示当前批量操作线程池【队列】中的请求数量// 当有大量的批量操作请求进入系统,且线程池中的线程都在忙碌时,新的请求会被放入队列中等待处理// 此值反映了当前等待处理的批量操作请求数量"queue" : 120,// "active" 表示当前【正在执行批量操作】的线程数量// 该值显示了线程池的忙碌程度,如果 "active" 等于 "threads",说明线程池中的所有线程都在工作"active" : 16,// "rejected" 表示由于线程池队列已满而被拒绝的批量操作请求数量// 当队列中的请求数量达到队列的最大容量时,新的请求将被拒绝// 此值为 0 表示目前没有请求被拒绝"rejected" : 0,// "largest" 表示批量操作线程池队列【曾经达到的最大请求数量】// 该值可以帮助你了解系统在过去的运行过程中,队列的压力情况"largest" : 200,// "completed" 表示批量操作线程池【已经完成处理的】请求数量// 此值反映了线程池的历史处理能力和工作量"completed" : 245600
}
  • 关键阈值判断:
    • 队列使用率 > 80%,jvm.mem.heap_used_percent > 75%:触发扩容或限流,队列过大可能引发OOM
    • Rejected计数 > 0:需立即调整配置
    • Active线程数持续满载:存在资源瓶颈

3.2 分级限流方案

  • 分级限流配置示例
# 【索引级别】限流(动态生效)
# 此操作可以在不重启 Elasticsearch 集群的情况下,直接对指定索引进行限流设置,方便灵活调整索引的操作速率
# PUT 请求用于更新资源,这里是更新名为 my_index 的索引的设置PUT /my_index/_settings
{# "index.ops.rate_limit" 是用于设置索引操作速率限制的配置项"index.ops.rate_limit": {# "max" 指定了在一定时间内允许的最大操作数据量# 这里设置为 "100mb",表示在下面指定的时间范围内,索引操作涉及的数据量最大不能超过 100 兆字节"max": "100mb",# "time" 定义了上述最大操作数据量所对应的时间周期# 设置为 "1s",意味着每秒内索引操作的数据量不能超过 100 兆字节"time": "1s"}
}# 【节点级别】限流(重启生效)
# 下面的配置需要在 elasticsearch.yml 文件中进行修改,修改后需要重启 Elasticsearch 节点才能使配置生效# elasticsearch.yml  Elasticsearch 的核心配置文件,用于设置节点的各种参数# "thread_pool.bulk.size" 用于设置批量操作线程池的线程数量
# 这里设置为 16,表示批量操作线程池中将有 16 个线程同时处理批量操作请求
# 线程数量的多少会影响批量操作的处理能力,需要根据节点的硬件资源和业务需求进行合理调整
thread_pool.bulk.size: 16# "thread_pool.bulk.queue_size" 用于设置批量操作线程池的队列大小
# 当有大量的批量操作请求进入系统,且线程池中的线程都在忙碌时,新的请求会被放入队列中等待处理
# 这里设置为 500,意味着队列最多可以容纳 500 个批量操作请求
# 如果队列满了,新的请求可能会被拒绝,因此需要根据实际情况合理设置队列大小
thread_pool.bulk.queue_size: 500
  • 限流策略对照表:不同场景限流策略选择
场景策略生效方式调整粒度
突发流量动态索引级限流即时生效精细
持续高负载节点级线程池调整重启生效粗粒度
混合工作负载队列优先级策略版本依赖中等

4. 性能压测与效果验证

4.1 测试环境

  • 集群配置:3节点(16CPU / 64GB / NVMe)
  • 数据集:商品日志数据(平均文档大小2KB)
  • 测试工具:esrally基准测试
    • Elasticsearch Rally(简称 esrally )是 Elastic 官方开发的一款用于对 Elasticsearch 进行基准测试的工具。
    • 它可以帮助你评估 Elasticsearch 集群在不同场景下的性能表现,找出性能瓶颈,为集群的优化和扩容提供依据
    • 可以使用 Python 的包管理工具 pip 进行安装pip install esrally。测试完成后,esrally 会输出详细的测试结果,包括索引速率、搜索响应时间、吞吐量等指标。

4.2 调优前后对比

配置项默认配置优化配置提升比例
bulk线程数1624+48%
队列深度2001000+400%
限流阈值50MB/s-
平均吞吐量78,000 docs/s142,000 docs/s+82%
P99延迟650ms320ms-51%
拒绝请求数1,2000100%
  • 吞吐量变化曲线图:
500k                                       
400k               ***********             
300k          *****           *****        
200k       ***                     ***     
100k   ****                           **** 0 ┼-------------------------------------默认配置  线程优化  队列优化  综合调优

5. 生产环境最佳实践

5.1 参数配置黄金法则

# 推荐配置模板(elasticsearch.yml)
# 用于优化 Elasticsearch 的性能,根据实际情况合理调整配置提升集群的稳定性和处理能力# "thread_pool.bulk" 用于配置批量操作线程池的相关参数
# 批量操作(如使用 Bulk API 一次性处理多个文档的索引、更新或删除操作)是 Elasticsearch 中常用的操作方式,合理配置该线程池能提高批量操作的效率
thread_pool.bulk:# "size" 定义了批量操作线程池中的线程数量# ${CPU_CORES} 代表系统的 CPU 核心数,乘以 1.5 意味着线程池的线程数量是 CPU 核心数的 1.5 # 这样设置的目的是充分利用 CPU 资源,让更多的线程同时处理批量操作请求,但又不会过度创建线程导致系统资源耗尽# 例如,如果系统有 8  CPU 核心,那么线程池的线程数量将是 8 * 1.5 = 12 size: ${CPU_CORES} * 1.5# "queue_size" 表示批量操作线程池队列的最大容量# 当有大量的批量操作请求进入系统,且线程池中的线程都在忙碌时,新的请求会被放入队列中等待处理# 这里将队列大小设置为 1000,意味着队列最多可以容纳 1000 个批量操作请求# 如果队列满了,新的请求可能会被拒绝,需要根据实际的业务流量和处理能力来调整这个值queue_size: 1000# "auto_queue" 是一个布尔值,【设置为 true 表示启用自动队列功能】# 当线程池中的线程都在忙碌时,新的请求会自动进入队列等待处理# 这有助于避免请求丢失,确保所有请求都能得到处理,但也可能会导致队列积压,需要结合队列大小和实际业务情况进行考虑auto_queue: true# "indices.memory.index_buffer_size" 用于设置索引缓冲区的大小
# 索引缓冲区是 Elasticsearch 用于临时存储待索引文档的内存区域
# 设置为 20% 表示将堆内存的 20% 分配给索引缓冲区
# 较大的索引缓冲区可以减少磁盘 I/O 操作,提高索引性能,但也会占用更多的堆内存,可能会影响其他操作的性能
# 需要根据【系统的内存资源和业务的索引频率】来合理调整这个比例indices.memory.index_buffer_size: 20%

5.2 监控预警方案

  • 建议设置以下报警阈值:
      1. bulk队列使用率 > 75% ,持续5分钟
      1. 节点写入吞吐量 > 80% ,磁盘顺序写能力
      1. JVM堆内存使用 > 70% ,持续10分钟

5.3 故障应急处理流程

  • 写入性能下降处理流程:1. 检查线程池状态:GET /_cat/thread_pool?v2. 分析热点节点:GET /_nodes/hot_threads3. 临时限流处理:PUT /_cluster/settings(动态调整)4. 纵向扩展:增加批量写入大小5. 横向扩展:添加Ingest节点
    
  • Ingest 节点是 Elasticsearch 中一个重要的组件,主要用于在文档被索引之前对其进行预处理。
    • 这意味着你可以对原始数据进行各种处理,如解析、转换、添加字段、删除字段等,以满足不同的索引和查询需求。

总结

  • 通过合理配置线程池参数与动态限流策略,可使批量写入吞吐量提升80%以上,同时保障集群稳定性
  • 建议结合具体硬件配置建立基准性能模型,采用分级限流策略应对不同场景的写入压力

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

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

相关文章

VSCode 与 Vim 插件 的 复制粘贴等快捷键冲突,优先使用 VSCode 的快捷键

VSCode 与 Vim 插件 的 复制粘贴等快捷键冲突,优先使用 VSCode 的快捷键 在 VSCode 中,如果你发现 Vim 插件(如 VSCodeVim 扩展)与 VSCode 的默认复制粘贴快捷键(CtrlC / CtrlV)冲突,并且你想优…

tsconfig.json 配置清单

tsconfig.json 配置清单 基础结构 {"compilerOptions": {// 编译选项},"include": [// 指定需要编译的文件或目录],"exclude": [// 指定不需要编译的文件或目录],"extends": "./base-tsconfig.json","files": […

springboot可以同时处理多少个请求

源码 ServerProperties Tomcat 配置 参数解析 必须要先建立连接,再用线程处理。 比如max-connection最大连接数,accept-count相当于队列容量。总连接数二者和 min-spare-treads 核心线程数默认10,max-threads最大线程数默认200。 正常…

Spring 三级缓存 vs 二级缓存:深度解析循环依赖的终极解决方案

目录 一. 循环依赖的本质矛盾 1. 什么是循环依赖? 2. 矛盾的核心 二. 三级缓存架构解析 三级缓存工作流程图​编辑 三、为什么必须三级缓存? 1. 二级缓存的致命缺陷 2. 三级缓存的精妙设计 四、场景推演:三级缓存如何解决代理问题 …

视频流畅播放相关因素

视频播放的流畅度是一个综合性问题,涉及从视频文件本身到硬件性能、网络环境、软件优化等多个环节。以下是影响流畅度的关键因素及优化建议: 一、视频文件本身 1. 分辨率与帧率 1.问题:高分辨率(如4K)或高帧率&#…

金融项目实战

测试流程 测试流程 功能测试流程 功能测试流程 需求评审制定测试计划编写测试用例和评审用例执行缺陷管理测试报告 接口测试流程 接口测试流程 需求评审制定测试计划分析api文档编写测试用例搭建测试环境编写脚本执行脚本缺陷管理测试报告 测试步骤 测试步骤 需求评审 需求评…

LeetCode 25 - K 个一组翻转链表

LeetCode 25 - K 个一组翻转链表 这道题是一个典型的链表操作题,考察我们对链表的精确操作,包括反转链表、分组处理、递归和迭代的结合应用等。还可以通过变体问题延伸到优先队列操作、归并、分块等,这使得它成为面试中的高频考题之一。 题目…

Leetcode 54: 螺旋矩阵

Leetcode 54: 螺旋矩阵 是一道经典的矩阵遍历模拟题目,要求我们以螺旋顺序遍历一个二维数组。这个问题在面试中非常经典,考察模拟、数组操作以及逻辑清晰度。掌握本题的高效解法可以迅速给面试官留下好印象。 适合面试的解法:边界法&#xff…

abseil-cpp:环境搭建

参考: https://abseil.io/docs/cpp/quickstart-cmake abseil-cpp.git/dd4c89b abseil-cpp.git/20240722.1 1. clone代码仓库、编译 git clone https://github.com/abseil/abseil-cpp.git /app/abseil-cpp/ #/app/abseil-cpp/.git/config git checkout 20240722.1git rev-pa…

Storm实时流式计算系统(全解)——下

storm编程案例-网站访问来源实时统计-需求 storm编程-网站访问来源实时统计-代码实现 根据以上条件可以只写一个类,我们只需要写2个方法和一个main(),一个读取/发射(spout)。 一个拿到数据统计后发到redis…

什么是SYN洪范攻击?

文章目录 一、什么是SYN洪范攻击?二、SYN泛洪攻击原理2.1 TCP 三次握手过程2.2 SYN攻击过程 三、防御措施 一、什么是SYN洪范攻击? SYN洪泛攻击(SYN Flood)发生在OSI第四层,是一种基于‌TCP协议三次握手漏洞‌的DoS&a…

【嵌入式】MQTT

MQTT 文章目录 MQTT安装简介MQTT客户端代码 安装 安装Paho MQTT C库: sudo apt-get install libpaho-mqtt3-dev头文件包含: #include "MQTTClient.h"编译选项: gcc -o $ $^ -lpaho-mqtt3c简介 MQTT协议全称是(Message Queuing…

ubuntu离线安装nvidia-container-runtime

参考文章 ubuntu系统docker20.4版本安装nvidia-container-runtime3.11.0-1版本(离线安装nvidia-docker) - jokerMM - 博客园 https://zhuanlan.zhihu.com/p/15194336245 一、软件地址 Index of /nvidia-docker/libnvidia-container/stable/ 从上述地地址——进入对应系统—…

用Python+Flask打造可视化武侠人物关系图生成器:从零到一的实战全记录

用PythonFlask打造可视化武侠人物关系图生成器:从零到一的实战全记录 一、缘起:一个程序小白的奇妙探索之旅 作为一个接触Python仅13天的编程萌新,我曾以为开发一个完整的应用是遥不可及的事情。但在DeepSeek的帮助下,我竟用短短…

RPA 职业前景:个人职场发展的 “新机遇”

1. RPA职业定义与范畴 1.1 RPA核心概念 机器人流程自动化(RPA)是一种通过软件机器人模拟人类操作,自动执行重复性、规则性任务的技术。RPA的核心在于其能够高效、准确地处理大量数据和流程,减少人工干预,从而提高工作…

Full GC 排查

在 Java 中,Full GC(完全垃圾回收)会对整个堆(包括年轻代和老年代,甚至可能包括永久代/元空间)进行垃圾回收,通常会导致较长的停顿(STW,Stop-The-World)。如果…

go语言中字符串嵌套

在Go语言中,字符串嵌套通常是指在字符串中包含另一个字符串。可以通过以下几种方式实现: 1. 使用双引号和转义字符 如果需要在字符串中嵌套双引号,可以使用转义字符 \ 来表示内部的双引号。例如: s : "He said, \"He…

Docker 学习(二)——基于Registry、Harbor搭建私有仓库

Docker仓库是集中存储和管理Docker镜像的平台,支持镜像的上传、下载、版本管理等功能。 一、Docker仓库分类 1.公有仓库 Docker Hub:官方默认公共仓库,提供超过10万镜像,支持用户上传和管理镜像。 第三方平台:如阿里…

js的简单介绍

一.javascript(是什么) 是一种运行在客户端(浏览器)的编程语言,实现人机交互效果 作用 网页特效(监听客户的一些行为让网页做出对应的反馈)表单验证(针对表格数据的合法性进行判断)数据交互(获取后台的数据&#xf…

k8s架构及服务详解

目录 1.1.容器是什么1.2.Namespace1.3.rootfs5.1.Service介绍5.1.1.Serice简介 5.1.1.1什么是Service5.1.1.2.Service的创建5.1.1.3.检测服务5.1.1.4.在运行的容器中远程执行命令 5.2.连接集群外部的服务 5.2.1.介绍服务endpoint5.2.2.手动配置服务的endpoint5.2.3.为外部服务…