柠檬学院马延辉:如何提高ElasticSearch索引速度

合集下载

ElasticSearchIndex速度优化(官方翻译)

ElasticSearchIndex速度优化(官方翻译)

ElasticSearchIndex速度优化(官⽅翻译)使⽤Bulk请求进⾏IndexBulk请求将产⽣⽐单⽂档index请求有更好的性能。

⾄于Bulk请求中⽂档数量的⼤⼩,建议使⽤单⼀节点单⼀分⽚进⾏测试,先试试看100个,然后200个,然后400这样,每次进⾏翻倍测试,只要速度稳定了,也就是最合适的⼤⼩了。

但是要注意⼀下,并不是速度最合适了就OK,因为每次请求总的⼤⼩要进⾏⼀下控制。

并发发送的时候,ES内存压⼒会很⼤,⼀定要避免每次请求超过⼏⼗兆,即便是这样插⼊的性能更好(这个我踩过坑,我这测试超过10M,ES就不接受请求,直接拒绝了)。

使⽤多个节点或者多线程进⾏Index⼀般来说⼀个线程,即便是使⽤了Bulk⽅式进⾏Index,也⽆法达到ES集群的瓶颈,所以为了最⼤限度的利⽤集群资源,使⽤多线程或者多进程的⽅式进⾏Index是⼀个很好的选择。

这样不仅最⼤程度利⽤了集群资源,还帮助减少了fsync的成本。

(这个fsync是什么意思我暂时也没弄明⽩,后续补充)。

要注意⼀下TOO_MANY_REQUESTS (429) 相应(对应Java Client 则是EsRejectedExecutionException), 这说明ES集群已经跟不上你Index的速度了,使⽤⼀些适当的⽅式限制⼀下速度吧。

(官⽅⽂档说暂停Index⼀会或者使⽤随机指数函数Backoff)。

类似Bulk Index 数量,多线程多进程Index也需要进⾏⼈⼯测试,直到找到⼀个合适线程数或者进程数。

增加refresh interval默认的 index.refresh_interval 是1s,在index的时候如果没有实时性检索需求,建议可以设置⼤⼀些,⽐如30S,如果不需要检索,等index完成才进⾏检索的话,可以设置为-1,也就是禁⽤,等完成index之后在调整回来。

禁⽤refresh,降低分⽚副本数如果需要⼀次index⼤量数据,最好禁⽤refresh,也就是将refresh_interval设置为-1,同时index.number_of_replicas 设置为0,也就是不需要副本。

ES大数据量性能优化调优方案

ES大数据量性能优化调优方案

ES大数据量性能优化调优方案在解决ES(Elasticsearch)大数据量性能问题时,可以从以下几个方面进行调优:1.硬件优化:-增加主机的内存容量:ES使用内存作为缓存,增加内存容量可以提高查询性能。

-使用SSD硬盘:SSD硬盘拥有更快的读写速度,可以提高索引和的性能。

-增加CPU核心数量:ES可以利用多核心进行并行处理,增加CPU核心数量可以提高查询和索引性能。

2.配置优化:-配置JVM堆大小:ES默认的JVM堆大小是1GB,可以根据服务器的内存容量适当调大,如设置为服务器总内存的50%。

-设置合理的分片数量:ES将数据分片存储,可以根据数据量和查询负载设置合适的分片数量,避免过多的分片导致资源浪费。

-增加副本数量:ES允许为每个分片设置多个副本,增加副本数量可以提高查询的并发能力和故障容错能力。

-禁用不必要的插件:禁用不必要的插件可以减少ES的启动时间和内存占用。

3.索引设计优化:-尽量减少字段数量:每个字段都需要存储和索引,减少字段数量可以减少存储和索引的开销。

-使用合适的字段类型:选择合适的字段类型可以降低存储空间和查询时间,如数字类型使用整型而不是浮点型。

-压缩索引存储:ES提供了多种索引存储格式,可以选择适合的格式进行索引存储的压缩,减少存储空间。

