Elasticsearch 优化常用思路

1、硬件选择 

Elasticsearch 的基础是 Lucene,所有的索引和文档数据是存储在本地的磁盘中,具体的路径可在 ES 的配置文件../config/elasticsearch.yml 中配置,如下: 

#----------------------------------- Paths

------------------------------------

#  

# Path to directory where to store the data (separate multiple locations by comma):

#

#path.data: /path/to/data

#

# Path to log files:

#

#path.logs: /path/to/logs #

     磁盘在现代服务器上通常都是瓶颈。Elasticsearch 重度使用磁盘,你的磁盘能处理的吞吐量越大,你的节点就越稳定。这里有一些优化磁盘 I/O 的技巧: 

  1. 使用 SSD, 他们比机械磁盘优秀多了。 
  2. 使用 RAID 0。条带化 RAID 会提高磁盘 I/O,代价显然就是当一块硬盘故障时整个就故障了。不要使用镜像或者奇偶校验 RAID 因为副本已经提供了这个功能。 
  3. 另外,使用多块硬盘,并允许 Elasticsearch 通过多个 path.data 目录配置把数据条带化分配到它们上面。 
  4. 不要使用远程挂载的存储,比如 NFS 或者 SMB/CIFS。这个引入的延迟对性能来说完全是背道而驰的。 

2、分片策略 

2.1、合理设置分片数 

    分片和副本的设计为 ES 提供了支持分布式和故障转移的特性,但并不意味着分片和副本是可以无限分配的。而且索引的分片完成分配后由于索引的路由机制,我们是不能重新修改分片数的。可能有人会说,我不知道这个索引将来会变得多大,并且过后我也不能更改索引的大小,所以为了保险起见,还是给它设为 1000 个分片吧。但是需要知道的是,一个分片并不是没有代价的。需要了解: 

  1. 一个分片的底层即为一个 Lucene 索引,会消耗一定文件句柄、内存、以及 CPU 运转。 
  2. 每一个搜索请求都需要命中索引中的每一个分片,如果每一个分片都处于不同的节点还好, 但如果多个分片都需要在同一个节点上竞争使用相同的资源就有些糟糕了。 
  3. 用于计算相关度的词项统计信息是基于分片的。如果有许多分片,每一个都只有很少的数据会导致很低的相关度。 

     一个业务索引具体需要分配多少分片可能需要架构师和技术人员对业务的增长有个预先的判断,横向扩展应当分阶段进行。为下一阶段准备好足够的资源。 只有当你进入到下一个阶段,你才有时间思考需要作出哪些改变来达到这个阶段。一般来说,我们遵循一些原则: 

  1. 控制每个分片占用的硬盘容量不超过 ES 的最大 JVM 的堆空间设置(一般设置不超过 32G,参考下文的 JVM 设置原则),因此,如果索引的总容量在 500G 左右,那分片大小在 16 个左右即可;当然,最好同时考虑原则 2。 
  2. 考虑一下 node 数量,一般一个节点有时候就是一台物理机,如果分片数过多,大大超过了节点数,很可能会导致一个节点上存在多个分片,一旦该节点故障,即使保持了1个以上的副本,同样有可能会导致数据丢失,集群无法恢复。所以, 一般都设置分片数不超过节点数的3倍。 
  3. 主分片,副本和节点最大数之间数量,我们分配的时候可以参考以下关系:节点数<=主分片数*(副本数+1) 

2.2、 推迟分片分配 

对于节点瞬时中断的问题,默认情况,集群会等待一分钟来查看节点是否会重新加入,如果这个节点在此期间重新加入,重新加入的节点会保持其现有的分片数据,不会触发新的分片分配。这样就可以减少 ES 在自动再平衡可用分片时所带来的极大开销。 通过修改参数 delayed_timeout ,可以延长再均衡的时间,可以全局设置也可以在索引

级别进行修改:

PUT /_all/_settings  

