写给Java应用开发看的Elasticsearch调优手册

news2024/11/19 19:21:41

随着数据量的增长,MySQL在很多场景下,似乎已经无能为力了,所以有不少应用的数据从MySQL迁移到了Elasticsearch,我们的应用就在其中。由于开发时间紧张,所以仅仅只是了解了下Elasticsearch的基本知识,随便写了几个Demo,然后直接在正式的环境中使用Elasticsearch。因为给我们应用分配的Elasticsearch服务器足够强大,Elasticsearch本身也设计的足够好,当时数据量也没有那么海量,并发也没有那么高,所以一直没有问题,但是该来的总会来,随着公司的发展,数据量也在直线增长,并发越来越高,性能问题越来越明显,看着公司内,有越来越多的应用接入了Elasticsearch,看着公司外,有越来越的公司也引入了Elasticsearch,我意识到必须深入的了解下Elasticsearch。经过大半年的断断续续学习,终于对Elasticsearch有了一定的了解,但是我毕竟不是专门做搜索引擎的,更没有强大的算法、数据结构思维,所以对Elasticsearch的了解也仅仅是停留在“用的不这么差”的程度上,所以本篇博客主要是写给Java应用开发看的,如果是专门做搜索引擎的,就一笑而过吧。

优化漏斗

凡是涉及到某个组件的性能调优,我们在脑海中就要浮现出一张很经典的优化漏斗图:

左边就是很经典的漏斗图,漏斗分为四层,从上到下分别为:

  • 使用
  • 应用配置
  • JVM
  • OS

总的来说,层级在上面的,调优的效果越明显,由于我们的Elasticsearch是独立部署在服务器上的,所以服务器的配置也至关重要。对于Elasticsearch而言,硬件配置是基础,正确的使用姿势是核心,缺一不可。

本篇博客,我们就从这五个方面来对Elasticsearch进行调优。

硬件

Elasticsearch和普通应用不同,普通应用也许4C8G的配置就足够了,但是Elasticsearch需要比较好的配置,如果配置实在太低,就放弃Elasticsearch吧。

节点配置

Elasticsearch有三个常用的节点类型:Master节点、数据节点、协调节点,我们来看下这三种节点的职责以及需要什么样的配置。

  • 数据节点:主要负责保存数据,查询数据,所以这个节点的配置要求是最高的,不管是CPU、内存、磁盘,都要高配的,磁盘最好采用RAID0、SSD,为什么是RAID0?因为Elasticsearch本身就有冗余副本的存在,可以保证不丢失数据;
  • Master节点:一个Elasticsearch集群中只会有一个Master节点,Master主要负责管理集群变更、元数据的管理,该节点不需要太好的配置;
  • 协调节点:接受客户端的请求,并将请求路由到数据节点,然后将数据节点返回的内容进行处理,比如合并,排序等等,所以此节点对CPU、内存的要求是比较高的。

为了更加清晰,我给大家准备了一个表格:

节点类型CPU内存磁盘
数据节点高配置高配置高配置
Master节点低配置低配置低配置
协调节点高配置高配置低配置

我们在做数据查询的时候,协调节点会把请求路由给多个数据节点,多个数据节点再把数据响应给协调节点,协调节点再对数据进行加工处理,返回给客户端,需要做多次数据搬运,而且数据可能都不小,所以低延迟的网络也是必需的。

节点的单一职责

编码的时候,为了代码的扩展性、可维护性,我们需要满足“单一职责”,在分配节点的时候,为了Elasticsearch的性能,也需要满足“单一职责”,即:一个节点只做一件事情。

想想也是,Master节点作为集群的老大,相当于公司管理,数据节点是大头兵,如果Matser节点既要做管理的事情,又要做大头兵的事情,那会出现什么局面?

所以在条件允许的情况下,一个节点只做一件事情。

分片数(每个分片的大小控制在30-50G,3-5个分片可以满足大部分场景)

每个分片的大小控制在30-50G,Elasticsearch是严重依赖PageCache的,最好保证分片中的数据有1/3都在PageCache中。

如果你不想计算到底需要多少个分片,可以无脑配置3-5个分片,这满足大部分场景,毕竟一般的公司,你申请Elasticsearch集群,没有特殊的说明,运维小伙伴也是直接给你一个默认配置下的Elasticsearch集群,也不会特意问你数据的规模,如果你查询一下,会发现就是3-5个分片。

副本数(一个副本就够)

一个副本就够了,如果是数据迁移,为了追求迁移的速度,甚至可以把副本关闭了,等数据迁移完毕,再开启副本。

OS配置

禁用/少用swap

OS在内存不够用的时候,会将部分数据交换到swap空间(磁盘)上,但是磁盘的速度哪比得上内存的速度,所以会导致性能直线下降,所以应该关闭swap。

