[译]9条关于高性能ElasticSearch的配置建议

原文链接:https://www.loggly.com/blog/nine-tips-configuring-elasticsearch-for-high-performance/

Loggy使用ES作为其很多核心功能的搜索引擎. 如Jon Gifford在最近的文章ElasticSearch vs Solr中所述, 日志管理系统对搜索引擎有特别需求, 具体如下:

  • 对于大规模的数据索引具有可靠的性能及准实时的表现--在我们场景中,每秒有接近100000条日志记录

  • 同时对于大量的搜索处理能维护较高的性能和效率.

在构建我们的Gen2日志管理服务时, 我们希望能设置最优的参数以最大程序的发挥ElasticSearch的索引和搜索性能. 不幸的时, 很难在一个地方收集到完善的ElasticSearch设置文档. 这篇文章总结了我们学习到的一些知识, 同时可以作为你部署和配置自己的ES应用的一个参考列表.

本文档最新更新于09/2016

1: 提前规划indices, shards和cluster state的增长趋势

在ES中创建indices和shards非常简单, 但需要记住的是每个indiex和shard都有相应的资源开销.如果有太多的indices和shards, 单单是对他们管理上的开销就可能大大降低你的ES集群性能, 甚至极端场景下使服务不可用.

我们发现对管理系统开销影响最大的因素是cluster state, 包含了集群中每个索引的mappings信息.曾经某段时间, 我们单个集群的cluster state信息占用了900MB的空间. 集群虽然还存活着, 但已处于不可用状态.

下面我们通过一些数据来感受下其中都发生了事情...

假设你有一个索引, 其mappings大小为50K(在我们的集群中, 大约有700个字段). 如果你每小时生成一个索引, 那么一天下来将会有24 x 50K的cluster state数据增量, 大约是1.2MB. 如果你的系统中保存了1年的数据, cluster state信息将达到438MB(8760个indices, 53800个shards). 如果每天一个索引的话, cluster state信息会减少到18.25MB(365个indices, 1825个shards). 可以看到,每小时一个索引会把你置于一个完全不同的处境.

如果你的系统有实时索引数据的需求, 最好先为之做些规划, 并清楚的意识到你的系统中会存储多少cluster state信息以及将包含多少indices和shards. 在部署到生产环境之前, 应该先多做些测试和演练, 避免在凌晨3点因集群不可用而被叫起.

在集群配置方面, 为避免把自己置于险境, 你需要对系统中能容纳的indices和shards数量有全面的掌控.

2: 配置之前,先认识集群拓扑结构

在Loggly, 我们把ES的master节点和data节点分开部署.现在我们要说的不是这些细节, 而是强调在你做出正常的配置之前, 先选择正常的拓扑.

另外, 我们对于索引请求和查询请求也使用了不同的客户端程序. 这样不但可以为data节点减轻负载, 更重要的是我们的执行队列可以先提交给本地客户端, 再由其与集群的其他节点交互.

设置节点为master或data节点由以下两个参数的值来决定:

Master node: node.master:true node.data:false
Data node: node.master:false node.data:true
Client node: node.master:false node.data:false

上面的部分比较简单, 下面开始介绍一些需要着重注意的高级属性. 对于大部分系统来说, ES的默认配置已经足够, 但如果你的使用场景正如我们经常看到的日志类系统, 请一定不要错过下面的部分.

3: 设置mlockall是提升性能的最有效手段

Linux把它的物理内存划分为很多块, 称为. 而Swapping则是把内存中的一页复制到磁盘上预定义空间的过程, 以释放更多的内存页, 而磁盘上的这部分空间称为交换区. 物理内存和交换区空间的总和称为虚拟内存空间.

交换区并不总是有利的. 因为下内存相比, 磁盘总是慢太多. 通常内存的存储速度在纳秒级, 而磁盘却要毫秒级别. 所以磁盘的访问速度比直接访问内存要慢上万倍. 使用的交换空间越多, 系统会越多, 所以要避免交换区的使用.

mlockall参数允许设置ES节点不换出内存页(只有Linux/Unix系统才有此设置). 在你的yaml文件中, 可通过如下方式设置:

bootstrap.mlockall:true

在5.x版本中, 该参数被bootstrap.memory_lock:true所代替.

默认mlockall的值为false, 意味着ES节点的内存被允许换出. 设置该属性值后, 需要重启ES节点才能生效. 可以通过如下访问进行验证设置是否成功:

