Elasticsearch高性能实践

前言

本方案主要从运维层面分析es是实际生产使用过程中的参数优化,深入理解es各个名词及含义,深入分析es的使用过程中应注意的点,详细解释参数设置的原因以及目的,主要包括系统层面,参数层面。除此之外,优化方面还有查询优化和写入优化等。

第一章 基本概念

Elasticsearch 是一个分布式的免费开源搜索和分析引擎,适用于包括文本、数字、地理空间、结构化和非结构化数据等在内的所有类型的数据。Elasticsearch 在 Apache Lucene 的基础上开发而成,由 Elasticsearch N.V.(即现在的 Elastic)于 2010 年首次发布。Elasticsearch 以其简单的 REST 风格 API、分布式特性、速度和可扩展性而闻名,是 Elastic Stack 的核心组件;Elastic Stack 是一套适用于数据采集、扩充、存储、分析和可视化的免费开源工具。人们通常将 Elastic Stack 称为 ELK Stack(代指 Elasticsearch、Logstash 和 Kibana),目前 Elastic Stack 包括一系列丰富的轻量型数据采集代理,这些代理统称为 Beats,可用来向 Elasticsearch 发送数据。
Cluster:包含client、master、 data、 ingest各个节点的集群(其中master data是集群中必须存在的)
Node:集群服务单元
Index:ES中的索引,类似于msyql中的库名,包含一个或多个物理分片,它只是这些分片的逻辑命名空间
Type:一个 index 的不同分类,6.x 后只能配置一个 type,以后将移除
Document:最基础的可被索引的数据单元,如一个 JSON 串
Shards:一个分片是一个底层的工作单元,它仅保存全部数据中的一部分,它是一个 Lucence 实例 (一个 lucene 索引最大包含 2,147,483,519 (= Integer.MAX_VALUE - 128)个文档数量)
Replicas:分片副本,主要用于分片的实时备份,用于保障数据安全,高可用与分担检索压力。

分片与副本
分片与副本关系如图:
在这里插入图片描述
分片 (shard):首先我们需要知道ES 是一个分布式的搜索引擎,我们存放的数据 通常都会分解成不同部分, 分布在不同节点的部分数据就是分片。一个索引可以有多个分片,同一个索引的所有分片的数据集合才是完整的数据。ES 自动管理和组织分片, 并在必要的时候对分片数据进行再平衡分配, 所以用户基本上不用担心分片的处理细节。创建索引时默认的分片数为 5 个,需注意一旦创建不能更改。

副本 (replica):ES 默认创建一份副本,就是说在 5 个主分片的基础上,每个主(Paimary)分片都相应的有一个副(replica)本分片。ES不允许Primary和它的Replica放在同一个节点中,并且同一个节点不接受完全相同的两个Replica。副本并不是越多越好,额外的副本有利有弊,有副本可以有更强的故障恢复能力,但也占了相应副本倍数的磁盘空间。

第二章 硬件优化

1.使用固态SSD

ES 是一种密集使用磁盘的应用,在段合并的时候会频繁操作磁盘,所以对磁盘要求较高,当磁盘速度提升之后,集群的整体性能会大幅度提高。
磁盘的选择,提供以下几点建议:

  • 使用固态硬盘(Solid State Disk)替代机械硬盘。SSD 与机械磁盘相比,具有高效的读写速度和稳定性。

  • 使用 RAID 0。RAID 0 条带化存储,可以提升磁盘读写效率。
    在 ES 的服务器上挂载多块硬盘。使用多块硬盘同时进行读写操作提升效率,在配置文件 ES 中elasticsearch.yml

  • 设置多个存储路径,如下所示:
    path.data:/path/to/data1,/path/to/data2
    注意:避免使用 NFS(Network File System)等远程存储设备,网络的延迟对性能的影响是很大的。

2.设置合理的副本数和分片数