如果完全禁用swap,当内存不够用,OS可能会kill进程,所以为了可用性,也有一些人认为不要完全禁用swap,可以将swap设置成一个很小的数值,这样当性能直线下降,开发、运维都会有感知,可以给开发、运维处理的时间。

文件描述符设置为65535或更大

关闭atime

每次读取文件,Linux都会更新atime,没有实际用处,可以关闭。

设置最少的线程数量

Elasticsearch运行时会创建多种线程池来执行各种各样的操作,所以必须保证Elasticsearch可以创建足够的线程,而这个数量最少为4096。

减少TCP重传次数

Elasticsearch集群各个节点间的通信是使用TCP的,但是在丢包的情况下,Linux最多重传15次,而这15次重传会耗时900秒以上。这意味着系统发现网络分区故障需要非常长的时间,所以可以适当降低TCP重传次数。

JVM配置

最小堆内存和最大堆内存必须一样

如果最小堆内存、最大堆内存不一样,在运行的过程中,会频繁的进行伸缩。

最大堆内存不要超过服务器内存的一半

Elasticsearch是严重依赖PageCache的,最好保证分片中的数据有1/3都在PageCache中,所以最大堆内存不要超过服务器内存的一半,剩下的给OS使用。

最大堆内存不要超过32G(为了保险,可以设置30G)

最大堆内存一旦超过32G,JVM就会禁用指针压缩技术,这个时候,可能需要40-50G的内存才可以达到原先32G的效果,所以最大堆内存不要超过32G。32G是一个估算值,有些时候,可能不到32G就已经禁用了指针压缩技术,所以为了保险,最大堆内存可以设置30G。

垃圾收集器选用G1

对于大内存来说,G1比CMS给力,所以可以采用G1垃圾收集器,还需要调整两个参数,如果G1清理失败了,会转为单线程垃圾收集,这就太恐怖了,而G1默认的InitiatingHeapOccupancyPercent设置太乐观了,可能导致清理失败,所以需要适当降低InitiatingHeapOccupancyPercent。

-XX:G1HeapRegionSize=16m
-XX:InitiatingHeapOccupancyPercent=30
复制代码

应用配置

调整刷写频率

将文档写入Elasticsearch,会先写到buffer中,然后定时将buffer中的数据刷写到segment中,默认是1秒,可以适当调高此配置,当然buffer写满了,也会刷写到segment,但是大部分场景下,都是满足了时间的条件才触写刷新的。

配置项如下:

index.refresh_interval //默认是1秒,可以适当调高此配置
indices.memory.index_buffer_size //既可以配置字节数,又可以配置比例,这个参数是节点内所有分片共享的
复制代码

写translog改为异步形式

translog是用来保证数据不丢失的,类似于MySQL的binlog,默认写translog是同步的,可以改为异步的形式。

配置项如下:

index.translog.durability: async //默认是request
index.translog.sync_interval: 60s
复制代码

使用

尽可能使用系统自动生成的Id

如果不使用系统自动生成的Id,Elasticsearch会检查给定的Id是否重复,从而产生IO,如果可以的话,尽可能使用系统自动生成的Id。

批量写入

经验值是一次性写入5000到10000条数据。

以前我一直觉得批量写入几乎只有在数据迁移的时候才可能实现,平时几乎都是单条写入的,其实如果业务允许,可以先将请求用MQ中转下,Consumer消费MQ数据,将数据放入阻塞队列,另外一个线程用Google Guava提供的方法批量从阻塞队列中获取数据,最终批量写入Elasticsearch。

示例代码如下:

当然这样就增加代码的复杂度了,还要处理各种的异常场景,我这里仅仅是突然想到一个方法,和大家分享下。

mapping

字段越少越好,合适的数据类型

使用Keyword类型

对于等值查询而言,keyword比数值类型性能更好,所以如果不需要范围查询,可以使用Keyword类型。 不需要分词的文本,最好使用keyword,不然既影响写入性能,又占用空间。

如果不需要被索引,设置index为no

有不需要进行搜索的字段,可以设置其不需要索引,不然既影响写入性能,又占用空间。

如果不需要聚合、排序,设置doc_values为false

Doc values是基于列式存储的结构,聚合、排序非常高效,默认开启,占用空间。

扁平化(尽可能避免nested、parent-child)

尽可能避免nested、parent-child,不然既影响写入性能,又影响查询性能。

如果一个字段不需要算分,可以关闭Norms

如果当前字段不需要计算评分,设置false可以节省大量的磁盘空间,有助于提升性能。

不要使用Dynamic Mapping

如果使用Dynamic Mapping,那默认情况下,所有字段都是需要被索引的,而且都会创建doc_values,这肯定不是我们希望的,所以不要使用Dynamic Mapping,要自己严格定义mapping。