curl http://localhost:9200/_nodes/process?pretty

同时要注意, 如果设置了mlockall为true, 要确认通过-DXmx或ES_HEAP_SIZE给你的ES设置了足够的堆空间.

4: 通过discovery.zen控制ES的节点发现管理

Zen discovery是ES集群中节点发现连接的默认机制, 另外还有一些其他的发现机制, 如Azure, EC2和GCE. Zen discovery通过discovery.zen.*的一系列参数进行设置和控制.

在0.x和1.x版本中, 可以设置单播或多播方式, 并且多播是作为ES的默认方式使用的. 如果在这两个版本中想使用单播, 需要设置discovery.zen.ping.multicast.enable为false.

但自从ES 2.0以来, 单播是Zen discovery唯一可用的选择.

首先, 你需要通过discovery.zen.ping.unicast.hosts参数指定一组用于发现和连接节点的hosts. 为了简单, 可以为集群中的每个节点设置相同的值. 我们的集群中使用了所有master节点的地址.

discovery.zen.minimum_master_nodes参数用于控制最小的合理master节点数, 使得集群中其他节点可被发现和操作. 通常, 在多于2个节点的集群中建议该参数设置的值不小于2. 另外一种计算方式是(master节点数/2 + 1).

Data节点和master节点之前有两种检测方式:

  • master向所有其他节点发起ping请求, 以确认该节点是否存活

  • 其他的节点向master节点发现ping请求,以确认master是否存活,并决定是否需要开始新一轮的选举

节点检测过程由discovery.zen.fd.ping_timeout参数设置, 默认值为30s, 决定了一个发起ping请求的节点的响应等待时间. 如果你的集群带宽不足或网络拥堵, 则需要合理的重新调整该参数. 如果网络较差,该参数要相应的设置大一些, 值越大, 节点发现的失败的风险也就越低.

Loggly的discovery.zen参数设置如下:

discovery.zen.df.ping_timeout: 30s
discovery.zen.mininum_master_nodes: 2
discovery.zen.ping.unicast.hosts: ["esmaster01", "esmaster02", "esmaster03"]

就是说30s内需要有节点检测响应返回(通过discovery.zen.df.ping_timeout设置的).另外,其他节点至少要检测到2个master节点(我们总共有3个master节点), 第三个参数是说我们的单播主机分别为esmaster01, esmaster02和esmaster03.

5: 提防"DELETE_all"

ES的DELETE API允许你通过一个请求(使用通配符或_all)删除所有的索引数据, 意识到这一点非常重要.如下:

curl -XDELETE 'http://localhost:9200/*/'
curl -XDELETE 'http://localhost:9200/_all'

虽然这个功能很强大,却也极为危险,特别是在生产环境. 在我们所有的集群中, 我们都通过action.destructive_requires_name:true参数禁用了该删除功能.

这个参数由ES 1.0并入, 并替换掉了0.90版本中使用的action.disable_delete_all_indices参数.

6: 使用Doc Values

在ES2.0及以上版本中, Doc Values是默认使用的.而在较早的版本中则需要显示指定.Doc Values通过少量额外的索引和磁盘开销, 提供了比在normal字段上更高效的排序和聚合操作.本质上, Doc Values通过把ES转变为列式存储, 进而使得ES大量的分词特性比预想的更高效.

为了深入理解Doc Values带来的好处, 下面将把Doc Values与normal字段进行对比.

当在normal字段上进行排序或聚合操作时, 将导致大量的fielddata cache.因为当字段第一次被缓存时, ES需要为该字段每个可能的取值分配大量的堆空间, 并从每个文档中获取字段值数据. 因为这个过程可能需要从磁盘中读取数据, 因为将会十分耗时.一旦数据缓存完成, 以后再对该字段值的使用都会使用先前缓存的数据, 所以速度也会更快.但当有过多的字段被载入到缓存中时, 就会触发缓存淘汰机制, 一些字段将被汰出, 相应的再次使用被汰出的字段时, 就是又一次的耗时载入过程. 为了高效, 你可能想减少或降低缓存汰出, 这意味着你要减少或限制将被缓存的字段数量.

与之不同, Doc Values使用基于磁盘的数据结构, 并映射到进程的内存空间, 从而减少对堆空间的占用, 并具有与fielddata cache相匹敌的性能. 虽然在数据第一次从硬盘读取并载入时依然会有起始开销, 然而这一些都有操作系统的文件系统缓存进行处理, 所以只有你真正需要的数据才会被读入.

