ElasticSearch读写性能调优

文章目录

    • ES写入数据过程
    • ES读取数据的过程
    • 写数据底层原理
    • 提升集群读取性能
      • 数据建模
      • 优化分片
    • 提升写入性能的方法
      • 服务器端优化写入性能
      • 建模时的优化
      • 降低Translog写磁盘的频率,但是会降低容灾能力
      • 分片设定
      • 调整Bulk 线程池和队列

ES写入数据过程

  1. 客户端选择一个node发送请求过去,这个node就是coordinating node (协调节点)
  2. coordinating node,对document进行路由,将请求转发给对应的node
  3. node上的primary shard处理请求,然后将数据同步到replica node
  4. coordinating node如果发现primary node和所有的replica node都搞定之后,就会返回请求到客户端

在这里插入图片描述



ES读取数据的过程

根据id查询数据的过程

根据 doc id 进行 hash,判断出来当时把 doc id 分配到了哪个 shard 上面去,从那个 shard 去查询。

  1. 客户端发送请求到任意一个 node,成为 coordinate node 。
  2. coordinate node 对 doc id 进行哈希路由(hash(_id)%shards_size),将请求转发到对应的 node,此时会使用 round-robin 随机轮询算法,在 primary shard 以及其所有 replica 中随机选择一个,让读请求负载均衡。
  3. 接收请求的 node 返回 document 给 coordinate node 。
  4. coordinate node 返回 document 给客户端。



根据关键词查询数据的过程

分发请求 —> 结果归并 —> 回表查询

  • 客户端发送请求到一个 coordinate node 。
  • 协调节点将搜索请求转发到所有的 shard 对应的 primary shard 或 replica shard ,都可以。
  • query phase:每个 shard 将自己的搜索结果返回给协调节点,由协调节点进行数据的合并、排序、分页等操作,产出最终结果。(结果是doc id)
  • fetch phase:接着由协调节点根据 doc id 去各个节点上拉取实际的 document 数据,最终返回给客户端。



写数据底层原理

核心概念

  • segment file

    存储倒排索引的文件,每个segment本质上就是倒排索引。

    浅层次理解,每秒都会生成一个segment文件,当文件过多时es会自动进行segment merge(合并文件),合并时会同时将已经标注删除的文档物理删除。

    深层次理解,虽然是每隔一秒就会将内存中的segment数据刷新到segment file中,但实际上这里并没有直接到磁盘文件,而是先写入到OS Cache中。

  • commit point

    记录当前所有可用的segment

    每个commit point都会维护一个.del文件,ES是逻辑删除,当ES做删除操作时会在.del文件中声明某个document被删除了,该文件记录了在某个segment内某个文档已经被删除了。

    查询时,segment中是能查询到被删除的document的,但是返回结果时会根据commit point维护的.del文件把已经删除了的文档过滤掉

  • translog日志文件

    ES每次写入数据的同时会同步写到translog日志中,低版本是每隔5s写一次translog日志文件,为了防止elasticsearch宕机造成数据丢失,保证可靠存储

    所以Segment没有写入磁盘,即便发生了宕机,重启后,数据也能恢复

  • os cache

    操作系统内核态中的缓存区,应用程序不能直接操作,写数据持久化相关的操作,应用程序只能保证数据写入到os cache。最多再调用os提供的接口让os去刷盘。

  • refresh

    以refresh_interval为间隔时间,将保存在ES 内存缓存区中的数据 刷新到 os的文件系统缓存中,定期清空es的buffer,生成segment。

    将segment刷新到os cache中,并开放了查询权限,以提升搜索的实时性

  • flush

    删除旧的translog文件、生成segment并写入磁盘、更新commit point并写入磁盘。 ES自动完成,可优化点不多

在这里插入图片描述



提升集群读取性能

数据建模

  • 尽量将数据先行计算,然后保存到Elasticsearch 中。尽量避免查询时的 Script脚本计算

  • 尽量使用Filter Context,利用缓存机制,减少不必要的算分

  • 结合profile,explain API分析慢查询的问题,持续优化数据模型

  • 避免使用*开头的通配符查询