不要对text类型的字段进行排序

预索引

商品价格区间的搜索,比如可以查看价格100-200的商品,200-500的商品,500-1000的商品,那索引中必然含有price字段,我们可以通过范围查询搜索出对应的商品,但是范围查询的性能必然没有等值查询好,那我们可以在索引中再加一个字段:price_type(当price为100-200,price_type=1,当price为200-500,price_type=2,以此类推),这样我们就可以使用等值查询了。

查询某个月的数据,那索引中必然含有time字段,我们可以通过范围查询搜索出对应的数据,如果我们加一个month字段(yyyyMM),就可以采用等值查询了。

使用索引模板,对数据进行分片

相当于MySQL的分库分表,但是更加方便,只要定义一个模板,推送的数据满足相应的条件,就可以自动将索引创建出来。

避免深度分页,使用scroll和search_after分页

HBase和Elasticsearch搭配更香

Elasticsearch严重依赖PageCache,最好不要把太多字段放入Elasticsearch,会占用大量PageCache,查询会走到硬盘,严重影响查询性能,可以把核心字段、条件字段放Elasticsearch,其余数据放到HBase,通过_id去HBase查询更为明细的数据,如果HBase不可用,再查询MySQL,提高可用性。

使用Routing

默认情况: 插入数据是根据_id进行路由,选择某个分片:

  • 优点:使用简单,每个分片的数据量比较均匀;
  • 缺点:查询会扫描所有分片,开销比较大,性能取决于最慢的分片。

使用routing: 插入数据是根据给定的routing进行路由,写入到某个分片,查询的时候,也可以指定查询某个分片。

  • 优点:性能更好;
  • 缺点:使用比较复杂,需要自己控制写入的分片和查询的分片。

以上就是常用的Elasticsearch调优技巧,当然Elasticsearch的调优技巧远不止这些,比如比较高端的_sourse、store设置等等。

大家有没有发现,其中好多调优技巧,都是通用的,比如合适的数据类型,字段越少越好,预索引,比如增加文件描述符数量、关闭atime等等。

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

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

相关文章

[HDF5]如何使用CMake一起编译自己的代码和HDF5库

以一个实际项目来举例 目录 一.目录结构 二.CMakeLists.txt内容 三.执行CMakeLists命令 一.目录结构 1.build放CMake执行后生成的所有的内容,包括最后的工程或可执行文件等; 2.include放工程的头文件,以及HDF5的头文件,可以直接把HDF5中…

顶象业务安全情报——企业一眼“看透”黑灰产

不可否认,随着互联网的发展,黑灰产们也变得越来越“聪明”。它们不仅熟悉业务流程以及防护逻辑,并且能够熟练运用自动化、智能化的新兴技术实施攻击或诈骗行为,且极难识别。对购物、金融、社交、出行、教育、游戏等行业造成极大业…

3 个月前被裁员了,心情跌落谷底,直到我看到了这本神书…

3个月前的某一天,正在愉快的打工,突然被喊去谈话,然后就被辞退了。。 加入了找工作的大军 然而,因为疫情,因为大专学历的我,找工作比以往都艰难了许多 很多,纯粹就是因为学历,都不…

你想知道刷题的秘密吗?一篇博客让你明白什么是OJ题,如何刷OJ题,并深入浅出的带你刷遍顺序表的OJ题(小白必看)

目录 0.前言 1.什么是OJ 1.1 OJ简述 1.2 OJ的分类(尤其接口型OJ,带你剖析得明明白白) 1.3 接口型OJ的输入型参数 2. 剑指 Offer 56 - I. 数组中数字出现的次数 3. 88. 合并两个有序数组 4. 27.移除元素 5. 26. 删除有序数组中的重复…

Linux系统配置JDK环境变量

1、下载 1.1、Oracle官方下载地址:https://www.oracle.com/cn/java/technologies/downloads/#java8 1.2、同意协议,并点击Download 1.3、账号密码登录,没有可以创建一个 1.4、登录成功后就直接下载了 2、配置 2.1、下载好的压缩包上传到Lin…

FreeRTOS第一个任务的创建和调度详解(SVC异常)

在上一篇文章中,我详细分析了FreeRTOS中上下文切换:基于Cortex-M的RTOS上下文切换详解及FreeRTOS实例 但是第一个任务没有上下文,它是怎么运行的呢? 1 创建任务 如果我们没有创建任务的话,系统也有一个空闲任务用来…

【 java 集合】使用迭代器 Iterator 遍历集合

📋 个人简介 💖 作者简介:大家好,我是阿牛,全栈领域优质创作者。😜📝 个人主页:馆主阿牛🔥🎉 支持我:点赞👍收藏⭐️留言&#x1f4d…

空气源热泵设备远程监控的优点