简而言之, Doc Values减少了堆空间使用(相应的降低了GC影响), 并通过文件系统缓存减少读取的数据, 从而提高了整体性能.

7: ES shard分配相关的参数设置

shard分配就是把shard分散到不同节点的过程,可以发生在初始化备份阶段, 副本分配阶段或者节点再平衡过程中.也就是说它发生在任何节点增加或移除的过程中.

参数cluster.routing.allocation.cluster_concurrent_rebalance决定了在shard再平衡过程中允许并发的shard数.合适的设置由你使用的硬件性能决定, 如集群节点使用的CPU核数, IO性能等.如果参数设置的不合理,将会对ES索引过程的性能带来一定的影响.

cluster.routing.allocation.cluster_concurrent_rebalance:2

ES默认设置的值为2, 也就是说在任何时候最多只允许同时移动2个shards的数据.设置一个不太高的合理数值总是值得的,虽然shard再平衡的并发数受到制约, 但却不会对索引数据造成影响.

另外一个值得一提的参数是cluster.routing.allocation.disk.threshold_enabled.如果这个参数设置为true, 则在shard分配过程中为shard预留空闲的磁盘空间, 相反如果设置为false,则分配到该节点上的shard数据的未来增加将受到限制--没有足够的空间.

当threshold_enabled设置为true, 有两个相应的指标可以配置:low 和 high.

  • low 定义了当磁盘使用量超过该指标后,ES将不再为该节点分配shard, 默认值为85%

  • high 定义了当磁盘使用量超过该指标后,将有shard从该节点中移出, 默认值为90%

这两个参数即可按已使用量的百分比定义(例如,80%是说使用了80%的磁盘,尚有20%空闲), 也可以按最小可用磁盘空间定义(例如,20GB是说该节点尚有20GB空闲空间).

如果你有大量的小shards, ES使用的默认值可能会有些保守. 例如你有1TB的存储空间,而每个shard的大小仅为10GB, 理论上该节点能容纳100个数据shards.如果采用上面的默认设置, 在ES认为节点饱和前, 你最多只能存储80个shards.

所以为了找出一个合理设置, 你需要仔细观察在shard生命周期中的容量变化, 同时为之预留一定的安全空间.在上面的例子中, 假如有5个数据shards, 则需要确认在任何时候都要有50GB的可用空间(不是空闲空间, 是5个shards将占用的总空间).对于1TB的设备, 如果不考虑安全空间, low的值可设置为95%. 然而乘以50%的安全系数, 则需要至少预留75GB的空闲空间, 相应的合理的low值应为92.5%.

8: 合理的恢复设置帮你提升节点重启速度

ES提供了几个属性用于提高集群恢复速度,缩短节点重启时间.合理的取值依赖于你的硬件能力(硬盘和网络速度通常会是瓶颈), 所以能给出的最好的建议就是尝试,尝试,再尝试.

  • 控制单个节点并发恢复数据的shard数:

    cluster.routing.allocation.node_concurrent_recoveries

    shard数据恢复是一个IO密集型操作, 因此需要根据实际情形设置参数.在ES 5.x版本中, 这个参数分拆成两个新的设置:

cluster.routing.allocation.node_concurrent_incoming_recoveries
cluster.routing.allocation.node_concurrent_outgoing_recoveries
  • 控制单个节点上初始的主shard并发数:

    cluster.routing.allocation.node_initial_primaries_recoveries
  • 控制一个shard恢复数据时并行打开的数据流个数:

    indices.recovery.concurrent_streams
  • 与数据流紧密相关的是可用的带宽限制:

    indices.recovery.max_bytes_per_sec

    实际使用的硬件配置直接决定了以上几个参数的最优值设置.使用SSD硬盘以及高速的(10G)以太网结构和使用机械硬盘以及1G的以太网结构将有巨大的差别.

只有在集群重启的时候,才会使用以上数据恢复相关的参数设置.

9: 合理的线程池设置避免数据丢失

为了提高节点内的线程管理, ES维护了多个线程池.

在Loggly, 我们在使用_bulk操作来处理索引请求时发现, 设置合适的threadpool.bulk.queue_size对避免_bulk重试以及由其可能引起的数据丢失至关重要.

threadpool.bulk.queue_size: 5000

上面的参数用于设置bulk的队列长度, 即当节点的每个shard在处理bulk请求时, 如果无可用线程时, 能为每个shard排队等待的请求数量.这个参数应该与你的bulk请求负载相匹配, 如果设置过小, 而bulk请求较多时, ES会返回一个RemoteTransportException.

