【实战 ES】实战 Elasticsearch:快速上手与深度实践-2.2.3案例:电商订单日志每秒10万条写入优化

ops/2025/3/6 2:19:10/

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


文章大纲

  • Elasticsearch批量写入性能调优实战:2.2.3 案例:电商订单日志每秒10万条写入优化
    • 1. 原始架构与瓶颈分析
      • 1.1 初始集群配置
      • 1.2 性能瓶颈定位
    • 2. 全链路优化方案设计
      • 2.1 优化架构全景图
      • 2.2 优化措施矩阵
    • 3. 分阶段性能调优实施
      • 3.1 第一阶段:硬件与基础配置
      • 3.2 第二阶段:写入客户端优化
    • 4. 压力测试与效果验证
      • 4.1 测试环境
      • 4.2 调优效果对比(核心指标优化对比)
    • 5. 生产环境稳定性保障
      • 5.1 动态限流配置
      • 5.2 监控报警策略(生产环境监控报警矩阵)
    • 经验总结与避坑指南
      • 关键成功要素
      • 典型避坑指南
    • 最终效果

Elasticsearch批量写入性能调优实战:2.2.3 案例:电商订单日志每秒10万条写入优化


1. 原始架构与瓶颈分析

1.1 初始集群配置

组件配置详情问题表现
ES集群6节点(8C32G),HDD RAID5磁盘IO持续100%
索引设计15主分片/1副本,默认refresh_interval段合并风暴
写入客户端单线程批量提交,每次500条CPU利用率不足30%
JVM配置16GB堆,CMS GCGC停顿频繁(>2秒/分钟)

1.2 性能瓶颈定位

# 热点线程分析# 此请求用于获取 Elasticsearch 集群中各节点的热点线程信息# 热点线程是指在一段时间内占用大量 CPU 时间的线程# 通过分析热点线程,可以找出可能存在性能瓶颈的线程,例如哪些线程在频繁执行复杂的操作,从而定位性能问题的根源
GET /_nodes/hot_threads# 资源监控数据节点 CPU 利用率:75% (us 40%, sy 35%# 节点 CPU 利用率表示当前节点的 CPU 被使用的比例,这里为 75%,说明 CPU 处于较高的负载状态# "us" 代表【用户空间】 CPU 使用率,为 40%,表示用户进程占用 CPU 的时间比例# "sy" 代表【系统空间】 CPU 使用率,为 35%,表示操作系统内核进程占用 CPU 的时间比例# 较高的 CPU 利用率可能会导致系统响应变慢,需要检查是否有大量的复杂查询、数据处理或其他高 CPU 消耗的操作在运行磁盘 IO 等待:92%# 磁盘 IO 等待表示磁盘 I/O 操作导致线程等待的时间比例,这里达到了 92%# 这意味着大部分时间线程都在等待磁盘完成读写操作,说明磁盘 I/O 可能成为系统的瓶颈# 可能的原因包括磁盘性能不足、磁盘负载过高、数据存储不合理等,需要对磁盘进行优化,如更换高性能磁盘、优化数据存储策略等VM Old GC 频率:8 /分钟# JVM(Java 虚拟机)的 Old GC 即老年代垃圾回收# 频率为 8 /分钟,说明 JVM 老年代垃圾回收比较频繁# 频繁的老年代垃圾回收会导致系统暂停,影响系统的性能和响应时间# 可能是由于堆内存分配不合理、存在内存泄漏、大对象频繁创建等原因导致,需要调整 JVM 堆内存配置、检查代码是否存在内存泄漏问题线程池 bulk 队列拒绝数:1200/分钟# 线程池 bulk 队列用于存储等待被批量操作线程池处理的请求# 拒绝数为 1200/分钟,意味着每分钟有 1200 个批量操作请求由于队列已满而被拒绝# 这可能是因为批量操作请求过多,而线程池的处理能力有限或者队列大小设置不合理# 需要增加线程池的线程数量、扩大队列大小或者优化批量操作的请求频率
  • 关键瓶颈诊断:
      1. 磁盘IO瓶颈:HDD顺序写入速度仅120MB/s
      1. 批量处理效率低:单线程客户端无法利用多核
      1. 索引配置不合理:频繁refresh导致大量小段
      1. 内存压力大:默认JVM配置导致频繁GC