4.查询调优:- 避免使用全文检索查询:全文检索查询对ES来说是相对较慢的操作,如果只需要进行精确匹配查询,可以考虑使用Term查询。

-使用过滤器:过滤器是一种更快速的查询方式,可以在查询过程中对结果进行筛选,而不会计算相关性得分。

-使用批量操作:批量操作可以减少网络开销和提高吞吐量,对于需要批量处理的查询可以考虑使用批量操作接口。

5.缓存优化:-启用查询缓存:ES提供了查询缓存功能,可以将频繁使用的查询结果缓存起来,提高查询性能。

-使用字段数据加载:字段数据加载可以将字段的值和统计信息加载到内存中,减少查询时的IO操作。

6.集群管理优化:-增加节点数量:增加节点数量可以提高查询的并发能力和故障容错能力。

提升 elasticsearch响应时间的参数

提升 elasticsearch响应时间的参数

一、概述Elasticsearch作为一款开源的分布式搜索引擎,已经被广泛应用于各种企业级应用中。

然而,随着数据量的增长和查询请求的增加,提升Elasticsearch的响应时间成为了许多企业面临的挑战之一。

为了解决这一问题,我们需要对Elasticsearch的参数进行调优,以提高其响应时间和性能。

二、索引设计1. 确保合理的索引设计在使用Elasticsearch时,合理的索引设计是提升响应时间的关键之一。

我们需要确保索引的分片数量是合理的。

一般来说,每个分片的大小应该在10GB到50GB之间,过小或者过大的分片都会影响查询的性能。

我们还需要考虑合理的副本数量,以确保数据的可靠性和高可用性。

2. 使用合适的字段类型在创建索引时,我们需要选择合适的字段类型来存储数据。

对于需要进行全文搜索的文本字段,我们可以选择使用text类型;对于需要进行聚合和排序的字段,可以选择使用keyword类型。

合理选择字段类型可以减少索引的存储空间,并提高查询的性能。

三、硬件配置1. 确保足够的内存Elasticsearch是一个基于内存的搜索引擎,因此足够的内存是保障其性能的重要因素之一。

通常来说,我们建议将至少一半的可用内存分配给Elasticsearch进程,并且避免使用swap分区。

2. 高性能的存储设备除了内存以外,高性能的存储设备也是提升Elasticsearch响应时间的关键。

我们建议使用SSD硬盘来存储数据,以提高数据的读写速度。

四、调优参数1. 索引和搜索性能参数在Elasticsearch中,有许多与性能相关的参数可以进行调优,如index.merge、index.refresh_interval、search.throttled等。

通过合理设置这些参数,我们可以有效地提升Elasticsearch的性能。

通过增大index.refresh_interval的间隔时间,可以减少刷新操作对性能的影响;通过调整search.throttled参数,可以有效地控制搜索请求的并发度。

使用Elasticsearch的动态索引和索引优化

使用Elasticsearch的动态索引和索引优化

使用Elasticsearch的动态索引和索引优化关于映射实际工作中使用过ES的朋友可能会有和静儿一样的感受。

ES存储更新从编码上是很方便。

如下,Kubernetes的yaml文件完全可以通过json直接序列化一下,一行代码存入ES。

剩下的工作可以交给ES进行动态生成映射。

索引映射的生成方式有两种:动态映射字段和映射类型不需要在使用前定义,新字段名可以自动被添加到索引。

只需要更新索引,新字段可以被添加到顶层映射、内部对象或者嵌套字段。

显示的映射动态的映射,字段类型定义靠的ES自己来猜。

开发人员自己比ES 更了解自己的索引字段。

所以有时会需要明确的指定索引类型。

指定索引可以在创建索引时指定,也可以使用PUT API来在已经存在的索引里添加。

使用模板创建索引索引可使用预定义的模板进行创建,这个模板称作Index templates。

模板设置包括settings和mappings,通过模式匹配的方式可以使得多个索引重用一个模板。

别名说起来容易做起来难。

调试中,需要反复的权衡和实践。

发现索引的类型定义不合理,需要在ES平台上进行索引的字段类型修改。