{

  "settings": {

    "index.unassigned.node_left.delayed_timeout": "5m"  

  }

}

3、路由选择 

当我们查询文档的时候,Elasticsearch 如何知道一个文档应该存放到哪个分片中呢?它其实是通过下面这个公式来计算出来:  

shard = hash(routing) % number_of_primary_shards

routing 默认值是文档的 id,也可以采用自定义值,比如用户 id。 

不带 routing 查询 

在查询的时候因为不知道要查询的数据具体在哪个分片上,所以整个过程分为 2 个步骤 

  • 分发:请求到达协调节点后,协调节点将查询请求分发到每个分片上。 
  • 聚合: 协调节点搜集到每个分片上查询结果,在将查询的结果进行排序,之后给用户返回结果。 

带 routing 查询 

查询的时候,可以直接根据 routing 信息定位到某个分配查询,不需要查询所有的分配,经过协调节点排序。 向上面自定义的用户查询,如果 routing 设置为 userid 的话,就可以直接查询出数据来,效率提升很多。 

4、写入速度优化 

ES 的默认配置,是综合了数据可靠性、写入速度、搜索实时性等因素。实际使用时,我们需要根据公司要求,进行偏向性的优化。 

针对于搜索性能要求不高,但是对写入要求较高的场景,我们需要尽可能的选择恰当写优化策略。综合来说,可以考虑以下几个方面来提升写索引的性能: 

  1. 加大 Translog Flush ,目的是降低 Iops、Writeblock。 
  2. 增加 Index Refresh 间隔,目的是减少 Segment Merge 的次数。 
  3. 调整 Bulk 线程池和队列。 
  4. 优化节点间的任务分布。 
  5. 优化 Lucene 层的索引建立,目的是降低 CPU 及 IO。 

4.1、批量数据提交 

ES 提供了 Bulk API 支持批量操作,当我们有大量的写任务时,可以使用 Bulk 来进行批量写入。 

通用的策略如下:Bulk 默认设置批量提交的数据量不能超过 100M。数据条数一般是根据文档的大小和服务器性能而定的,但是单次批处理的数据大小应从 5MB~15MB 逐渐增加,当性能没有提升时,把这个数据量作为最大值。 

4.2、优化存储设备 

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

4.3、合理使用合并 

Lucene 以段的形式存储数据。当有新的数据写入索引时,Lucene 就会自动创建一个新的段。 

随着数据量的变化,段的数量会越来越多,消耗的多文件句柄数及 CPU 就越多,查询效率就会下降。 

由于 Lucene 段合并的计算量庞大,会消耗大量的 I/O,所以 ES 默认采用较保守的策略,让后台定期进行段合并 

4.4、减少 Refresh 的次数 

Lucene 在新增数据时,采用了延迟写入的策略,默认情况下索引的 refresh_interval为 1秒。 

Lucene 将待写入的数据先写到内存中,超过1秒(默认)时就会触发一次 Refresh,然后 Refresh 会把内存中的的数据刷新到操作系统的文件缓存系统中。 

如果我们对搜索的实效性要求不高,可以将 Refresh 周期延长,例如 30 秒。 这样还可以有效地减少段刷新次数,但这同时意味着需要消耗更多的 Heap 内存。 

4.5、加大 Flush 设置 

Flush 的主要目的是把文件缓存系统中的段持久化到硬盘,当 Translog 的数据量达到512MB 或者 30 分钟时,会触发一次 Flush。 

index.translog.flush_threshold_size 参数的默认值是 512MB,我们进行修改。 增加参数值意味着文件缓存系统中可能需要存储更多的数据,所以我们需要为操作系统的文件缓存系统留下足够的空间。

4.6、减少副本的数量 

ES 为了保证集群的可用性,提供了 Replicas(副本)支持,然而每个副本也会执行分析、索引及可能的合并过程,所以 Replicas 的数量会严重影响写索引的效率。 