那我们在创建索引的时候,应该创建多少个分片与副本数呢?
对于副本来说比较好确定,可以根据集群规模和存储空间来定,如果存储空间足够大,可以设置多副本,一般建议设置为1-3个即可,但注意,生产环境不可将副本设置为0,若由于异常原因,主数据丢失则数据无法正常使用,设置副本合理值可保证容灾,并且副本数量是可以动态调整的。
对于分片数,是比较难确定的。并不是分片越多越好,查询效率越高,因为在查询过程中,有一个分片合并的过程,如果分片数不断的增加,合并的时间则会增加,而且随着更多的任务需要按顺序排队和处理,更多的小分片不一定要比查询较小数量的更大的分片更快。如果有多个并发查询,则有很多小碎片也会降低查询吞吐量。
一个索引分片数一旦确定,就不能更改,所以我们在创建索引前,要充分的考虑到,以后我们创建的索引所存储的数据量,否则创建了不合适的分片数,会对我们的性能造成很大的影响。一个分片的大小不要超过 50G,一般建议分片为最大为30G,这样的配置有助于集群的健康。实际生产环境还需要对数据进行压测,以确定最合适的分片数,确保更加充分利用ES集群性能。
如果当前es集群已做优化配置,但某个索引分片数并不合理,查询经常超时,那么可以按照时间去创建索引比如 Application_log_202209, Application_log_202210, Application_log_202211,然后进行通配符查询,这种是按照月份进行索引的创建,还可以按照天或者小时,当然,这个取决于数据量是否足够大。

3.系统优化

系统层面的调优主要是内存的设定与避免交换内存。关闭交换分区,我们知道如果ES使用了交换分区,性能会急剧下降。
大多数操作系统尝试将尽可能多的内存用于文件系统缓存,并急切地换掉未使用的应用程序内存。这可能导致部分 JVM 堆甚至其可执行页面被换出到磁盘。

交换对性能和节点稳定性非常不利,应该不惜一切代价避免。它可能导致垃圾收集持续几分钟而不是几毫秒,并且可能导致节点响应缓慢甚至与集群断开连接。在Elastic分布式系统中,让操作系统杀死节点更有效。
系统设置关闭交换分区:
swapoff -a
ES 安装后默认设置的堆内存是 1GB,显然是不够的,我们在生产环境都要重新配置内存。
要设置多少内存给 ES 呢?
其实这是要看我们集群节点的内存大小,还取决于我们是否在服务器节点上还是否要部署其他服务。
如果内存相对很大,如 64G 及以上,并且我们不在 ES 集群上部署其他服务,那么建议 ES 内存可以设置为 31G,我们知道es也是基于jvm的,jvm的最大设置内存一般为31G,所以这里有一个31G性能瓶颈问题,即使你给了 ES 集群大于 32G 的内存,其性能也不一定会更加高效,甚至会低于设置为 32G 时候的性能。
这里为什么是31G呢?
在 Java 中,所有对象都分配在堆上,然后有一个 Klass Pointer 指针指向它的类元数据。 这个指针在 64 位的操作系统上为 64 位,64 位的操作系统可以使用更多的内存(2^64)。在 32 位的系统上为 32 位,32 位的操作系统的最大寻址空间为 4GB(2^32)。 但是 64 位的指针意味着更大的浪费,因为你的指针本身大了。浪费内存不算,更糟糕的是,更大的指针在主内存和缓存器(例如 LLC, L1等)之间移动数据的时候,会占用更多的带宽。
Java 使用内存指针压缩(Compressed Oops)技术来解决这个问题。它的指针不再表示对象在内存中的精确位置,而是表示偏移量。
这意味着 32 位的指针可以引用 4GB 个 Byte,而不是 4GB 个 bit。也就是说,当堆内存为 32GB 的物理内存时,也可以用 32 位的指针表示。不过,在越过那个神奇的边界 32GB 时,指针就会变为普通对象的指针,每个对象的指针都变长了,就会浪费更多的内存,降低了 CPU 的性能,还要让 GC 应对更大的内存。
事实上,当内存到达 40~40GB 时,有效的内存才相当于内存对象指针压缩技术时的 32GB 内存,所以即便你有足够的内存,也尽量不要超过 32G,因此我们建议可以设置为 31GB。
以我们以前生产环境为例,单台服务器内存为64G,设置es内存为31G,留一半内存给系统,注意系统只运行了es服务,并未运行其他服务器抢占资源,以充分发挥ES集群的性能。还有一点就是确保堆内存最小值(Xms)与最大值(Xmx)的大小是相同的,防止程序在运行时改变堆内存大小,这是一个很耗系统资源的过程。
这里有个问题如果我的机器内存大于64G呢?
比如我有个机器有 128G 内存,我可以创建两个 Node,使用 32G 内存。也就是说 64G 内存给 ES 的堆内存,剩下的 64G 给 Lucene。其他类型依次类推。但并不建议一台机器运行多个同一集群的es节点。
避免交换内存,可以在配置文件中对内存进行锁定,以避免交换内存(也可以在操作系统层面进行关闭内存交换)。
对应的参数: bootstrap.mlockall: true