如果使用的是模板方式,修改模板后需要将索引删除后重建生效。

如果只是想重命名一个字段而不修改映射,可以使用别名(alias)字段。

提高索引性能的一些建议提高写入效率1>使用批量请求并调整其大小使用bulk api可以多线程并发创建,并将操作合并批量进行请求。

批量的大小取决于数据、集群配置等。

2>根据日志对故障容忍,合理设置事务日志是同步还是异步因为Translog顺序写日志比构建索引更高效。

为了保证数据的完整性,ES默认每次请求结束都会进行一次sync同步操作。

但是如果是海量的日志,可以容忍发生故障时丢失一定的数据,可以设成异步来提高写效率。

设置参数是:index.translog.durability=async。

提高读取效率1>根据实时性需求调整索引刷新频率如果搜索结果不需要实时性很高,可以按需设置i索引刷新频率。

提升elasticsearch写入速度的案例分享

提升elasticsearch写入速度的案例分享

提升elasticsearch写入速度的案例分享一、背景基本配置5台配置为 24C/125G/17T 的主机,每台主机上搭建了一个elasticsearch节点。

采用的elasticsearch集群版本为7.1.1。

使用的管理工具包括kibana和cerebro。

数据来源数据来源为kafka的三个topic,主要用于实时日志数据的存储和检索,由于实时性要求,所以需要将数据快速的写入到es中。

关注【侠梦的开发笔记】获取更多干货这里就分别称它们为TopicA、TopicB、TopicC吧。

由于是调优写入,所以对源数据的一些基本的指标需要作出一个详细的梳理,便于后续分析。

以下为三个topic的数据产生情况:问题重现在未做任何配置的情况下,分别使用java和logstash进行数据抽取,发现效率都不高,具体问题表现在:1、kafka数据积压严重,消费跟不上生产的速度。

2、elasticsearch集群负载很高,大量写入被拒绝。

3、java程序频繁抛出RejectionException异常。

4、主机cpu异常的高。

操作系统层面及JVM的配置调整这里不再阐述,有很多关于此类的文章可以参考。

我们分模块对各个部分进行调整,具体细节如下。

二、写入程序优化从定数到定量在使用的java程序中,我们将固定条数插入改为固定大小插入,由于使用的es版本较高,直接替换成了官方推荐的BulkProcessor方式。

具体指定属性有:# 每2w条执行一次bulk插入bulkActions: 20000# 数据量达到15M后执行bulk插入bulkSizeMb: 15# 无论数据量多少,间隔20s执行一次bulkflushInterval: 20# 允许并发的bulk请求数concurrentRequests: 10这里的具体配置值,可以根据观察集群状态,来逐步增加。

对于高版本的es,可以通过x-pack的监控页面观察索引速度进行相应调整,如果es版本较低,可以使用推荐的rest api进行逻辑封装。

elasticsearch索引技巧

elasticsearch索引技巧

elasticsearch索引技巧【原创实用版4篇】篇1 目录1.Elasticsearch 简介2.索引的作用3.索引的类型4.索引的技巧5.索引的优化6.总结篇1正文1.Elasticsearch 简介Elasticsearch 是一个基于 Lucene 的分布式搜索和分析引擎。

它能够快速地存储、搜索和分析大量数据。

Elasticsearch 具有高度可扩展性,能够处理 PB 级别的数据。

它广泛应用于日志分析、数据可视化、实时搜索等领域。

2.索引的作用在 Elasticsearch 中,索引是一种重要的数据结构,用于快速查找和定位文档。

索引可以看作是文档的“路由”,它可以根据关键词快速找到相关文档。

有了索引,Elasticsearch 能够在毫秒级别内完成搜索和分析任务。

3.索引的类型Elasticsearch 中有多种索引类型,包括:- BKD 索引:基于文档内容的索引,适用于全文搜索。

- IDX 索引:基于文档 ID 的索引,适用于精确查找。

- TVD 索引:基于文档类型的索引,适用于分类查询。

