Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >ES03# Elasticsearch性能调优点梳理

ES03# Elasticsearch性能调优点梳理

作者头像
瓜农老梁
发布于 2022-04-28 00:05:36
发布于 2022-04-28 00:05:36
66800
代码可运行
举报
文章被收录于专栏:瓜农老梁瓜农老梁
运行总次数:0
代码可运行

引言

本文主要梳理了Elasticsearch集群常见优化点,就一些主要项能够在实践中指导使用,本文主要内容有:

  • JVM参数调优
  • 系统参数调优
  • 写性能调优点
  • 读性能调优点
  • 分片均衡优化案例

一、JVM参数调优

1.参数设置

修改jvm参数可以通过config/jvm.options.d/jvm.options调整,不建议直接修改config/jvm.options,通过-Xms和-Xmx设置。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
-Xms15g
-Xmx15g

2.参数大小

设置JVM堆内存配置机器内存一半,JVM内存配置不超过32G

备注:参见官方文档

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
https://www.elastic.co/guide/en/elasticsearch/reference/current/advanced-configuration.html#set-jvm-options

二、系统参数调优

1.文件描述符限制

1.1 设置最大文件数

设置用户的打开的最多文件数,将account换成实际用户。

命令:vim /etc/security/limits.conf

内容:如下修改

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# End of file
account soft nofile 65535
account hard nofile 65535
* soft nofile 65535
* hard nofile 65535
1.2 查看文件描述符

输入:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
GET _nodes/stats/process?filter_path=**.max_file_descriptors