第三章 参数优化

1.Elasticsearch.yml参数解析

  • node.name: “node1”:集群中的节点名,在同一个集群中不能重复。节点的名称一旦设置,就不能再改变了。当然,也可以设置成服务器的主机名称,例如 node.name:${HOSTNAME}。
  • noed.master:true:指定该节点是否有资格被选举成为 Master 节点,默认是 True,如果被设置为 True,则只是有资格成为 Master 节点,具体能否成为 Master 节点,需要通过选举产生。
  • node.data:true:指定该节点是否存储索引数据,默认为 True。数据的增、删、改、查都是在 Data 节点完成的。
  • index.number_of_shards:5:设置都索引分片个数,默认是 5 片。也可以在创建索引时设置该值,具体设置为多大都值要根据数据量的大小来定。如果数据量不大,则设置成 1 时效率最高。
  • index.number_of_replicas:1:设置默认的索引副本个数,默认为 1 个。副本数越多,集群的可用性越好,但是写索引时需要同步的数据越多。
  • path.conf:/path/to/conf:设置配置文件的存储路径,默认是 ES 目录下的 Conf 文件夹。建议使用默认值。
  • path.data:/path/to/data1,/path/to/data2:设置索引数据多存储路径,默认是 ES 根目录下的 Data 文件夹。切记不要使用默认值,因为若 ES 进行了升级,则有可能数据全部丢失。 可以用半角逗号隔开设置的多个存储路径,在多硬盘的服务器上设置多个存储路径是很有必要的。
  • path.logs:/path/to/logs:设置日志文件的存储路径,默认是 ES 根目录下的 Logs,建议修改到其他地方。
  • path.plugins:/path/to/plugins:设置第三方插件的存放路径,默认是 ES 根目录下的 Plugins 文件夹。
  • bootstrap.mlockall:true:设置为 True 时可锁住内存。因为当 JVM 开始 Swap 时,ES 的效率会降低,所以要保证它不 Swap。
  • network.bind_host:192.168.0.1:设置本节点绑定的 IP 地址,IP 地址类型是 IPv4 或 IPv6,默认为 0.0.0.0。
  • network.publish_host:192.168.0.1:设置其他节点和该节点交互的 IP 地址,如果不设置,则会进行自我判断。
  • network.host:192.168.0.1:用于同时设置 bind_host 和 publish_host 这两个参数。
  • http.port:9200:设置对外服务的 HTTP 端口,默认为 9200。ES 的节点需要配置两个端口号,一个对外提供服务的端口号,一个是集群内部使用的端口号。 http.port 设置的是对外提供服务的端口号。注意,如果在一个服务器上配置多个节点,则切记对端口号进行区分。
  • transport.tcp.port:9300:设置集群内部的节点间交互的 TCP 端口,默认是 9300。注意,如果在一个服务器配置多个节点,则切记对端口号进行区分。
  • transport.tcp.compress:true:设置在节点间传输数据时是否压缩,默认为 False,不压缩。
  • discovery.zen.minimum_master_nodes:1:设置在选举 Master 节点时需要参与的最少的候选主节点数,默认为 1。如果使用默认值,则当网络不稳定时有可能会出现脑裂。 合理的数值为(master_eligible_nodes/2)+1,其中 master_eligible_nodes 表示集群中的候选主节点数。
  • discovery.zen.ping.timeout:3s:设置在集群中自动发现其他节点时 Ping 连接的超时时间,默认为 3 秒。 在较差的网络环境下需要设置得大一点,防止因误判该节点的存活状态而导致分片的转移。