# 使用constant_score + filter 避免相关性算分
GET /sys_user/_search
{
  "query": {
    "constant_score": {
      "filter": {
        "term": {
          "address.keyword": "广州白云山公园"
        }
      }
    }
  }
}
# 使用wildcard通配符匹配
GET /sys_user/_search
{
  "query": {
    "wildcard": {
      "address": {
        "value": "*白*"
      }
    }
  }
}



优化分片

  • 避免Over Sharing

  • 一个查询需要访问每一个分片,分片过多,会导致不必要的查询开销

  • 结合应用场景,控制单个分片的大小

  • Search业务数据搜索场景:20GB

  • Logging日志场景:50GB

  • Force-merge Read-only索引

  • 使用基于时间序列的索引,将只读的索引进行force merge,减少segment数量

  • #手动force merge
    POST /my_index/_forcemerge
    



提升写入性能的方法

  • 写性能优化的目标: 增大写吞吐量,越高越好

  • 客户端: 多线程,批量写

    • 可以通过性能测试,确定最佳文档数量
    • 多线程: 需要观察是否有HTTP 429(Too Many Requests)返回,实现 Retry以及线程数量的自动调节
  • 服务器端: 单个性能问题,往往是多个因素造成的。需要先分解问题,在单个节点上进行调整并且结合测试,尽可能压榨硬件资源,以达到最高吞吐量

    • 使用更好的硬件。观察CPU / IO Block
    • 线程切换│堆栈状况



服务器端优化写入性能

  • 降低IO操作

    • 使用ES自动生成的文档ld
    • 一些相关的ES 配置,如Refresh Interval
  • 降低 CPU 和存储开销

    • 减少不必要分词
    • 避免不需要的doc_values
    • 文档的字段尽量保证相同的顺序,可以提高文档的压缩率
  • 尽可能做到写入和分片的均衡负载,实现水平扩展

    • Shard Filtering / Write Load Balancer
  • 调整Bulk 线程池和队列



注意:ES 的默认设置,已经综合考虑了数据可靠性,搜索的实时性,写入速度,一般不要盲目修改。一切优化,都要基于高质量的数据建模。



建模时的优化

  • 只需要聚合不需要搜索,index设置成false
  • 不要对字符串使用默认的dynamic mapping。字段数量过多,会对性能产生比较大的影响
  • Index_options控制在创建倒排索引时,哪些内容会被添加到倒排索引中。



如果需要追求极致的写入速度,可以牺牲数据可靠性及搜索实时性以换取性能:

  • 牺牲可靠性: 将副本分片设置为0,写入完毕再调整回去
  • 牺牲搜索实时性︰增加Refresh Interval的时间
  • 牺牲可靠性: 修改Translog的配置



降低 Refresh的频率

  • 增加refresh_interval 的数值。默认为1s ,如果设置成-1,会禁止自动refresh

    • 避免过于频繁的refresh,而生成过多的segment 文件

    • 但是会降低搜索的实时性

      PUT /my_index/_settings
      {
          "index" : {
              "refresh_interval" : "10s"
          }
      }
      
  • 增大静态配置参数indices.memory.index_buffer_size

    • 默认是10%,会导致自动触发refresh



降低Translog写磁盘的频率,但是会降低容灾能力

  • Index.translog.durability: 默认是request,每个请求都落盘。设置成async,异步写入
  • lndex.translog.sync_interval:设置为60s,每分钟执行一次
  • Index.translog.flush_threshod_size: 默认512 m,可以适当调大。当translog 超过该值,会触发flush



分片设定

  • 副本在写入时设为0,完成后再增加
  • 合理设置主分片数,确保均匀分配在所有数据节点上
  • Index.routing.allocation.total_share_per_node:限定每个索引在每个节点上可分配的主分片数



调整Bulk 线程池和队列

  • 客户端

    • 单个bulk请求体的数据量不要太大,官方建议大约5-15mb
    • 写入端的 bulk请求超时需要足够长,建议60s 以上
    • 写入端尽量将数据轮询打到不同节点。
  • 服务器端

    • 索引创建属于计算密集型任务,应该使用固定大小的线程池来配置。来不及处理的放入队列,线程数应该配置成CPU核心数+1,避免过多的上下文切换
    • 队列大小可以适当增加,不要过大,否则占用的内存会成为GC的负担
    • ES线程池设置: https://blog.csdn.net/justlpf/article/details/103233215
