日志是一个写多读少的业务场景,对写入速度要求非常高。以我们的一个集群为例。单集群日志量达到100TB,每秒日志写入次数达到10W。
ES并不是简单的顺序写入。为了构建倒排索引,保证数据的可靠性和实时性,其背后有很多耗时的合并或者额外的操作。磁盘I/O和CPU压力非常大!
使用iotop观察,可以发现ES进程几乎占满了SSD盘的I/O资源,达到了200MB/s+。使用top命令观察发现8核CPU的用户已经快满了。 ES 非常消耗资源。
由于很容易发现系统的瓶颈,所以我们应该重点优化这个资源,将ES的写入速度压榨到极限。
此优化的示例版本是7.9.2。 ES版本升级速度真快,已经彻底脱离5时代了。
1、哪些操作占用资源优化首先要了解ES的编写流程,了解哪些步骤是最耗时的。
首先是副本的问题。为了保证最低的高可用,这里的副本数设置为1,无法保存。因此,将份数设置为0只适合第一次导入数据时。
如上图所示,一条数据需要经过多个步骤才能最终实现。在这个过程中,甚至还会有tranlog等备份机制。
ES的底层存储是Lucene,它包含一系列反向索引。这样的索引称为段。但记录不会直接写入段,而是先写入缓冲区。
当缓冲区满了,或者缓冲区在缓冲区中停留的时间足够长并且达到刷新时间(强调)时,缓冲区的内容将被立即写入段中。
这就是为什么refresh_interval属性的配置会严重影响性能的原因。如果实时性要求不高,不妨配置大一些。
缓冲区默认使用堆空间的10%,最小值为48mb(用于分片)。如果索引很多,写入量很大,这个内存占用就相当可观了,可以适当增加。
2、开始优化数据写入主要有三个动作:flush、refresh、merge。通过调整它们的行为,您可以权衡性能和数据可靠性。
flush从上面的介绍可以看出,translog写入的是全量数据。有点像MysSQL中的binlog或者redis的aof,用于保证异常情况下的数据安全。
这是因为当我们将数据写入磁盘后,我们必须调用fsync将数据刷新到磁盘。如果我们不这样做,系统断电时数据将会丢失。
ES默认对每个请求执行一次flush,但对于日志来说,这不是必需的。您可以使用以下参数将此过程更改为异步:
curl -H'Content-Type:application/json'-XPUT'http://localhost:9200/_all/_settings?preserve_existing=true'-d'{'index.translog.durability'3336 0'async','index.translog.flush_threshold_size':'512mb ','index.translog.sync_interval':'60s'}'这可以说是优化中最重要的一步,对性能影响最大,但是在极端的某些情况下,有可能会丢失一些数据。对于日志系统来说,是可以忍受的。
refreshES除了写入translog之外,还会将数据写入缓冲区。但要注意!此时,无法搜索到缓冲区的内容,仍然需要将其写入段中。
这是刷新动作,默认为1秒。也就是说你写的数据很有可能在1秒后就会被搜索到。
所以ES不是一个实时搜索系统,它是一个近实时系统。
这个刷新间隔可以通过index.refresh_interval来修改。
对于日志系统,当然需要增加。 xjjdog这里调整为120s,减少了这些掉段的频率,速度自然会更快。
curl -H'Content-Type:application/json'-XPUT'http://localhost:9200/_all/_settings?preserve_existing=true'-d'{'index.refresh_interval':'120s'}'merge合并实际上是lucene的机制,它主要是将小段块组合起来生成更大的段,以提高检索速度。
原因是刷新过程会产生很多小段文件,数据删除也会产生空间碎片。所以合并,通俗地说,就像一个碎片整理的过程。像postgresql等,也有vaccum进程做同样的事情。
显然,这种排序操作不仅消耗I/O,还浪费CPU。
可怕的是merge有3种策略。
tiered 默认选项,它合并大小相似的索引段,并考虑每层允许的最大索引段数。 log_byte_size以字节数的对数为计算单位,选择多个索引进行合并并创建新索引。 log_doc以索引段中的文档数为计算单位,选择多个索引进行合并并创建新索引。每个策略都有非常详细的针对性配置,这里不再赘述。
由于日志系统没有随机删除操作,所以我们可以保持默认。
3、微调新版本优化了线程池的配置,不再需要配置复杂的搜索、批量、索引线程池。如果需要,只需配置以下内容:thread_pool.get.size、thread_pool.write.size、thread_pool.listener.size、thread_pool.analyze.size。调整具体observable_cat/thread_pool接口暴露的数据。
事实上,可以通过配置多个磁盘来分散I/O压力,但这很容易导致数据热点集中在单个磁盘上。
Lucene的索引创建过程会消耗大量的CPU。您可以减少倒排索引的数量以减少CPU消耗。第一个优化是减少字段数量;第二个优化是减少索引字段的数量。具体操作是将不需要搜索的字段的索引属性设置为not_analyzed或no。至于_source和_all,在实际调试中作用不大,不再赘述。
另外,如果通过filebeat或logstash等组件传输日志,一般会启用批处理模式。通过批处理可以提高性能,但不宜太大。可以根据实际观察来设定。一般在1k-1w之间。
ES有多种使用场景。鉴于其NoSQL 性质,有些人甚至用它来取代传统的关系数据库。
我们了解到ES写法有flush、refresh、merge三个过程。其中,对I/O影响最大的动作是translog和merge的动作;对CPU影响最大的是索引创建和合并的过程。在普通的映射设计中,我们应该尽量减少字段数量和索引字段数量。这种双管齐下的方法可以解决CPU和I/O两个瓶颈。
本文采摘于网络,不代表本站立场,转载联系作者并注明出处:https://www.iotsj.com//kuaixun/7734.html
用户评论
刚开始看觉得标题有点吓人,但写起来这么专业的文章估计能学到不少.
有10位网友表示赞同!
Elasticsearch的写入速度一直是我比较关注的一点,希望这篇文章能给出一些具体的优化建议。
有11位网友表示赞同!
极限压榨?想想就让人紧张了。希望能详细介绍一些达到极限压榨后需要注意的地方。
有18位网友表示赞同!
现在很多企业都在用 Elasticsearch 做数据分析,提高写入速度确实很重要!
有9位网友表示赞同!
Elasticsearch 确实是一个强大的搜索引擎,但要发挥它的极致性能,肯定需要一些技巧和经验.
有11位网友表示赞同!
51CTO 写的文章质量一向不错,这篇文章应该值得一看。
有7位网友表示赞同!
极限压榨会对 Elasticsearch 的稳定性有什么影响呢?希望这篇文章能解答我的疑问。
有18位网友表示赞同!
Elasticsearch 写入速度慢的问题,我最近遇到的确实比较烦人。希望能从文章中找到一些解决方案。
有17位网友表示赞同!
学习一下高性能 Elasticsearch 优化技巧,以后做数据分析能更有底气!
有15位网友表示赞同!
对 Elasticsearch 不太了解,看了这篇文章或许能入门了?
有7位网友表示赞同!
看来 ElasticSerch 的配置参数很重要啊,想要达到极限压榨肯定要看一些具体的操作步骤。
有19位网友表示赞同!
文章提到极限压榨,会不会导致资源浪费呢?希望能看到一些节约资源的建议。
有13位网友表示赞同!
Elasticsearch 的底层原理我还是不太清楚,这篇文章可能可以让我更深入地了解它了。
有5位网友表示赞同!
学习新的技术手段是很有必要的,希望这篇文章能带给我一些启发。
有6位网友表示赞同!
看到极限压榨我就想到游戏里的高难BOSS,怎么才能战胜呢?
有15位网友表示赞同!
数据分析越来越重要,提高 Elasticsearch 的写入速度确实可以提升工作效率。
有6位网友表示赞同!
51CTO 应该是个很棒的技术网站,我也要经常去看看它的文章了!
有7位网友表示赞同!
Elasticsearch 写入速度慢的问题应该很多人都遇到过吧?这篇文章能提供一些解决方案吗?
有15位网友表示赞同!
学习新的技术总是让人兴奋不已!期待看到这篇文章的具体内容。
有10位网友表示赞同!
也许我也可以尝试一下极限压榨,看看 Elasticsearch 能发挥出多大的潜力?!
有12位网友表示赞同!