2.其他重要参数

2.1 refresh参数
Lucene 将待写入的数据先写到内存中,超过 1 秒(默认)时就会触发一次 Refresh,然后 Refresh 会把内存中的的数据刷新到操作系统的文件缓存系统中。
如果我们对搜索的实效性要求不高,可以将 Refresh 周期延长,例如 30 秒,若对实时性要求较高,切勿将此参数设置的较高(默认1s即可)。
设置示例:

index.refresh_interval:30s

2.2 Flush参数
Flush 的主要目的是把文件缓存系统中的段持久化到硬盘,当 Translog 的数据量达到 512MB 或者 30 分钟时,会触发一次 Flush。
index.translog.flush_threshold_size 参数的默认值是 512MB,我们进行修改。

2.3 合并线程参数
index.merge.scheduler.max_thread_count: 1 索引 merge 最大线程数设置为 1 个,该参数可以有效调节写入的性能。因为在存储介质上并发写,由于寻址的原因,写入性能不会提升,只会降低。
如果是机械盘可以设置为1
index.merge.scheduler.max_thread_count: 1,如果是SSD,则可以设置多个线程,比如6个合并线程:
index.merge.scheduler.max_thread_count: 6
如何确定设置多少呢?
首先我们的服务器是多线程的,不可超过服务器的最大线程数,其次我们还需要通过一定的性能压测,来查看设置的参数是否有利于提升es集群性能。
段合并,合并在后台定期执行,比较大的 segment 需要很长时间才能完成,为了减少对其他操作的影响(如检索),elasticsearch 进行阈值限制,默认是 20MB/s,可配置的参数:“indices.store.throttle.max_bytes_per_sec” : “200mb”

2.4 index缓存参数
如果我们要进行非常重的高并发写入操作可以将indices.memory.index_buffer_size 调大一些,index buffer 的大小是所有的 shard 公用的,一般建议,对于每个 shard 来说,最多给 512mb,因为再大性能就没什么提升了。ES 会将这个设置作为每个 shard 共享的 index buffer,那些特别活跃的 shard 会更多的使用这个 buffer。默认这个参数的值是 10%,也就是 jvm heap 的 10%。
indices.memory.index_buffer_size:512m

2.5 超时参数

  • discovery.zen.ping_timeout 判断 master 选举过程中,发现其他 node 存活的超时设置
  • discovery.zen.fd.ping_interval 节点被 ping 的频率,检测节点是否存活
  • discovery.zen.fd.ping_timeout 节点存活响应的时间,默认为 30s,如果网络可能存在隐患,可以适当调大
  • discovery.zen.fd.ping_retries ping 失败/超时多少导致节点被视为失败,默认为 3

2.6 优化完成参数示例

index.merge.scheduler.max_thread_count:1# 索引merge最大线程数
indices.memory.index_buffer_size:30%# 内存
index.translog.durability:async#异步写硬盘,增大写的速度
index.translog.sync_interval:120s#translog 间隔时间
discovery.zen.ping_timeout:120s# 心跳超时时间
discovery.zen.fd.ping_interval:120s# 节点检测时间
discovery.zen.fd.ping_timeout:120s#ping 超时时间
discovery.zen.fd.ping_retries:6# 心跳重试次数
thread_pool.bulk.size:20# 写入线程个数
thread_pool.bulk.queue_size:1000# 写入线程队列大小
index.refresh_interval:300s#index 刷新间隔

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

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