参数名默认策略(Elasticsearch原生默认行为)动态调整范围(是否支持运行时修改及限制条件)监控指标(对应Metricbeat/API监控指标名称)风险场景
core固定为CPU核心数需重启生效thread_pool.bulk.active数值过小导致CPU利用率不足
max等于core(禁用弹性扩容)需重启生效thread_pool.bulk.threads设置过高引发线程竞争
keep_alive固定30秒支持动态调整thread_pool.bulk.largest过短导致频繁线程创建/销毁
queue_size固定200可动态调整(需关闭auto_queue)thread_pool.bulk.queue过大导致OOM,过小触发拒绝
auto_queue自动调整队列(初始200→max 100000)运行时自动调节thread_pool.bulk.rejected突发流量时可能误判

2. 全链路优化方案设计

2.1 优化架构全景图

在这里插入图片描述

2.2 优化措施矩阵

优化维度具体措施预期收益
硬件升级HDD -> NVMe SSD磁盘IO提升10倍
索引设计动态模板+时间序列优化写入吞吐+50%
写入客户端多线程批量+自动重试机制CPU利用率提升3倍
集群配置独立协调节点+专用Ingest节点拒绝率降为0
JVM调优G1GC+堆内存调整GC停顿减少80%
流量控制基于Kafka的削峰填谷峰值处理能力2倍
  • G1GCGarbage First Garbage Collector)是 Java 虚拟机(JVM)中的一种垃圾回收器,Java 9 中成为默认的垃圾回收器。
    • G1GC 是一款面向服务器端应用的垃圾回收器,旨在满足大内存、多处理器系统的需求。主要目标是在尽可能减少停顿时间的同时,保持较高的吞吐量与传统的垃圾回收器(如 CMS、Parallel GC 等)不同,G1GC 采用了基于 Region 的内存管理方式和标记 - 整理算法。

3. 分阶段性能调优实施

3.1 第一阶段:硬件与基础配置