输出:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{
  "nodes" : {
    "UsN0qcWUTC68THnK0N9wLA" : {
      "process" : {
        "max_file_descriptors" : 1048576
      }
    },
    //...
}

备注:参见官方文档

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
https://www.elastic.co/guide/en/elasticsearch/reference/current/setting-system-settings.html

https://www.elastic.co/guide/en/elasticsearch/reference/current/file-descriptors.html

2.关闭系统交换区

2.1 执行禁用命令

命令:sudo swapoff -a

2.2 设置swappiness

将swappiness设置为1,通常情况下不交换,只在紧急情况允许少量交换。

  • swappiness=0 仅在内存不足的情况下,当剩余空闲内存低于vm.min_free_kbytes limit时,使用交换空间
  • swappiness=1 内核版本3.5及以上、Red Hat内核版本2.6.32-303及以上,进行最少量的交换,而不禁用交换

修改vim /etc/sysctl.conf,添加如下内容,添加后执行sysctl -p让其生效。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
vm.swappiness=1
2.3 锁定地址空间

为了提高数据访问和操作效率,将进程使用的地址空间锁定在物理内存中,防止交换到swap空间。

1.开启内存锁

修改config/elasticsearch.yml中的bootstrap.memory_lock参数

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
bootstrap.memory_lock: true

2.检查锁是否开启

输入:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
GET _nodes?filter_path=**.mlockall

输出:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{
  "nodes" : {
    "m8c-TdL1RbK1M7goGTCTUQ" : {
      "process" : {
        "mlockall" : true
      }
    },
    "-3lP6pM8SHq1-ulpGQybWQ" : {
      "process" : {
        "mlockall" : true
      }
    },
    "6HCT0tLPQ7uKoJPnYPlO1A" : {
      "process" : {
        "mlockall" : true
      }
    }
  }
}

3.给ES用户授权

修改/etc/security/limits.conf,添加如下内容。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# allow user 'elasticsearch' mlockall
elasticsearch soft memlock unlimited
elasticsearch hard memlock unlimited

备注:参见官方文档

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
https://www.elastic.co/guide/en/elasticsearch/reference/current/setup-configuration-memory.html

3.虚拟内存限制

系统参数max_map_count限制一个进程拥有的虚拟内存数量,默认值为65536。

修改vim /etc/sysctl.conf,添加如下内容,添加后执行sysctl -p让其生效。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
vm.max_map_count=262144

备注:参见官方文档

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
https://www.elastic.co/guide/en/elasticsearch/reference/current/vm-max-map-count.html

4.进程数量限制

操作系统对每个用户创建进程的限制, 官方建议为Elasticsearch user至少设置4096,可以调整的更大一些

命令:ulimit -u 655350

修改 vim /etc/security/limits.conf

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
* soft nproc 655350

5.系统优化其他点

  • 文件系统缓存会缓存I/O操作,确保至少物理内存的一半
  • 使用好的硬件,例如:SSD硬盘
  • 单节点数据建议控制在2TB,最大不超过5TB
  • 搜索性能要求搞得尽可能SSD,按照1:10配置内存磁盘

备注:参见官方文档

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
https://www.elastic.co/guide/en/elasticsearch/reference/current/max-number-of-threads.html

三、写性能调优点

1.多线程批量请求

批量写入: 具体一次写入多少document,需要测试给出。例如:建一个索引,单节点单分片,不断调整写入数量测试100,200,800,1000...等

多线程: 需要关注服务端返回的TOO_MANY_REQUESTS (429) 异常

2.增加refresh_interval间隔

写入过程:数据写入时,先保存在Index buffer,满足refresh_interval为间隔时长后,定期清空buffer,生成segment供检索。

增加refresh_interval时长,比如:30秒,可以避免生成过多的segment。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{
  "index": {
    "refresh_interval": "30s",
}

3.增加indexing buffer缓存区

Indexing缓存区用于存储新的document,当缓存区满了后会写入segment落盘,index_buffer_size默认为整个堆内存的10%,min_index_buffer_size指定缓存区允许的最小值,默认为48mb。

修改elasticsearch.yml添加参数

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
indices.memory.index_buffer_size: 30%
indices.memory.min_index_buffer_size: 96mb

4.设置副数量为零

在初始化第一次加载的时候设置副本为0,加载完成后再调整副本数量。如果日志类场景可以考虑将副本设置为0,提升性能的同时会牺牲

可靠性。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{
  "index": {
    "number_of_replicas": "0"
  }
}

5.使用文档自增ID

如果自己设置文档ID,ElasticSearch会校验在分片中是否重复,避免不必要的校验使用自增ID。

6.分区均衡

设置合理的分片数确保均匀分布到所有数据节点上,通过参数index.routing.allocation.total_share_per_node限定每个索引在每个节点上可分配的主分片数,例如等于平均数或者略大于平均数。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{
  "index": {
    "routing": {
      "allocation": {
        "total_shards_per_node": "2"
      }
    }
  }
}

7.Translog配置

降低写磁盘的频率

  • Index.translog.durability:事务日志,默认request每次请求都会落盘,修改为async,异步写入
  • index.translog.sync_interval: 设置为60s,每分钟执行一次
  • Index.translog.flush_threshod_size: 默认512M,可以适当调大一些,当translog超过该值触发flush

8.Bulk/线程池/队列设置

客户端设置

  • 单个bulk请求体不要太大,官方建议5~15M
  • 单个bulk请求超时足够长,建议60s以上
  • 写入段尽量将数据轮训到不同的节点,使用负载均衡

服务端设置

  • 服务端线程池设置为核数+1
  • 队列大小适当增加,也需要注意过大会成为 GC 的负担

elasticsearch.yml配置

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
## Threadpool Settings ##

# Search pool
threadpool.search.type: fixed
threadpool.search.size: 20
threadpool.search.queue_size: 100

# Bulk pool
threadpool.bulk.type: fixed
threadpool.bulk.size: 60
threadpool.bulk.queue_size: 300

# Index pool
threadpool.index.type: fixed
threadpool.index.size: 20
threadpool.index.queue_size: 100

# Indices settings
indices.memory.index_buffer_size: 30%
indices.memory.min_index_buffer_size: 96mb

# Cache Sizes
indices.fielddata.cache.size: 15%
indices.fielddata.cache.expire: 6h
indices.cache.filter.size: 15%
indices.cache.filter.expire: 6h

# Indexing Settings for Writes
index.refresh_interval: 30s
index.translog.flush_threshold_ops: 50000

9.额外优化项

9.1 不检索的字段

只聚合不搜索的字段,index设置为false。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{
  "mappings": {
    "properties": {
      "foo": {
        "type": "integer",
        "index": false
      }
    }
  }
}

9.2 不适用dynamic mapping

对字符串不要使用默认的dynamic mapping,字段数量过多,对性能产生比较大的影响

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{
  "mappings": {
    "dynamic": false,
    "properties": {}
  }
}

9.3 关闭_source

关闭_source,减少IO操作

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
"mappings": {  
    "_source": {  
        "enabled": false  
    }
} 

10.索引示例

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{
  "index": {
    "lifecycle": {
      "name": "xxx_log_store"
    },
    "routing": {
      "allocation": {
        "total_shards_per_node": "2"
      }
    },
    "refresh_interval": "30s",
    "number_of_shards": "30",
    "translog": {
      "sync_interval": "60s",
      "durability": "async"
    },
    "number_of_replicas": "0",
    "mappings": {
      "dynamic": false,
      "properties": {}
    }
  }
}

备注:参见官方文档

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Indexing buffer setting
https://www.elastic.co/guide/en/elasticsearch/reference/current/indexing-buffer.html
Tune for indexing speed
https://www.elastic.co/guide/en/elasticsearch/reference/current/tune-for-indexing-speed.html
Tune for disk usage
https://www.elastic.co/guide/en/elasticsearch/reference/current/tune-for-disk-usage.html

四、读性能调优点

1.文档建模

  • 避免嵌套类型的数据,查询速度会慢几倍
  • 避免父子类型的数据,查询速度慢几百倍

2.禁用脚本

尽量将数据先行计算,然后保存到ElasticSearch中,避免使用查询脚本Script,可以使用ingest Pipeline并入需要的字段

3.禁用通配符

禁止使用*开头的通配符查询,性能会很差

4.注意分片数量

一个查询访问每一个分片,分片过多,开销增加

5.基于时间的索引

在索引的名字中增加时间信息,按照每天/每周/每月的方式进行划分,将只读的索引进行force merge减少segment的数量

6.使用Filter Context

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

备注:参见官方文档

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
https://www.elastic.co/guide/en/elasticsearch/reference/current/tune-for-search-speed.html

五、分片均衡优化案例

下面案例中ES集群中有15个节点,索引只有30个主分片,没有设置副本。通过设置total_shards_per_node(每个节点中最多分片数)不同的值,观察主分片在各个节点的均衡情况。

1.没有设置total_shards_per_node

备注:上图为没有设置total_shards_per_node参数,30个分片被分布在5个节点中,节点最多分片8,最少分片2,分片不均衡。

2.设置total_shards_per_node=3

备注:当设置total_shards_per_node=3时,30个分片被分布在14个节点中,节点最多分片数3,最少分片数2,分片比较均衡。

3.设置total_shards_per_node=2

备注:当设置total_shards_per_node=2时,30个分片被分布在15个节点中,每个节点分片数均为2,分片均衡。

4.性能情况

备注:当分片分配均衡时,写入性能也非常高,下图为28.5万/秒。当严重不均衡时,性能不足其一半。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-04-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 瓜农老梁 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
NoSQL初探之人人都爱Redis:(4)Redis主从复制架构初步探索
  通过前面几篇的介绍中,我们都是在单机上使用Redis进行相关的实践操作,从本篇起,我们将初步探索一下Redis的集群,而集群中最经典的架构便是主从复制架构。那么,我们首先来了解一下神马是主从复制架构?
Edison Zhou
2018/08/20
5950
NoSQL初探之人人都爱Redis:(4)Redis主从复制架构初步探索
Redis入门-贰
在上次的Redis的文章中,大致的讲了下Redis是什么,为什么使用Redis,Redis为什么适用于做缓存以及对它的5种数据类型做的简单介绍。
用户5521279
2019/10/31
3850
Redis入门-贰
Redis缓存服务搭建及实现数据读写
发现博客园中好多大牛在介绍自己的开源项目是很少用到缓存,比如Memcached、Redis、mongodb等,今天得空抽时间把Redis缓存研究了一下,写下来总结一下,跟大家一起分享 一下。由于小弟水平有限又是第一次接触Redis,有些的不对的地方欢迎指出纠正。
写代码的猿
2019/04/11
6790
Redis缓存服务搭建及实现数据读写
asp.net core 上使用redis探索(3)--redis示例demo
由于是基于.net-core平台,所以,我们最好是基于IDistributedCache接口来实现。ASP.NET-CORE下的官方redis客户端实现是基于StackExchange的。但是官方提供的IDistributeCache接口中的方法只是增删改查,我们可以继续拓展,增加订阅/发布,消息队列,当然这些方法必须是基于底层的StackExchange相对应的方法来做的。 如果我们要实现自己的Redis客户端,同时不使用底层的StackExchange驱动,可以派生一个继承自IDistributedCache的接口,定义自己需要的方法,例如:
Ryan_OVO
2023/10/19
3080
asp.net性能优化之使用Redis缓存(入门)
1.1对于大量的数据读取,为了缓解数据库的压力将一些不经常变化的而又读取频繁的数据存入redis缓存
张哥编程
2024/12/21
860
分布式中使用Redis实现Session共享(一)
用户1168362
2018/01/05
2.3K0
分布式中使用Redis实现Session共享(一)
windows 下对Redis的安装和部署以及连接客户端
Redis的安装和部署 一、Redis的下载地址 Redis官方并没有提供Redis的windows安装包,但在github上, 有相关的下载地址,如下: https://github.com/ServiceStack/redis-windows/tree/master/downloads 也可以到百度网盘下载,下载地址:http://pan.baidu.com/s/1gf2nuin,我下载的版本是redis-64.3.0.503.zip(64位的win系统,redis 3.0版本)。  —–
学到老
2018/03/19
3K0
windows 下对Redis的安装和部署以及连接客户端
Redis的安装以及使用入门
Redis的安装以及使用入门 Redis是一个用的比较广泛的Key/Value的内存数据库,新浪微博、 Github、StackOverflow?等大型应用中都用其作为缓存,Redis的官网为htt
bering
2019/12/02
8050
windows 下对redis安装和部署以及连接客户端与操作
Redis官方并没有提供Redis的windows安装包,但在github上, 有相关的下载地址,如下: https://github.com/ServiceStack/redis-windows/tree/master/downloads
学到老
2019/02/14
1.1K0
C# 通过ServiceStack 操作Redis——String类型的使用及示例
我这里就用别人已经封装好的Reids操作类来和大家一起参考了下,看看怎么使用ServiceStack.Redis 操作Redis数据
明志德道
2023/10/21
3670
C# 通过ServiceStack 操作Redis——String类型的使用及示例
【架构师(第四十一篇)】 服务端开发之安装并连接 Redis数据库
找到 requirepass foobared,复制到新的一行,将前面的 # 删除,并清除空格,不然会造成密码设置不成功。
一尾流莺
2022/12/10
3180
【架构师(第四十一篇)】 服务端开发之安装并连接 Redis数据库
Redis——Windows安装
本篇只谈安装,后续会深入讲解Redis,比如它的内存管理,快照,订阅等待。针对不同的用户,Redis有Windows和Linux两种环境安装, 官网上下的是Statble版是Linux,大家一定要注意。由于本人做本地端,所以以下谈的是Windows安装。
全栈程序员站长
2022/07/22
7380
Redis——Windows安装
windows下配置redis
https://github.com/MicrosoftArchive/redis/releases
I Teach You 我教你
2023/07/18
2060
windows下配置redis
在Window系统中使用Redis缓存策略
Redis是一个用的比较广泛的Key/Value的内存数据库,新浪微博、Github、StackOverflow 等大型应用中都用其作为缓存,Redis的官网为http://redis.io/。
用户1055830
2019/05/25
8340
高性能开发(1) Redis缓存主从配置详解
高性能开发(1) Redis缓存主从配置详解
Java架构师必看
2021/06/11
3410
高性能开发(1) Redis缓存主从配置详解
redis在window环境下的安装教程
进入这个网址,下载window版本https://github.com/microsoftarchive/redis/releases
GeekLiHua
2025/01/21
2050
redis在window环境下的安装教程
redis(一)数据类型与应用场景
Redis 是一个由Salvatore Sanfilippo写的key-value存储系统。
杨小杰
2020/02/18
4830
Redis从入门到精通(一)Window下如何安装配置Redis
最近项目中需要使用Redis,刚好这两天有时间,便总结记录一下Redis的安装,以及如何在.NET中使用Redis。
架构师精进
2020/05/24
1K0
Redis从入门到精通(二)C#中使用redis及封装Redis工具类
上一篇讲述了安装redis《Redis总结(一)Redis安装》,同时也大致介绍了redis的优势和应用场景。本篇着重讲解.NET中如何使用redis和C#。
架构师精进
2020/05/24
10.3K0
win10下安装redis 服务
下载地址:https://github.com/MSOpenTech/redis/releases
用户1214487
2018/09/27
2.3K0
win10下安装redis 服务
推荐阅读
相关推荐
NoSQL初探之人人都爱Redis:(4)Redis主从复制架构初步探索
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验