相关文章

Nacos系列:Nacos 控制台手册

引言 Nacos是阿里巴巴中间件部门开源的一款用于服务发现和配置管理的产品,Nacos 控制台主要旨在于增强对于服务列表、健康状态管理、服务治理、分布式配置管理等方面的管控能力,以便进一步帮助用户降低管理微服务应用架构的成本。 一、访问 Nacos 控制台…

FPGA 第十四讲 分频器--偶分频

时间:2024.12.14 时钟对于 FPGA 是非常重要的,但板载晶振提供的时钟信号频率是固定的,不一定满足工程需求,所以使用分频或倍频产生需要的时钟是很有必要的。 一、学习内容 1.分频器 分频器是数字系统设计中最常见的基本电路之一。所谓“分频”,就是把输入信号的频率变成…

Linux:Git

Git常见指令: git help xx_command git xx_command --help git --version 查看git版本git config --global user.name "xxx_name" 全局级别的签名设置,全局的放在本用 git config --global user.ema…

如何使用aws的bedrock训练适合自己的模型

使用 Amazon Bedrock 训练适合自己的模型是一个涉及多个步骤的过程,包括数据准备、模型选择、训练和部署。以下是九河云总结的详细的步骤指南,帮助您在 AWS Bedrock 上训练和部署自定义模型。 ### 1. **准备工作** 在开始训练模型之前,您需…

30.攻防世界unserialize3

进入场景 解读一下 这个类 xctf 中有一个公共属性 $flag &#xff0c;其值为 111 &#xff0c;并且定义了一个 __wakeup 魔术方法&#xff0c;当对象被反序列化时会自动调用该方法&#xff0c;该方法会输出 bad requests 并终止程序的执行。 ?code提示了参数 <?php clas…

PWM调节DCDC参数计算原理

1、动态电压频率调整DVFS SOC芯片的核电压、GPU电压、NPU电压、GPU电压等&#xff0c;都会根据性能和实际应用场景来进行电压和频率的调整。 即动态电压频率调整DVFS&#xff08;Dynamic Voltage and Frequency scaling&#xff09;&#xff0c;优化性能和功耗。 比如某SOC在…

Python爬虫之Selenium的应用

【1】Selenium基础介绍 1.什么是selenium&#xff1f; &#xff08;1&#xff09;Selenium是一个用于Web应用程序测试的工具。 &#xff08;2&#xff09;Selenium 测试直接运行在浏览器中&#xff0c;就像真正的用户在操作一样。 &#xff08;3&#xff09;支持通过各种driv…

DocFlow票据AI自动化处理工具:出色的文档解析+抽取能力,提升企业文档数字化管理效能

目录 财务应付 金融信贷业务 近期&#xff0c;DocFlow票据自动化产品正式上线。DocFlow是一款票据AI自动化处理工具&#xff0c;支持不同版式单据智能分类扩展&#xff0c;可选功能插件配置流程&#xff0c;满足多样业务场景。 随着全球化与信息化进程&#xff0c;企业的文件…

Python高性能web框架-FastApi教程:(3)路径操作装饰器方法的参数