DELETE myindex
PUT myindex
{
  "settings": {
    "index": {
      "refresh_interval": "30s",  #30s一次refresh
      "number_of_shards": "2"
    },
    "routing": {
      "allocation": {
        "total_shards_per_node": "3"  #控制分片,避免数据热点
      }
    },
    "translog": {
      "sync_interval": "30s",
      "durability": "async"    #降低translog落盘频率
    },
    "number_of_replicas": 0		# 副本分片数0
  },
  "mappings": {
    "dynamic": false,     #避免不必要的字段索引,必要时可以通过update by query索引必要的字段
    "properties": {}
  }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

记录一次搭建uniapp-vue3的基础项目

1.使用 HBuilder X 创建uniapp vue3的基础项目 2.安装 自动导包插件 unplugin-auto-import npm install unplugin-auto-import或者 pnpm install unplugin-auto-import2.1 根目录下创建 vite.config.js 复制粘贴以下内容 import { defineConfig } from vite import uni fro…

食品零食小吃商城管理系统-计算机毕设Java|springboot实战项目

🍊作者:计算机毕设匠心工作室 🍊简介:毕业后就一直专业从事计算机软件程序开发,至今也有8年工作经验。擅长Java、Python、微信小程序、安卓、大数据、PHP、.NET|C#、Golang等。 擅长:按照需求定制化开发项目…

一文学会本地部署可视化应用JSONCrack并配置公网地址实现远程协作

文章目录 前言1. Docker安装JSONCrack2. 安装Cpolar内网穿透工具3. 配置JSON Crack界面公网地址4. 远程访问 JSONCrack 界面5. 固定 JSONCrack公网地址 前言 本文主要介绍如何在Linux环境使用Docker安装数据可视化工具JSONCrack,并结合cpolar内网穿透工具实现团队在…

网络编程/在哪些场景中不必要进行网络字节序装换? Windows Sockets: Byte Ordering

文章目录 概述字节序必须转换字节序的的情况不必转换字节序的的情况字节序转换的例程字节序转换函数字节序转换可以不生硬字节序和位序 概述 本文主要讲述了在哪些场景下必须要进行大小端字节序转换,在哪些场景下可以不用进行大小端字节序转换,IP和端口…

<数据集>安全帽和安全背心识别数据集<目标检测>

数据集格式:VOCYOLO格式 图片数量:22141张 标注数量(xml文件个数):22141 标注数量(txt文件个数):22141 标注类别数:3 标注类别名称:[helmet, vest, head] 序号类别名称图片数框数1helmet15937572402v…

程序员如何写PLC程序

PLC是可编程逻辑控制器的简称,常用的编程语言是IEC61131-3(梯形图、结构化文本、指令表、功能块、顺序功能图)和西门子的SCL。程序员常用的编程语言是JS、Java、Python、C/C、Go等。PLC广泛采用编程工具有codesys、博图等。程序员常用的编程工…

XSS DOM破坏实战案例

目录 案例一 思考 源码分析 查找问题 实现 案例二 查看源码 问题查找 实现 实验环境:DOM clobbering | Web Security Academy (portswigger.net) 案例一 里面是一篇篇的博客,点击进去里面是一些评论 思考 尝试一些常规的xss 没什么效果... 他将…

为什么穷大方

为什么有些人明明很穷,却非常的大方呢? 因为他们认知太低,根本不懂钱的重要性,总是想着及时享乐,所以一年到头也存不了什么钱。等到家人孩子需要用钱的时候,什么也拿不出来,还到处去求人。 而真…

【Qt】常用控件QCheckBox

常用控件QCheckBox QCheckBox表示复选按钮,可以允许选中多个。 QCheckBox继承自QAbstractButton 例子:获取复选按钮的取值 使用Qt Designer先大体进行设计 代码实现: #include "widget.h" #include "ui_widget.h"Widge…

Python爬虫——爬取某网站的视频

爬取视频 本次爬取,还是运用的是requests方法 首先进入此网站中,选取你想要爬取的视频,进入视频播放页面,按F12,将网络中的名称栏向上拉找到第一个并点击,可以在标头中,找到后续我们想要的一些…

不能使用乘除法、for、while、if、else、switch、case求1+2+3+...+n

求123...n_牛客题霸_牛客网 (nowcoder.com) 描述 求123...n&#xff0c;要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句&#xff08;A?B:C&#xff09;。 数据范围&#xff1a; 0<n≤2000<n≤200 进阶&#xff1a; 空间复杂度 O(1)O(…

MySQL:查询(万字超详细版)

&#x1f48e;所属专栏&#xff1a; MySQL &#x1f48e;1. 单表查询 &#x1f48e;1.1 全列查询和指定列查询 全列查询&#xff1a; select * from exam; 在实际开发中不要使用 * 来进行查询&#xff0c;因为数据库会很大&#xff0c;影响效率 指定列查询&#xff1a; se…

Redis未授权访问漏洞利用合集

一、基本信息 靶机&#xff1a;IP:192.168.100.40 攻击机&#xff1a;IP:192.168.100.60 二、漏洞 & 过程 Redis 未授权访问漏洞利用无口令远程登录靶机 靶机 cd redis-4.0.8/src./redis-server ../redis.conf 攻击机 ./redis-cli -h 192.168.100.40 Redis 未授权访问…

eNSP 华为ACL配置

华为ACL配置 需求&#xff1a; 公司保证财务部数据安全&#xff0c;禁止研发部门和互联网访问财务服务器&#xff0c;但总裁办不受影响 R1&#xff1a; <Huawei>sys [Huawei]sys Router1 [Router1]undo info-center enable [Router1]int g1/0/0 [Router1-GigabitEth…

openharmony 南向开发基础:ohos自定义子系统,自定义部件,调用hilog部件,hilog日志封装傻瓜式教程

openharmony 南向开发基础:ohos自定义子系统,自定义部件,调用hilog部件,hilog日志封装 自定义单部件 关于开源鸿蒙的南向教程不多,很多都是从官方文档上抄的的例子,官网的例子不是很适合入门,写的很粗糙,不适合傻瓜阅读,毕竟对于刚入行鸿蒙的新手而言,gn语法就是第一劝退魔咒…

【k8s从节点报错】error: You must be logged in to the server (Unauthorized)

k8s主节点可以获取nodes节点信息&#xff0c;但是从节点无法获取&#xff0c;且报错“error: You must be logged in to the server (Unauthorized)” 排查思路&#xff1a; 当时证书过期了&#xff0c;只处理的主节点的证书过期&#xff0c;没有处理从节点的 kubeadm alpha …

解锁 Starknet 的深层洞察:利用 Dune 构建动态数据可视化

原文&#xff1a;https://dev.to/lordghostx/queries-to-insights-visualizing-starknet-data-with-dune-j8p 作者&#xff1a;LordGhostX 编译&#xff1a;TinTinLand Starknet 的链上数据为其区块链生态系统提供了丰富的洞察。它为用户活动、交易模式和网络交互提供了全面…

【系统架构设计】系统规划

【系统架构设计】系统规划 项目的提出和选择可行性研究与效益分析方案的制订和改进新旧系统的分析和比较 项目的提出和选择 Noriaki Kano 提出了顾客质量模型图 假想质量 &#xff1a; 是客户想当然认为产品应该具备的功能或性能&#xff0c;客户并不能正确描述自己想当然要得…

8.MySQL知识巩固-牛客网练习题

目录 SQL228 批量插入数据 描述 SQL202 找出所有员工当前薪水salary情况 描述 示例1 SQL195 查找最晚入职员工的所有信息描述 示例1 SQL196 查找入职员工时间排名倒数第三的员工所有信息描述 SQL201查找薪水记录超过15条的员工号emp_no以及其对应的记录次数t 描述 SQL…

记一次数据库慢查询的处理方法

1.案发现场 今天打开系统&#xff0c;发现有个页面一直报接口超时&#xff0c;然后定位到该接口和对应的查询sql&#xff0c;拿到navicat中去执行发现执行效率确实很慢&#xff0c;sql和执行时间如下&#xff1a;SELECT DISTINCTr.id,r.province,r.city,r.district,r.NAME,r.lo…