当写索引时,需要把写入的数据都同步到副本节点,副本节点越多,写索引的效率就越慢。 

如果我们需要大批量进行写入操作,可以先禁止 Replica 复制,设置 index.number_of_replicas: 0 关闭副本。在写入完成后,Replica 修改回正常的状态。 

5、内存设置 

ES 默认安装后设置的内存是1GB,对于任何一个现实业务来说,这个设置都太小了。 如果是通过解压安装的 ES,则在 ES 安装文件中包含一个 jvm.option 文件,添加如下命令来设置 ES 的堆大小,Xms 表示堆的初始大小,Xmx 表示可分配的最大内存,都是 1GB。 确保 Xmx 和 Xms 的大小是相同的,其目的是为了能够在 Java 垃圾回收机制清理完堆区后不需要重新分隔计算堆区的大小而浪费资源,可以减轻伸缩堆大小带来的压力。 

假设你有一个 64G 内存的机器,按照正常思维思考,你可能会认为把 64G 内存都给 ES 比较好,但现实是这样吗, 越大越好?虽然内存对 ES 来说是非常重要的,但是答案是否定的! 

因为 ES 堆内存的分配需要满足以下两个原则: 

  1. 不要超过物理内存的 50%:Lucene 的设计目的是把底层 OS 里的数据缓存到内存中。 Lucene 的段是分别存储到单个文件中的,这些文件都是不会变化的,所以很利于缓存,同时操作系统也会把这些段文件缓存起来,以便更快的访问。 如果我们设置的堆内存过大,Lucene 可用的内存将会减少,就会严重影响降低 Lucene 的全文本查询性能。 
  2. 堆内存的大小最好不要超过 32GB:在 Java 中,所有对象都分配在堆上,然后有一个 Klass Pointer 指针指向它的类元数据。 

这个指针在 64 位的操作系统上为 64 位,64 位的操作系统可以使用更多的内存(2^64)。在 32 位  的系统上为 32 位,32 位的操作系统的最大寻址空间为 4GB(2^32)。 但是 64 位的指针意味着更大的浪费,因为你的指针本身大了。浪费内存不算,更糟糕的是,更大的指针在主内存和缓存器(例如 LLC, L1 等)之间移动数据的时候,会占用更多的带宽。 

最终我们都会采用31G设置 

假设你有个机器有 128 GB 的内存,你可以创建两个节点,每个节点内存分配不超过 32 GB。 也就是说不超过 64 GB 内存给 ES 的堆内存,剩下的超过 64 GB 的内存给 Lucene

6、其他重要配置 

参数名 

参数值 

说明 

cluster.name

elasticsearch

配置 ES 的集群名称,默认值是 ES,建议改成与所

存数据相关的名称,ES 会自动发现在同一网段下的集群名称相同的节点 

node.name

node-1

集群中的节点名,在同一个集群中不能重复。节点的名称一旦设置,就不能再改变了。当然,也可以设置成服务器的主机名称,例如 node.name:${HOSTNAME}。 

node.master

true

指定该节点是否有资格被选举成为 Master 节点,默认是 True,如果被设置为 True,则只是有资格成为 Master 节点,具体能否成为 Master 节点,需要通过选举产生。 

node.data

true

指定该节点是否存储索引数据,默认为 True。数据的增、删、改、查都是在 Data 节点完成的。 

index.number_of_shards

1

设置都索引分片个数,默认是 1 片。也可以在创建索引时设置该值,具体设置为多大都值要根据数据量的大小来定。如果数据量不大,则设置成 1 时效率最高 

index.number_of_replicas

1

设置默认的索引副本个数,默认为 1 个。副本数越多,集群的可用性越好,但是写索引时需要同步的数据越多。 

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 秒。 

在较差的网络环境下需要设置得大一点,防止因误

判该节点的存活状态而导致分片的转移 

 

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

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

相关文章