4.索引的技巧创建索引时,可以采用以下技巧来提高搜索效率:- 选择合适的索引类型:根据搜索需求,选择合适的索引类型。

- 合理分配字段:将相关字段分配到同一个索引中,以提高搜索的准确性。

- 使用预处理:对搜索关键词进行预处理,如分词、拆分等,以提高搜索效果。

5.索引的优化为了提高 Elasticsearch 的性能,可以对索引进行优化:- 优化索引结构:定期对索引进行维护,如合并碎片、更新文档等。

- 缓存索引数据:将热点数据缓存到内存中,以减少磁盘 I/O 操作。

- 调整索引参数:根据实际情况,调整索引的参数,如分配、刷新等。

6.总结Elasticsearch 的索引技巧对于提高搜索性能至关重要。

通过合理创建和管理索引,可以实现高效、准确的搜索和分析。

篇2 目录1.Elasticsearch 简介2.索引的作用3.索引的类型4.索引的优化技巧5.索引的注意事项篇2正文1.Elasticsearch 简介Elasticsearch 是一款开源的分布式搜索引擎,它可以快速地存储、搜索和分析大量数据。

Elasticsearch索引和查询性能调优的21条建议

Elasticsearch索引和查询性能调优的21条建议

Elasticsearch索引和查询性能调优的21条建议Elasticsearch部署建议1. 选择合理的硬件配置:尽可能使⽤ SSDElasticsearch 最⼤的瓶颈往往是磁盘读写性能,尤其是随机读取性能。

使⽤SSD(PCI-E接⼝SSD卡/SATA接⼝SSD盘)通常⽐机械硬盘(SATA盘/SAS盘)查询速度快5~10倍,写⼊性能提升不明显。

对于⽂档检索类查询性能要求较⾼的场景,建议考虑 SSD 作为存储,同时按照 1:10 的⽐例配置内存和硬盘。

对于⽇志分析类查询并发要求较低的场景,可以考虑采⽤机械硬盘作为存储,同时按照 1:50 的⽐例配置内存和硬盘。

单节点存储数据建议在2TB以内,不要超过5TB,避免查询速度慢、系统不稳定。

2. 给JVM配置机器⼀半的内存,但是不建议超过32G修改 conf/jvm.options 配置,-Xms 和 -Xmx 设置为相同的值,推荐设置为机器内存的⼀半左右,剩余⼀半留给操作系统缓存使⽤。

JVM 内存建议不要低于 2G,否则有可能因为内存不⾜导致 ES ⽆法正常启动或内存溢出,JVM 建议不要超过 32G,否则 JVM 会禁⽤内存对象指针压缩技术,造成内存浪费。

机器内存⼤于64G 内存时,推荐配置 -Xms30g -Xmx30g。

JVM 堆内存较⼤时,内存垃圾回收暂停时间⽐较长,建议配置 ZGC 或 G1 垃圾回收算法。

3. 规模较⼤的集群配置专有主节点,避免脑裂问题Elasticsearch 主节点负责集群元信息管理、index 的增删操作、节点的加⼊剔除,定期将最新的集群状态⼴播⾄各个节点。

在集群规模较⼤时,建议配置专有主节点只负责集群管理,不存储数据,不承担数据读写压⼒。

# 专有主节点配置(conf/elasticsearch.yml):node.master:truenode.data: falsenode.ingest:false# 数据节点配置(conf/elasticsearch.yml):node.master:falsenode.data:truenode.ingest:trueElasticsearch 默认每个节点既是候选主节点,⼜是数据节点。

ES集群调整搜索速度一、内存文件系统足够的缓存

ES集群调整搜索速度一、内存文件系统足够的缓存

ES集群调整搜索速度一、内存文件系统足够的缓存一、内存文件系统足够的缓存Elasticsearch严重依赖于文件系统缓存,以加快搜索速度。

通常,您应确保至少有一半的可用内存分配给文件系统缓存,以便Elasticsearch可以将索引的热区保留在物理内存中。

二、使用更快的硬件如果搜索是受CPU限制的,那就加大CPU。

ES对CPU的要求,使用多核CPU优于单核CPU。

