正文
以我调优的集群为例,我所调优的服务器节点内存为 64G,服务器节点上也基本不跑其他服务,所以我把 ES 集群内存大小设置为了 31G,以充分发挥集群性能。
设置 ES 集群内存的时候,还有一点就是确保堆内存最小值(Xms)与最大值(Xmx)的大小是相同的,防止程序在运行时改变堆内存大小,这是一个很耗系统资源的过程。
还有一点就是避免交换内存,可以在配置文件中对内存进行锁定,以避免交换内存(也可以在操作系统层面进行关闭内存交换)。对应的参数:
bootstrap.mlockall: true
分片与副本
分片 (shard):ES 是一个分布式的搜索引擎, 索引通常都会分解成不同部分, 分布在不同节点的部分数据就是分片。ES 自动管理和组织分片, 并在必要的时候对分片数据进行再平衡分配, 所以用户基本上不用担心分片的处理细节。创建索引时默认的分片数为 5 个,并且一旦创建不能更改。
副本 (replica):ES 默认创建一份副本,就是说在 5 个主分片的基础上,每个主分片都相应的有一个副本分片。额外的副本有利有弊,有副本可以有更强的故障恢复能力,但也占了相应副本倍数的磁盘空间。
那我们在创建索引的时候,应该创建多少个分片与副本数呢?
对于副本数,比较好确定,可以根据我们集群节点的多少与我们的存储空间决定,我们的集群服务器多,并且有足够大多存储空间,可以多设置副本数,一般是 1-3 个副本数,如果集群服务器相对较少并且存储空间没有那么宽松,则可以只设定一份副本以保证容灾(副本数可以动态调整)。
对于分片数,是比较难确定的。因为一个索引分片数一旦确定,就不能更改,所以我们在创建索引前,要充分的考虑到,以后我们创建的索引所存储的数据量,否则创建了不合适的分片数,会对我们的性能造成很大的影响。
对于分片数的大小,业界一致认为分片数的多少与内存挂钩,认为 1GB 堆内存对应 20-25 个分片,而一个分片的大小不要超过 50G,这样的配置有助于集群的健康。但是我个人认为这样的配置方法过于死板,我个人在调优 ES 集群的过程中,根据总数据量的大小,设定了相应的分片,保证每一个分片的大小没有超过 50G(大概在 40G 左右),但是相比之前的分片数查询起来,效果并不明显。之后又尝试了增加分片数,发现分片数增多之后,查询速度有了明显的提升,每一个分片的数据量控制在 10G 左右。
查询大量小分片使得每个分片处理数据速度更快了,那是不是分片数越多,我们的查询就越快,ES 性能就越好呢?其实也不是,因为在查询过程中,有一个分片合并的过程,如果分片数不断的增加,合并的时间则会增加,而且随着更多的任务需要按顺序排队和处理,更多的小分片不一定要比查询较小数量的更大的分片更快。如果有多个并发查询,则有很多小碎片也会降低查询吞吐量。
如果现在你的场景是分片数不合适了,但是又不知道如何调整,那么有一个好的解决方法就是按照时间创建索引,然后进行通配查询。如果每天的数据量很大,则可以按天创建索引,如果是一个月积累起来导致数据量很大,则可以一个月创建一个索引。如果要对现有索引进行重新分片,则需要重建索引,我会在文章的最后总结重建索引的过程。