如上所述, bulk请求涉及到的每个shard的数据都在这个队列里, 因此合理的设置是bulk的并发数乘以这些请求相关的shard数. 比如说: 单个bulk请求包含的数据分布在10个shards上, 即便只有一次bulk请求, 你也要有一个至少长度为10的队列设置.话说回来, 如果设置过大则会消耗更多的JVM堆空间(同时意味你正提交的数据量可能超出你实际能索引的能力), 然而却能减化你的客户端处理逻辑.

要么设置一个相对合适的较大的队列值, 要么在你的代码中合理的处理掉RemoteTransportException. 如果处理不当, 则会面临数据丢失的风险. 下面的异常模仿的是队列长度为10,而并发发起了超过10个bulk请求的场景:

RemoteTransportException[[<Bantam>][inet[/192.168.76.1:9300]][bulk/shard]]; nested: EsRejectedExecutionException[rejected execution (queue capacity 10) on org.elasticsearch.action.support.replication.TransportShardReplicationOperationAction$AsyncShardOperationAction$1@13fe9be];

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

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

相关文章

ABP vNext微服务架构详细教程——结束语

ABP vNext微服务架构详细教程——简介ABP vNext微服务架构详细教程——架构介绍ABP vNext微服务架构详细教程——身份管理服务ABP vNext微服务架构详细教程——基础服务层ABP vNext微服务架构详细教程——聚合服务ABP vNext微服务架构详细教程——身份认证服务ABP vNext微服务架…

创建 linux分区命令,Linux中创建分区

在很多情况下我们可能需要在使用Linux的时候创建新的分区来帮助我们更好的学习和工作&#xff0c;接下来我就详细的介绍一下如何利用fdisk这条命令进行硬盘分区。Linux磁盘分区和windows存在区别&#xff0c;Linux分区分为三类 主分区 扩展分区 和逻辑分区。然而它们三个关系有…

Android studio之Error:(23, 17) Failed to resolve: junit:junit:4.12

1 probleam 2 resolve method // testCompile junit:junit:4.12

20杨氏矩阵查找

问题描述&#xff1a;在一个m行n列二维数组中&#xff0c;每一行都按照从左到右递增的顺序排序&#xff0c;每一列都按照从上到下递增的顺序排序。请完成一个函数&#xff0c;输入这样的一个二维数组和一个整数&#xff0c;判断数组中是否含有该整数。 例如下面的二维数组就…

玩一玩微信公众号开发(一) 接入系统

一开始我准备学一学微信开发。后来看了一下文档&#xff0c;需要自己搭服务器进行接口对调。有点麻烦所以就没继续学下去。现在学习过了Kotlin、Spring Boot很多东西&#xff0c;感觉可以比较方便的进行开发了。今天就来回过头学习一下。 准备工作 申请公众号 首先说明一下&…

Android studio之NDK integration is deprecated in the current plugin解决办法

1 、问题 编译Android项目&#xff0c;出现下面错误 NDK integration is deprecated in the current plugin 2、解决办法 在我们 gradle.properties(Project Properties) file add android.useDeprecatedNdktrue

使用 System.Net.Http.Json 简化 HttpClient 的使用

使用 System.Net.Http.Json 简化 HttpClient 的使用Intro从 .NET Core 3.1 开始&#xff0c;微软添加了一个 System.Net.Http.Json 的扩展&#xff0c;可以用来简化 HttpClient 的使用&#xff0c;看到在很多项目里还并未开始使用&#xff0c;所以想向大家介绍一下SamplePostAs…

MySQL的四种不同查询的分析

1.前置条件&#xff1a;本次是基于小数据量&#xff0c;且数据块在一个页中的最理想情况进行分析&#xff0c;可能无具体的实际意义&#xff0c;但是可以借鉴到各种复杂条件下&#xff0c;因为原理是相同的,知小见大&#xff0c;见微知著&#xff01;打开语句分析并确认是否已经…

.NET6之MiniAPI(十八):OpenAPI swagger

从本篇开始&#xff0c;介绍一些很不错的三方库&#xff0c;来丰富MiniAPI的使用。在创建MiniAPI项目时&#xff0c;模板提供了一个是否启用OpenAPI的选项&#xff0c;足见这个三方库的优势和强大。OpenAPI为我们测试API提供了强大的支持&#xff0c;调用API的开发人员&#xf…