LT8713SX高性能Type-C/DP1.4到Type-C/DP1.4/HDMI2.0转换器,USB3.0高速双向无源开关,支持同屏异显

LT8713SX是一款高性能Type-C/DP1.4到Type-C/DP1.4/HDMI2.0转换器&#xff0c;具有三个可配置的DP1.4/HDMI2.0/ dp输出接口和音频输出接口。LT8713SX支持DisplayPort单流传输(SST)模式和多流传输(MST)模式。当接收到多个视频/音频流&#xff0c;这些视频/音频流被打包并通过单个…

【Java系列】文件操作详解

个人主页&#xff1a;兜里有颗棉花糖 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 兜里有颗棉花糖 原创 收录于专栏【Java系列专栏】【JaveEE学习专栏】 本专栏旨在分享学习JavaEE的一点学习心得&#xff0c;欢迎大家在评论区交流讨论&#x1f48c; 目录 …

计算机网络——基础知识汇总(八)

个人名片&#xff1a; &#x1f981;作者简介&#xff1a;一名喜欢分享和记录学习的在校大学生 &#x1f42f;个人主页&#xff1a;妄北y &#x1f427;个人QQ&#xff1a;2061314755 &#x1f43b;个人邮箱&#xff1a;2061314755qq.com &#x1f989;个人WeChat&#xff1a;V…

vim 命令速记

vim 常用命令 编辑模式&#xff0c; ESC-> 命令模式&#xff08;常规模式&#xff09;&#xff0c;命令模式下输入&#xff1a;->底行模式 常规模式下&#xff1a; i&#xff1a;切换到插入 / 查找&#xff0c;查到后 n下一个 N上一个底行模式下&#xff1a; q 不保…

网络通信(1)-网络通信原理

目录 一、网络概述 二、网络基础架构 三、网络协议 四、网络层次模型

学习Go语言Web框架Gee总结--上下文Context(二)

学习Go语言Web框架Gee总结--上下文Context context/go.modcontext/main.gocontext/gee/context.gocontext/gee/router.gocontext/gee/gee.go 学习网站来源&#xff1a;Gee 项目目录结构&#xff1a; context/go.mod module examplego 1.21.5require gee v0.0.0 replace gee…

【23-24 秋学期】NNDL 作业13 优化算法3D可视化

编程实现优化算法&#xff0c;并3D可视化 1. 函数3D可视化 分别画出 和 的3D图 代码如下&#xff1a; from mpl_toolkits.mplot3d import Axes3D import numpy as np from matplotlib import pyplot as plt import torch from nndl.op import Op# 画出x**2 class Optimized…

查看ios 应用程序性能

目录 摘要 前言 性能概括 CPU内存监控 内存监控 磁盘监控 网络监控 GPU fps 摘要 本篇博文将介绍一款重量级性能测试工具——克魔助手&#xff0c;针对iOS应用程序的性能监控进行详细介绍。通过克魔助手&#xff0c;开发者可以方便地查看应用程序的CPU、内存、GPU性能…

【Python】配置环境变量

Python配置Windows系统环境变量 打开电脑属性 ——> 高级系统设置 ——> 高级 ——> 环境变量 Python安装目录 D:\Program Files\Python39 winR打开运行&#xff0c;输入cmd打开命令窗口 python -V

vivado XDC优先级

XDC优先级 关于XDC优先级 Xilinx Design Constraints&#xff08;XDC&#xff09;的优先级规则继承自Synopsys Design限制&#xff08;SDC&#xff09;。本章讨论如何解决约束冲突或重叠。 XDC约束顺序 XDC约束是按顺序解释的命令。对于等效约束&#xff0c;最后一个约束优…

基于Java SSM框架实现停车场管理系统项目【项目源码+论文说明】计算机毕业设计