空气源热泵热水器是一种节能、环保、安全的新能源产品,也是家庭采暖、生活热水及空调制冷等方面的最佳选择。 在使用时,只需一次少量的电能就能实现连续制热和制冷,其制热效率是燃气热水器、电热水瓶和燃油热车等供热设备的数倍,因…

亿联会议系统操作使用全教程

环境: 终端VC800 亿联会议pc.v4.2.11 教程: 一、下载安装亿联会议PC/手机APP 官网下载 1.以下教程为Windows版演示 2.安装亿联会议软件(具体操作按软件提示步骤进行) 3.注册账号 3.1点击免费注册按钮,自动跳转至…

SCI投稿经验分享:成功发表一篇中科院2区智能物联网类SCI真的不难

我是如何用三个月成功发表一篇TOP 【本期推荐】本期小编分享点不一样的内容。关注小编三个月以上的铁粉可能会留意到七月份本协会新增了一本计算机智能物联网类1区TOP刊,该刊一经推出就受到了广大作者的纷纷投稿。奈何期刊合作期刊编辑严格控制版面,所以…

配电网络扩展规划:考虑使用概率性能源生产和消费概况的决策(Matlab代码实现)

💥💥💥💞💞💞欢迎来到本博客❤️❤️❤️💥💥💥 🎉作者研究:🏅🏅🏅主要研究方向是电力系统和智能算法、机器学…

Java开发学习(三十一)----Maven属性与版本管理

一、属性 1.1 问题分析 如下图所示 你会发现,如果现在想更新Spring的版本,你会发现依然需要更新多个jar包的版本,这样的话还是有可能出现漏改导致程序出问题,而且改起来也是比较麻烦。 问题清楚后,我们需要解决的话…

SpringBoot 打 jar包和打war 包配置

文章目录1. 前言2. SpringBoot 打 jar 包3. SpringBoot 打 war 包4.小结1. 前言 目前我们熟知的SpringBoot 打包方式,一共分为两种,一种是打jar 包(内置tomcat 方式,yml 里的配置参数生效包括端口,和servlet 的contex…

EndNote参考文献导入

简介 本文介绍如何在Word作文过程中借助EndNote管理参考文献,关于如何将参考文献导入到EndNote中这里不做说明,假定需要的文献均已经导入。 具体步骤 为什么需要文献管理工具来生成参考文献呢?最核心的原因就是自动控制的,文献的…

JAVA SCRIPT设计模式--结构型--设计模式之ADAPTER适配器(6)

JAVA SCRIPT设计模式是本人根据GOF的设计模式写的博客记录。使用JAVA SCRIPT语言来实现主体功能,所以不可能像C,JAVA等面向对象语言一样严谨,大部分程序都附上了JAVA SCRIPT代码,代码只是实现了设计模式的主体功能,不代…

代码详细教程+文档+PPT+源码等]SSM框架网上书城全套含微信支付|电商购物计算机专业毕业论文java毕业设计网站

💖💖更多项目资源,最下方联系我们✨✨✨✨✨✨ 目录 Java项目介绍 资料获取 Java项目介绍 计算机毕业设计java毕设SSM框架实现的网上书城-升级版_哔哩哔哩_bilibili项目资料网址: http://itzygogogo.com软件下载地址:http://itzygogogo.co…

Spring的IOC是啥?有什么好处?

单一职责原则 依赖倒转原则 最小知识原则 接口隔离原则 合成/聚合复用原则 里氏代换原则,任何基类可以出现的地方,子类一定可以出现 依赖倒置 假设我们设计一辆汽车:先设计轮子,然后根据轮子大小设计底盘,接着根…

封装基板出厂100欧姆,测试85欧姆?

作者:一博科技高速先生成员 陈亮 封装基板(Package Substrate)是半导体芯片的载体。为芯片提供连接、保护、支撑、散热、组装等功效,以实现多引脚化,缩小产品体积、改善电性能及散热性、多芯片模块化等。我们生活中看…

构造HTTP请求 以及 关于HTTPS的加密

1.构造HTTP请求 构造HTTP请求有很多种方式.使用html,使用jQuery,使用socket…等等. 这里我们介绍两种. 使用html使用jQuery 1.1.使用html构造HTTP请求 使用html构造HTTP请求,要使用到 form 标签. 这里form标签中的属性有两个. action :填写数据要返送到的地址.(URL)meth…

【云原生 | Kubernetes 实战】08、零故障升级之 Pod 健康探测——启动、存活、就绪探测

目录 一、Pod容器健康探测 1.1 为什么要对容器做探测? 默认的健康检查 探测类型 检查机制 探测结果 Pod 探针相关的属性 两种探针区别 1.2 启动探测 startupprobe exec 模式 tcpsocket 模式 httpget 模式 1.3 存活性探测 livenessProbe 通过 exec …