如果搜索是在I/O上受限制的话,就需要提供更多的内存和更快的硬盘。

SSD硬盘性能优于机械硬盘,本地硬盘性能优于远程虚拟硬盘。

三、文档建模设计文档应该建模设计,是搜索尽可能的快。

避免使用nested(慢几倍)和父子关系(慢百倍),可以通过对文档进行非规范化的建模设计来达到相同的目的,解决问题。

四、搜索尽可能少的字段query_string或 multi_match查询目标的字段越多,它的速度就越慢。

五、预索引数据您应该利用查询中的模式来优化数据索引的方式。

例如:你有一个类型的文档所有文档都包含一个字段 price,并且你大多数查询的时候都是使用比较固定的大小范围查询或者聚合,此时如果把这个时间分为预索引到文档中,并且使用terms聚合查询会更快。

例如,你有一类型的数据如下PUT index/_doc/1{"designation": "spoon","price": 13并且你搜索的时候经常使用以下范围查询GET index/_search{"aggs": {"price_ranges": {"range": {"field": "price","ranges": [{ "to": 10 },{ "from": 10, "to": 100 },{ "from": 100 }]}}}}此时你就应该在文档索引时添加一个price_range字段,并且映射成keyword类型的PUT index{"mappings": {"_doc": {"properties": {"price_range": {"type": "keyword"}}}}PUT index/_doc/1{"designation": "spoon","price": 13,"price_range": "10-100"}然后查询、聚合的时候就使用这个新的字段来代替price的range 聚合GET index/_search{"aggs": {"price_ranges": {"terms": {"field": "price_range"}}}}六、将标识符映射为keyword类型有些字段虽然是数字类型的,但是实际上并不是都要映射为数字类型。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

我Google了下,大致给出的答案如下:
使用bulk API
初次索引的时候,把replica 设置为0
1.增大threadpool.index.queue_size
2.增大indices.memory.index_buffer_size
3.增大index.translog.flush_threshold_ops
4.增大index.translog.sync_interval
5.增大index.engine.robin.refresh_interval
这篇文章会讲述上面几个参数的原理,以及一些其他的思路。

这些参数大体上是朝着两个方向优化的:
●减少磁盘写入
●增大构建索引处理资源
一般而言,通过第二种方式的需要慎用,会对集群查询功能造成比较大的影响。

这里还有两种形态的解决方案:
●关闭一些特定场景并不需要的功能,比如Translog或者Version等
●将部分计算挪到其他并行计算框架上,比如数据的分片计算等,都可以放到Spark上事先算好
上面的参数都和什么有关
●其中5,6 属于TransLog 相关。

●4 则和Lucene相关
●3 则因为ES里大量采用线程池,构建索引的时候,是有单独的线程池做处理的
●7 的话个人认为影响不大
●2 的话,能够使用上的场景有限。

个人认为Replica这块可以使用Kafka的ISR机制。

所有数据还是都从Primary写和读。

Replica尽量只作为备份数据。

Translog
为什么要有Translog? 因为Translog顺序写日志比构建索引更高效。

我们不可能每加一条记录就Commit一次,这样会有大量的文件和磁盘IO产生。

但是我们又想避免程序挂掉或者硬件故障而出现数据丢失,所以有了Translog,通常这种日志我们叫做Write Ahead Log。

为了保证数据的完整性,ES默认是每次request结束后都会进行一次sync操作。

具体可以查看如下方法:
该方法会调用IndexShard.sync 方法进行文件落地。

你也可以通过设置index.translog.durability=async 来完成异步落地。

这里的异步其实可能会有一点点误导。

前面是每次request结束后都会进行sync,这里的sync仅仅是将Translog落地。

而无论你是否设置了async,都会执行如下操作:根据条件,主要是每隔sync_interval(5s) ,如果flush_threshold_ops(Integer.MAX_VALUE),flush_threshold_size(512m),flush_threshold_period(30m) 满足对应的条件,则进行flush操作,这里除了对Translog进行Commit以外,也对索引进行了Commit。

所以如果你是海量的日志,可以容忍发生故障时丢失一定的数据,那么完全可以设置,index.translog.durability=async,并且将前面提到的flush*相关的参数调大。

而极端情况,你还可以有两个选择:
●设置index.translog.durability=async,接着设置index.translog.disable_flush=true 进行禁用定时flush。

然后你可以通过应用程序自己手动来控制flush。

●通过改写ES 去掉Translog日志相关的功能。

当然,如果去掉Translog日志有两个风险点:
●Get最新数据会有点问题。

因为根据ID Get最新数据是从Translog里拿的。

●我们知道ES通过Shard Replication 保证Node节点出现故障时出现数据的完整性。

在Relocating的时候,Replica 从Primary 进行Recover时,Primary会先Snapshot Lucene,然后拷贝数据到Replica,最后通过回放Translog 保证数据的一致性。

Version
Version可以让ES实现并发修改,但是带来的性能影响也是极大的,这里主要有两块:
需要访问索引里的版本号,触发磁盘读写
锁机制
目前而言,似乎没有办法直接关闭Version机制。

你可以使用自增长ID并且在构建索引时,index 类型设置为create。

这样可以跳过版本检查。

这个场景主要应用于不可变日志导入,随着ES被越来越多的用来做日志分析,日志没有主键ID,所以使用自增ID是合适的,并且不会进行更新,使用一个固定的版本号也是合适的。

而不可变日志往往是追求吞吐量。

当然,如果有必要,我们也可以通过改写ES相关代码,禁用版本管理。

分发代理
ES是对索引进行了分片(Shard),然后数据被分发到不同的Shard。

这样查询和构建索引其实都存在一个问题:
如果是构建索引,则需要对数据分拣,然后根据Shard分布分发到不同的Node节点上。

如果是查询,则对外提供的Node需要收集各个Shard的数据做Merge
这都会对对外提供的节点造成较大的压力,从而影响整个bulk/query 的速度。

一个可行的方案是,直接面向客户提供构建索引和查询API的Node节点都采用client模
式,不存储数据,可以达到一定的优化效果。

另外一个较为麻烦但似乎会更优的解决方案是,如果你使用类似Spark Streaming这种流式处理程序,在最后往ES输出的时候,可以做如下几件事情:
●获取所有primary shard的信息,并且给所有shard带上一个顺序的数字序号,得到
partition(顺序序号) -> shardId的映射关系
●对数据进行repartition,分区后每个partition对应一个shard的数据
●遍历这些partions,写入ES。

方法为直接通过RPC 方式,类似
transportService.sendRequest 将数据批量发送到对应包含有对应ShardId的Node 节点上。

这样有三点好处:
1.所有的数据都被直接分到各个Node上直接处理。

避免所有的数据先集中到一台服
务器
2.避免二次分发,减少一次网络IO
3.防止最先处理数据的Node压力太大而导致木桶短板效应
场景
因为我正好要做日志分析类的应用,追求高吞吐量,这样上面的三个优化其实都可以做了。

一个典型只增不更新的日志入库操作,可以采用如下方案:
1.对接Spark Streaming,在Spark里对数据做好分片,直接推送到ES的各个节点
2.禁止自动flush操作,每个batch 结束后手动flush。

3.避免使用Version
我们可以预期ES会产生多少个新的Segment文件,通过控制batch的周期和大小,预判出ES Segment索引文件的生成大小和Merge情况。

最大可能减少ES的一些额外消耗
总结
大体是下面这三个点让es比原生的lucene吞吐量下降了不少:
为了数据完整性ES额外添加了WAL(tanslog)
为了能够并发修改添加了版本机制
对外提供服务的node节点存在瓶颈
ES的线性扩展问题主要受限于第三点,
具体描述就是:
如果是构建索引,接受到请求的Node节点需要对数据分拣,然后根据Shard分布分发到不同的Node节点上。

如果是查询,则对外提供的Node需要收集各个Shard的数据做Merge
另外,索引的读写并不需要向Master汇报。

相关文档
最新文档