基于java的SSM框架实现停车场管理系统演示 摘要 以往的停车场管理事务处理主要使用的是传统的人工管理方式&#xff0c;这种管理方式存在着管理效率低、操作流程繁琐、保密性差等缺点&#xff0c;长期的人工管理模式会产生大量的文本车辆上报与文本数据&#xff0c;这对事务的…

BERT模型

BERT&#xff08;Bidirectional Encoder Representations from Transformers&#xff09;是一个由谷歌在2018年提出的自然语言处理&#xff08;NLP&#xff09;预训练模型。 BERT&#xff08;双向编码器表示&#xff09;模型是一种基于Transformer的架构&#xff0c;它用于涉及…

Latex使用BibTeX添加参考文献,保持专有名词原格式,如全部大写方法

一、背景 当我们使用Latex写文章时&#xff0c;通常使用BibTeX的方式添加参考文献&#xff0c;这种方式非常方便&#xff0c;可以使用期刊定义好的参考文献格式。但有时&#xff0c;某篇参考文献题目中含有专有名词时&#xff0c;如DMPs&#xff0c;参考文献会自动将其转为小写…

Android ImageView的Bitmap在scaleType情况下Bitmap顶部与底部RectF坐标,Kotlin

Android ImageView的Bitmap在scaleType情况下&#xff0c;Bitmap顶部与底部RectF坐标&#xff0c;Kotlin 通常&#xff0c;在ImageView设置scaleType后&#xff0c;Android会把原始图片通过缩放放在ImageView里面&#xff0c;例如&#xff1a; <ImageViewandroid:id"id…

【心得】PHP反序列化高级利用(phar|session)个人笔记

目录 ①phar反序列化 ②session反序列化 ①phar反序列化 phar 认为是java的jar包 calc.exe phar能干什么 多个php合并为独立压缩包&#xff0c;不解压就能执行里面的php文件&#xff0c;支持web服务器和命令行 phar协议 phar://xxx.phar $phar->setmetadata($h); m…

Redis:原理+项目实战——Redis实战2(Redis实现短信登录(原理剖析+代码优化))

&#x1f468;‍&#x1f393;作者简介&#xff1a;一位大四、研0学生&#xff0c;正在努力准备大四暑假的实习 &#x1f30c;上期文章&#xff1a;Redis&#xff1a;原理项目实战——Redis实战1&#xff08;session实现短信登录&#xff08;并剖析问题&#xff09;&#xff09…

实现CodeWave 低代码开发平台快速应用开发的完整指南

目录 前言1 CodeWave开发流程2 应用创建2.1 新建应用2.2 从应用模板创建应用 3 数据模型设计3.1 实体设计3.2 结构设计3.3 枚举设计 4 逻辑设计4.1 查询数据源设置4.2 组件和属性配置4.3 属性设置与服务端全局变量 5 页面设计5.1 选择页面模板5.2 前端全局变量设计5.3 事件逻辑…

cocos creator + vscode debug

安装插件 安装插件&#xff1a;JavaScript Debugger 配置 7456 为本地cocos creator的启动端口 启动debug调试 选择对应的启动方式

编程笔记 html5cssjs 020 HTML URL

编程笔记 html5&css&js 020 HTML URL HTML 统一资源定位器(Uniform Resource Locators)。URL 是一个网页地址。 URL可以由字母组成&#xff0c;如"baidu.com"&#xff0c;或互联网协议&#xff08;IP&#xff09;地址&#xff1a; 192.68.12.12。大多数人进入…

彻底理解前端安全面试题(2)—— CSRF 攻击,跨站请求伪造攻击详解,建议收藏(含源码)

前言 前端关于网络安全看似高深莫测&#xff0c;其实来来回回就那么点东西&#xff0c;我总结一下就是 3 1 4&#xff0c;3个用字母描述的【分别是 XSS、CSRF、CORS】 一个中间人攻击。当然 CORS 同源策略是为了防止攻击的安全策略&#xff0c;其他的都是网络攻击。除了这…