路径操作装饰器方法的参数 1. 定义带有参数的POST请求路由 app.post(/items,tags[这是items测试接口],summary这是items测试的summary,description这是items测试的description,response_description这是items测试的response_description) def test():return {items: items数据…

Visual Studio Community安装WebForm创建和数据连接

目录 一、安装Visual Studio Community 1.下载Visual Studio Community 2.双击安装 3.配置 二、项目创建 1.创建新项目 2.配置新项目 3.创建web窗体 4.代码分部 5.文件打开问题 三、数据库访问 1.自己先装一个sql server 2.创建实体数据模型 3.创建连接 4.修改更…

【flutter】webview下载文件方法集锦

说明&#xff1a;android的webview是不支持下载的&#xff01;&#xff01;&#xff01; 所以我们需要监听下载接口 然后手动执行下载操作&#xff0c;分为三种类型 直接打开浏览器下载&#xff08;最简单&#xff09;&#xff0c;但是一些下载接口需要cookie信息时不能满足 …

一行一行出字的视频怎么做?简单的操作方法

在视频制作中&#xff0c;逐行出现的字幕效果不仅能够增强视觉冲击力&#xff0c;还能让观众更加专注于内容&#xff0c;特别适合用于教育视频、书单推荐、诗歌朗诵等多种场景。下面&#xff0c;我们将详细介绍如何影忆&#xff0c;来制作这种逐行出字的视频效果。 1.字幕逐行…

专题三:简单多状态 dp 问题

> 作者&#xff1a;დ旧言~ > 座右铭&#xff1a;松树千年终是朽&#xff0c;槿花一日自为荣。 > 目标&#xff1a;了解什么是记忆化搜索&#xff0c;并且掌握记忆化搜索算法。 > 毒鸡汤&#xff1a;有些事情&#xff0c;总是不明白&#xff0c;所以我不会坚持。早…

海外组网之优解:外贸 SD-WAN 跨境组网专线赋能企业全球互联

在全球化商业进程中&#xff0c;众多企业积极拓展海外业务&#xff0c;设立国内外分支&#xff0c;然而分支组网难题也随之而来。外贸 SD-WAN 跨境专线成为解决此类问题的优选方案&#xff0c;为企业提供高效稳定的网络连接。 一、SD-WAN 跨境组网专线优势 &#xff08;一&…

【机器人】轨迹规划 之 spline 规划

在轨迹规划中&#xff0c;使用 spline &#xff08;通常是指通过样条曲线进行轨迹规划&#xff09;可以实现平滑、连续的路径。以下是使用样条&#xff08;如B样条、三次样条插值&#xff09;的具体方法和步骤&#xff0c;结合一个简单的例子说明&#xff1a; 示例场景&#xf…

Python生成对抗神经网络GAN预测股票及LSTMs、ARIMA对比分析ETF金融时间序列可视化

全文链接&#xff1a;https://tecdat.cn/?p38528 本文聚焦于利用生成对抗网络&#xff08;GANs&#xff09;进行金融时间序列的概率预测。介绍了一种新颖的基于经济学驱动的生成器损失函数&#xff0c;使 GANs 更适用于分类任务并置于监督学习环境中&#xff0c;能给出价格回…

【渗透测试】信息收集二

其他信息收集 在渗透测试中&#xff0c;历史漏洞信息收集是一项重要的工作&#xff0c;以下是相关介绍&#xff1a; 历史漏洞信息收集的重要性 提高效率&#xff1a;通过收集目标系统或应用程序的历史漏洞信息&#xff0c;可以快速定位可能存在的安全问题&#xff0c;避免重复…

【泛微系统】流程发起次数报表

流程发起次数报表 应用场景: 查询所有发起过业务流程的员工的信息,可作为绩效考核、系统使用情况等依据; 如何使用该SQL生成系统在线报表,实时查询最新的发起数据? 1、数据库创建视图,并定义一个视图名称如;view_test1 2、系统后台建模引擎-表单-右键创建一个虚拟表单…

k8s中用filebeat文件如何收集不同service的日志

以下是一个详细的从在 Kubernetes 集群中部署 Filebeat&#xff0c;到实现按web-oper、web-api微服务分离日志并存储到不同索引的完整方案&#xff1a; 理解需求&#xff1a;按服务分离日志索引 在 Kubernetes 集群中&#xff0c;有web-oper和web-api两种微服务&#xff0c;希…

【LeetCode】2406、将区间分为最少组数

【LeetCode】2406、将区间分为最少组数 文章目录 一、数据结构-堆、贪心1.1 数据结构-堆、贪心1.2 多语言解法 二、扫描线2.1 扫描线 一、数据结构-堆、贪心 1.1 数据结构-堆、贪心 题目已知一些区间, 需要尽量合并, 使 组 最少. 可以用图解画一下 因为尽量合并, 为了紧凑, …