使用Elasticsearch,数据量从一亿到百亿的进步

2021年3月25日 17点热度 0条评论 来源: lcfchan

上篇写了ES的服务器配置及架构的演进,这篇来讲讲其它的优化过程。

相信大家基本都跟我一样,开始ES的学习,肯定不会去系统的看书,一是工作上不会给你那么多的时间,二是工作了这么多年,基本上已经没有完整的看一本技术书的能力,基本就是稍微看看官网,再找一两篇网上的文章看看就开始跟着操作了,要在实践中这么做,有时候真的是挺坑的,大部分的文章作者,其实都只是把系统给跑通了,根本没有做过优化,数据量少的时候,顺丰顺水的,数据一多,就有苦头吃了。

1、JVM从32G调整为31G

网上大部分的文章是64G内存的服务器,一般设置一半的内存做为JVM内存,超过32GB时,Java内存指针压缩失效,浪费一些内存,降低了CPU性能,GC压力也较大。但32G内存指针压缩失效这一说法,跟不同的linux版本有关,有看过一篇文章,推导出的大小在31点几G,所以为了保险就设置为31G。

2、设置堆内存断路器,防止OOM

在没有设置堆内存断路器的时候,有同事在聚合的时候,时间段稍微拉长点,就引起了数据节点OOM,导致数据节点退出,然后自动平衡数据,使得系统变的特别慢,后来设置了断路器之后,基本就避免了OOM问题,不过fielddata的断路器只有在有开启fielddata为TRUE时才需要设置,如果不开启不需要设置。

3、默认分片设置

原来默认模板,每个索引都设置10个分片,而且我们是按天来索引的,不管多大的数据量都是一天10个索引,这样产生的分片特别多,占用大量的内存,经过优化,把默认的模板设置分片为1,当数据量一天大于30G以上的,才设置多个分片,按一个分片30G来分配,这样一天产生的分片数降为原来分片数量的20%左右,系统性能明显提高。

4、把index.merge.scheduler.max_thread_count设置为1

这个找了比较久才发现的一个问题,没有设置之前,ES数据节点负载都是很高,基本都在30以上,服务器本身比较老旧,CPU核数16核,而且使用的是老旧的硬盘,在网上搜索很久,查找为什么ES负载会这么高,最后搜索到一篇文章,硬盘如果不是固态硬盘,而且CPU核数本身不是很高,则要把index.merge.scheduler.max_thread_count设置为1,ES默认为3,会产生大量的磁盘I/O等待,所以负载就变的特别高。

5、凌晨对前一天的索引进行force_merge

因 flush间隔为默认的1秒,而且把归并的核心数降低,所以使得系统的分段变的更多,分段太多会带来麻烦,每个段都会消耗文件句柄,内存,所以需要在凌晨的时候,对前一天的大索引进行强制归并。

6、有些索引设置为只保留keyword,不要text字段

ES默认string在索引的时候,会同时生成keyword跟text字段,这样不要用text字段的时候就比较浪费,可以直接在mapping中设置只生成keyword字段。

7、降低查询及写数据的队列大小

ES队列设置太大,会引起堆内存占满的情况,使得FGC特别频繁,系统卡顿就特别多。

8、聚合搬到APACHE DRUID

把聚合搬到APACHE DRUID,让ES只做更擅长的搜索。

经过以上的调整,现在ES系统打开的索引文档数量,由原来打开1亿条就相当卡,到现在打开百亿的量,索引每秒10万左右的文档

    原文作者:lcfchan
    原文地址: https://blog.csdn.net/lcfchan/article/details/115217711
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系管理员进行删除。