Android之ndk-build出现c:28:51: error: ‘get_string‘ undeclared here (not in a function)解决办法

1 problem ndk-build error: get_string undeclared here (not in a function) 2 resolve jstring get_strstring(JNIEnv* env, jobject thiz) {return (*env)->NewStringUTF(env, "I am chenyu, 动态注册JNI"); }jint add_int(JNIEnv* env, jobject jobj, ji…

BeetleX服务网关授权配置

很多应用服务都需要授权访问&#xff0c;为了更好地统一处理这种授权验证&#xff0c;服务网关提供了JWT验证插件用于解决这问题。网关的JWT验证插件默认是关闭的&#xff0c;只有当开启后网关才会对请求进行拦截验证处理。开启开启JWT验证需要在插件管理里开启Webapi JWT验证插…

Linux下的压缩与解压缩

tar命令zip命令unzip命令gzip命令bzip2命令tar命令&#xff1a;压缩和解压缩tar格式的文件格式&#xff1a;tar [主选项辅选项] 文件或目录【主选项告诉tar要做什么事&#xff0c;是必须要有的&#xff0c;辅选项是辅助使用的&#xff0c;和通常的选项一样&#xff0c;可选】主…

Android之JNI动态注册native方法和JNI数据简单使用

1、爆结果照片 2、介绍JNI注册方式 JVM 查找 native 方法有两种方式: 1)、按照 JNI 规范的命名规则(静态注册) 2) 、调用 JNI 提供的 RegisterNatives 函数,将本地函数注册到 JVM 中(动态注册) 静态注册的实现可以参考我的这篇博客 http://blog.csdn.net/u01…

Linux怎么查询全部容器时间,linuxea:如何单单修改docker容器的系统时间

一般情况下&#xff0c;我们仅仅需要修改容器的时间与我们宿主机的实际实际一致即可&#xff0c;我们知道&#xff0c;默认情况下docker容器是不允许访问系统时钟&#xff0c;但是有一款开源的软件使这样的需求变成了可能。此lib拦截用于检索当前时间和日期的所有系统调用&…

关闭系统索引(转)

转自“http://jingyan.baidu.com/article/d621e8daeaaa392865913f0a.html” 关闭系统索引 Windows索引服务是为文件、电子邮件和其他内容提供内容索引、属性缓存和搜索结果。 Windows系统在安装完成后&#xff0c;会逐步创建特定文件、文件夹和其它目标的索引&#xff0c;例如开…

如何编译 dotnet/aspnetcore 源代码

前言最近&#xff0c;准备为 dotnet/aspnetcore 修改 issue&#xff0c;但是在 clone 代码后&#xff0c;发现要编译成功&#xff0c;远没有想象中那么容易。因此&#xff0c;将整个过程进行记录&#xff0c;以供大家参考。以下操作都是在 Windows 10 下完成。0.环境准备详见官…

linux 编译工具链,Linux工具链for TKStudio下载_Linux工具链for TKStudio官方下载-太平洋下载中心...

Linux工具链for TKStudio是一款支持TKStudio IDE集成开发环境的辅助LINUX交叉编译工具链软件&#xff0c;交叉编译就是跨架构编译&#xff0c;编译出来的程序不能在本机执行(当然有例外情况)。所以这个时候就需要交叉编译工具链。译工具链一般最简化的为 binutils gcc glibc …

Convolutional Neural Networks for Visual Recognition 1

Introduction 这是斯坦福计算机视觉大牛李菲菲最新开设的一门关于deep learning在计算机视觉领域的相关应用的课程。这个课程重点介绍了deep learning里的一种比较流行的模型&#xff1a;Convolutional Neural Networks&#xff0c;简称CNN&#xff0c;主要利用CNN来做visual r…

记一次 .NET 某供应链WEB网站 CPU 爆高事故分析

一&#xff1a;背景 1. 讲故事年前有位朋友加微信求助&#xff0c;说他的程序出现了偶发性CPU爆高&#xff0c;寻求如何解决&#xff0c;截图如下&#xff1a;我建议朋友用 procdump 在 cpu 高的时候连抓两个dump&#xff0c;这样分析起来比较稳健&#xff0c;朋友也如期的成功…

html5做的太阳系

效果图&#xff1a; 源代码&#xff1a; <!DOCTYPE html><html><head><meta charset"UTF-8"> <title></title></head><body><canvas id"canvas" width"1000" height"1000" style&…