Elasticsearch调优篇 04

1、使用 bulk 批量写入

  你如果要往es里面灌入数据的话,那么根据你的业务场景来,如果你的业务场景可以支持让你将一批数据聚合起来,一次性写入es,那么就尽量采用bulk的方式,每次批量写个几千条这样子。

  bulk批量写入的性能比你一条一条写入大量的 document 的性能要好很多。但是如果要知道一个bulk请求最佳的大小,需要对单个 es node 的单个 shard 做压测。

  先 bulk 写入 100 个 document,然后 200个,400个,以此类推,每次都将 bulk size 加倍一次。如果bulk写入性能开始变平缓的时候,那么这个就是最佳的bulk大小。

  并不是 bulk size 越大越好,而是根据你的集群等环境具体要测试出来的,因为越大的 bulk size 会导致内存压力过大,因此最好一个请求不要发送超过 10MB 的数据量。

  先确定一个是 bulk size,此时就尽量是 单线程,一个es node,一个 shard,进行测试。看看单线程最多一次性写多少条数据,性能是比较好的。

2、使用多线程写入 elasticsearch

  单线程发送bulk请求是无法最大化es集群写入的吞吐量的。

  如果要利用集群的所有资源,就需要使用多线程并发将数据bulk写入集群中。

  为了更好的利用集群的资源,这样多线程并发写入,可以减少每次底层磁盘 fsync 的 次数 和 开销。

  首先对单个es节点的单个shard做压测,比如说,先是2个线程,然后是4个线程,然后是8个线程,16个,每次线程数量倍增。

  一旦发现es返回了 TOO_MANY_REQUESTS 的错误,JavaClient也就是 EsRejectedExecutionException。

  此时那么就说明 es 是已经到了一个并发写入的最大瓶颈了,此时我们就知道最多只能支撑这么高的并发写入了。

3、禁用一些无用字段

  1. 关闭 _all 配置选项,降低内存使用量以及提升写入速度

  2. 内存是宝贵的,每次创建索引的时候要做到充分利用,即

    <1. 有的字段不用的我们坚决不索引

    <2. 各个字段含义清晰就设置为最小类型

    <3. 有些大文本字段如果只用于召回,不用于返回数据,尽可能的只索引不存储

4、refresh 和 replia

  这要分两种情况来对待,分别为:全量重建索引 和 实时增量索引

  全量重建索引

  可以禁止 refresh 和 replica,即 index.refresh_interval = -1 & index.number_of_replicas = 0

  <1. 此时就不需要创建 segment file,对应文件句柄少了,所消耗的资源也会降低很多

  <2. 创建的 segment 文件少了,对应 merge 的压力也会降下来

  <3. 不需要将数据复制到其他的 replica shards 上面去,降低了保证数据一致性的耗时

  此时写入的速度会非常快。

  一旦写完之后,我们做完对应的 merge optimization 优化就可以将相关参数复原。

  实时增量索引

  默认的refresh间隔是 1s,用 index.refresh_interval 参数可以设置,这样会其强迫 es 每秒中都将内存中的数据写入磁盘中,创建一个新的segment file。

  正是这个间隔,让我们每次写入数据后,1s以后就可以看到。

  但是如果我们将这个间隔调大,比如30s,可以接受写入的数据30s后才看到,那么我们就可以获取更大的写入吞吐量,因为30s内都是写内存的,每隔30s才会创建一个segment file。

5、使用自动生成的 id

  如果我们要手动给 es document 设置一个id,那么 es 需要每次都去确认一下那个id是否存在于相同的分片中,这个过程是比较耗费时间的。

  如果我们使用自动生成的id,那么es就可以跳过这个步骤,写入性能会更好。对于你的业务中的表id,可以作为 es document 的一个 field。

6、用性能更好的硬件设备

  可以使用性能更好的 SSD 磁盘来替代 机械磁盘

原文地址:https://www.cnblogs.com/liang1101/p/13188979.html