# elasticsearch.yml 核心修改# 优化 Elasticsearch 集群的性能,以适应特定的业务需求和硬件环境# "thread_pool.bulk" 用于配置批量操作线程池的相关参数# 批量操作(如使用 Bulk API 一次性处理多个文档的索引、更新或删除操作)是 Elasticsearch 中常用的操作方式,合理配置该线程池能提高批量操作的效率
thread_pool.bulk:# "size" 定义了批量操作线程池中的线程数量# 这里设置为 32,是基于每个节点有 16  CPU,乘以 2 意味着线程池的线程数量是 CPU 核心数的 2 # 这样设置的目的是充分利用 CPU 资源,让更多的线程同时处理批量操作请求,但又不会过度创建线程导致系统资源耗尽size: 32          # 16核CPU × 2# "queue_size" 表示批量操作线程池队列的最大容量# 当有大量的批量操作请求进入系统,且线程池中的线程都在忙碌时,新的请求会被放入队列中等待处理# 这里将队列大小设置为 2000,意味着队列最多可以容纳 2000 个批量操作请求# 如果队列满了,新的请求可能会被拒绝,需要根据实际的业务流量和处理能力来调整这个值queue_size: 2000# "indices.memory.index_buffer_size" 用于设置索引缓冲区的大小# 索引缓冲区是 Elasticsearch 用于临时存储待索引文档的内存区域# 设置为 30% 表示将堆内存的 30% 分配给索引缓冲区# 较大的索引缓冲区可以减少磁盘 I/O 操作,提高索引性能,但也会占用更多的堆内存,可能会影响其他操作的性能# 需要根据系统的内存资源和业务的索引频率来合理调整这个比例
indices.memory.index_buffer_size: 30%# 索引模板配置# 索引模板用于定义新创建索引的默认设置和映射# 这里创建了一个名为 "orders" 的索引模板,当创建与该模板匹配的索引时,会自动应用模板中的设置
PUT _template/orders
{"settings": {# "number_of_shards" 定义了每个索引的主分片数量# 这里设置为 30,意味着每个新创建的与 "orders" 模板匹配的索引将有 30 个主分片# 增加主分片数量可以提高数据的并行处理能力和集群的扩展性,但也会增加集群的管理开销和资源消耗# 需要根据数据量、查询需求和集群规模来合理设置主分片数量"number_of_shards": 30,# "refresh_interval" 表示索引的刷新间隔# 这里设置为 "30s",意味着每隔 30 秒,索引会将内存中的数据刷新到磁盘上,使其可以被搜索到# 较长的刷新间隔可以减少磁盘 I/O 操作,提高索引性能,但会增加数据的可见延迟# 需要根据业务对数据实时性的要求来调整刷新间隔"refresh_interval": "30s",# "translog.durability" 用于设置事务日志的持久化策略# 这里设置为 "async",表示事务日志将异步刷新到磁盘# 异步刷新可以提高索引性能,但在发生故障时可能会丢失部分未刷新到磁盘的事务日志数据# 如果对数据的持久性要求较高,可以将其设置为 "request",表示每次请求都将事务日志同步刷新到磁盘"translog.durability": "async"}
}
  • 硬件升级方案:
    • 数据节点:12台(32CPU128G,2TB NVMe × 4 RAID0)
    • 协调节点:3台(16CPU64G,仅处理HTTP请求)

3.2 第二阶段:写入客户端优化

// 多线程BulkProcessor配置BulkProcessor bulkProcessor = BulkProcessor.builder(client::bulkAsync, new BulkProcessor.Listener() { /* 监听器 */ }).setBulkActions(2000)      // 2000文档提交.setBulkSize(new ByteSizeValue(10, ByteSizeUnit.MB)).setConcurrentRequests(8)  // 并发写入线程数.build();
  • 客户端优化关键参数:
    • 并发线程数 = 协调节点数 × 2 (3×2=6,取8预留余量)
    • 单个批量大小:10MB(根据ES官方建议5-15MB)
    • 重试策略:指数退避(最大重试3次)

4. 压力测试与效果验证

4.1 测试环境

组件配置详情
压测工具自研Go语言压测工具(模拟真实订单流)
测试数据集1亿条订单数据(含28个字段)
持续时间30分钟稳态压力测试

4.2 调优效果对比(核心指标优化对比)

指标优化前优化后提升幅度
平均吞吐量35,000/s121,000/s245%
P99写入延迟1200ms230ms80%
磁盘IO利用率98%65%-
拒绝请求数1,200/min0100%
GC停顿时间2.1s/min0.3s/min85%
  • 吞吐量趋势图:
140k ┤             ***************
120k ┤          ***               ***
100k ┤        **                     **80k ┤      **                         **60k ┤    **                             **40k ┤  **                                 **20k ┤**                                     **┼----------------------------------------5min   10min   15min   20min   25min

5. 生产环境稳定性保障

5.1 动态限流配置

# 索引级别限流(根据业务高峰动态调整)# 该操作的目的是对指定索引进行限流设置,并且可以依据业务高峰时段的不同情况动态调整限流参数,以保障 Elasticsearch 集群的稳定运行,避免因某个索引的操作过于频繁而影响整体性能。# PUT 请求用于更新资源,这里是更新名为 orders 的索引的设置。PUT /orders/_settings{# "index.rate_limit" 是用于设置索引操作速率限制的配置项。"index.rate_limit": {# "max_docs_per_second" 指定了每秒允许索引的最大文档数量。# 这里设置为 150000,表示在一秒内,对 orders 索引进行操作时,最多只能索引 150000 个文档。# 此设置可防止短时间内大量文档的涌入导致集群资源耗尽或性能下降。"max_docs_per_second": 150000,# "max_bytes_per_second" 指定了每秒允许索引的最大数据量。# 设置为 "500mb",意味着每秒对 orders 索引进行操作时,涉及的数据量不能超过 500 兆字节。# 结合文档数量限制和数据量限制,能更全面地控制索引操作的速率。"max_bytes_per_second": "500mb"}
}# 集群级别断路器# 集群级别断路器【用于防止 Elasticsearch 集群因内存使用过度而崩溃】。# 它会对某些可能消耗大量内存的操作进行限制,当达到或接近设定的限制时,会阻止这些操作继续执行。# "indices.breaker.total.limit" 是一个全局设置,用于定义整个集群中所有断路器的总内存使用上限。# 设置为 70%,表示集群中所有可能触发断路器的操作所使用的内存总和不能超过堆内存的 70%# 这样可以为集群保留一定的内存空间,用于其他必要的操作,确保集群的稳定性。
indices.breaker.total.limit: 70%

5.2 监控报警策略(生产环境监控报警矩阵)

监控指标报警阈值响应动作
bulk队列拒绝率> 0次/5分钟自动扩展协调节点
磁盘IO等待时间> 70%持续10分钟触发数据归档流程
JVM Old GC频率> 2次/分钟触发堆内存分析并扩容
节点CPU使用率> 85%持续5分钟动态降低索引refresh频率

经验总结与避坑指南

关键成功要素

    1. SSD硬件升级:NVMe SSD使磁盘IOPS从1,500提升至80,000
    1. 客户端多线程改造:写入并发从1线程提升到8线程
    1. 索引预分区策略:分片数从15增加到30(数据节点数×2.5)
    1. JVM垃圾回收调优:G1GC替代CMS,最大GC停顿从2.1s降至0.4s
    • CMSConcurrent Mark Sweep)是 Java 虚拟机(JVM)中的一种垃圾回收器,主要用于对老年代进行垃圾回收,其设计目标是尽量减少垃圾回收时的停顿时间,以提高应用程序的响应性,适合对响应时间要求较高的应用场景。
    • 是一种以获取最短回收停顿时间为目标的垃圾回收器,它基于 “标记 - 清除” 算法实现。

典型避坑指南

    1. 避免超大分片单个分片大小控制在30-50GB
    1. 禁用swap:防止内存交换导致性能断崖式下降
    1. 批量请求超时设置:建议为30s+指数退避重试
    1. 冷热数据分离:将历史数据迁移至冷节点

最终效果

  • 经过系统优化后,该电商平台在双11期间:
    • 峰值吞吐量:稳定处理12.4万条/秒订单日志
    • 资源利用率:CPU 75%、磁盘IO 65%、内存使用率70%
    • 系统稳定性:连续72小时无写入失败记录
    • 成本效益:硬件投入增加40%,处理能力提升300%

http://www.ppmy.cn/ops/163470.html

相关文章

[vue] 缩放比适配问题

在开发前端页面的时候经常会发生不同用户存在不同缩放比的问题. 解决方案为 第一步, 在html标签中添加缩放锚点,及隐藏对应的滑块 项目刚开始 对于lang是没有设置的 , 这里我们设置成zh-CN,后续的最关键内容为transform-origin: 0 0;这样就保证了在缩放的时候不会乱跑. <…

网络安全员证书

软考网络安全员证书&#xff1a;信息安全领域的黄金标准 随着信息技术的飞速发展&#xff0c;网络安全问题日益凸显&#xff0c;网络安全员的需求也日益增加。软考网络安全员证书作为信息安全领域的黄金标准&#xff0c;对于网络安全从业者来说具有重要意义。本文将详细介绍…

嵌入式开发中的计算机体系结构与主流架构深度解析

一、计算机体系结构基础 1.1 计算机模型:图灵机与两大经典架构 图灵机模型 图灵机是现代计算机的理论基础,由无限长纸带(TAPE)、读写头(HEAD)、控制规则(TABLE)和状态寄存器组成。其核心思想是将复杂运算分解为有限个基本操作,映射到现代计算机中即为程序代码(纸带)…

Nginx系列07(Nginx 性能优化、Nginx 安全配置)

目录 Nginx 性能优化 Nginx 安全配置 Nginx 性能优化 概念&#xff1a;Nginx 性能优化旨在通过调整各种配置参数和采用特定技术&#xff0c;提升 Nginx 服务器处理请求的能力&#xff0c;降低响应时间&#xff0c;增加并发连接数&#xff0c;从而更高效地为用户提供服务&…

【金融量化】Ptrade中如何获取各类回测数据?

1. get_history 功能: 获取指定时间段内的历史行情K线数据&#xff0c;支持多股票、多行情字段获取。参数: security: 股票代码或股票代码列表&#xff08;list[str]/str&#xff09;。start_date: 开始时间&#xff0c;格式为YYYYmmdd、YYYY-mm-dd、YYYY-mm-dd HH:MM、YYYYmm…

局域网自动识别机器名和MAC并生成文件的命令

更新版本&#xff1a;添加了MAC 地址 确定了设备唯一性 V1.1 局域网自动识别机器名和MAC并生成文件的批处理命令 echo off setlocal enabledelayedexpansionREM 设置输出文件 set outputFilenetwork_info.txtREM 清空或创建输出文件 echo Scanning network from 192.168.20.1…

Ubuntu: 域名解析错误:Temporary failure in name resolution

临时解决方案 你可以尝试直接指定一个公共 DNS 服务器来进行测试&#xff0c;比如 Google 的公共 DNS 或 Cloudflare 的 DNS。在命令行中可以这样操作&#xff1a; 使用 Google 的公共 DNS&#xff1a; sudo systemd-resolve --set-dns8.8.8.8 --interface* --set-domain~. su…

Ubuntu20.04双系统安装及软件安装(七):Anaconda3

Ubuntu20.04双系统安装及软件安装&#xff08;七&#xff09;&#xff1a;Anaconda3 打开Anaconda官网&#xff0c;在右侧处填写邮箱&#xff08;要真实有效&#xff01;&#xff09;&#xff0c;然后Submit。会出现如图示的Success界面。 进入填写的邮箱&#xff0c;有一封Ana…