elasticsearch 大数据下 bulk 优化

2022-04-13  本文已影响0人  King斌

es中 bulk api 可以在单个API调用中执行许多索引/删除操作,这可以大大提高索引速度。在线上突然遇到这样错误:

2019-02-27  12:19:07.836  [inner-job-enable-job-61]  ERROR  com.dangdang.ddframe.job.executor.handler.impl.DefaultJobExceptionHandler  :?  -  Job  'enable-job'  exception  occur  in  job  processing
java.lang.RuntimeException:  ElasticsearchStatusException[Unable  to  parse  response  body];  nested:  ResponseException[method  [POST],  host  [http://10.80.229.22:9200],  URI  [/_bulk?timeout=1m],  status  line  [HTTP/1.1  413  Request  Entity  Too  Large]
];
                at  com.kxtx.opa.es.config.ElasticsearchTemplate.commonExceptionHandle(ElasticsearchTemplate.java:290)
                at  com.kxtx.opa.es.config.ElasticsearchTemplate.batchSave(ElasticsearchTemplate.java:153)
                at  com.kxtx.opa.timer.ProductEnableTimer.realSaveOrUpdateElastic(ProductEnableTimer.java:193)
                at  com.kxtx.opa.timer.ProductEnableTimer.execute(ProductEnableTimer.java:92)
                at  com.dangdang.ddframe.job.executor.type.SimpleJobExecutor.process(SimpleJobExecutor.java:41)
                at  com.dangdang.ddframe.job.executor.AbstractElasticJobExecutor.process(AbstractElasticJobExecutor.java:206)
                at  com.dangdang.ddframe.job.executor.AbstractElasticJobExecutor.access$000(AbstractElasticJobExecutor.java:47)
                at  com.dangdang.ddframe.job.executor.AbstractElasticJobExecutor$1.run(AbstractElasticJobExecutor.java:185)
                at  java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
                at  java.util.concurrent.FutureTask.run(FutureTask.java:266)
                at  java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
                at  java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
                at  java.lang.Thread.run(Thread.java:748)
Caused  by:  org.elasticsearch.ElasticsearchStatusException:  Unable  to  parse  response  body
                at  org.elasticsearch.client.RestHighLevelClient.parseResponseException(RestHighLevelClient.java:598)
                at  org.elasticsearch.client.RestHighLevelClient.performRequest(RestHighLevelClient.java:501)
                at  org.elasticsearch.client.RestHighLevelClient.performRequestAndParseEntity(RestHighLevelClient.java:474)
                at  org.elasticsearch.client.RestHighLevelClient.bulk(RestHighLevelClient.java:246)
                at  com.kxtx.opa.es.config.ElasticsearchTemplate.batchSave(ElasticsearchTemplate.java:150)
                ...  11  common  frames  omitted
                Suppressed:  java.lang.IllegalStateException:  Elasticsearch  didn't  return  the  [Content-Type]  header,  unable  to  parse  response  body
                                at  org.elasticsearch.client.RestHighLevelClient.parseEntity(RestHighLevelClient.java:611)
                                at  org.elasticsearch.client.RestHighLevelClient.parseResponseException(RestHighLevelClient.java:594)
                                ...  15  common  frames  omitted
Caused  by:  org.elasticsearch.client.ResponseException:  method  [POST],  host  [http://10.80.229.22:9200],  URI  [/_bulk?timeout=1m],  status  line  [HTTP/1.1  413  Request  Entity  Too  Large]

                at  org.elasticsearch.client.RestClient$1.completed(RestClient.java:358)

业务反馈,才1w多条就报这个!如果你对nginx足够的了解会发现这个错误是它的,接下来要看nginx的配置文件,最终确人有个参数值 client_max_body_size 太小,那就改大些吧!那es能接受多大的呢?es的bulk的批量究竟该多大,之前讲过,这里不再啰嗦。

那就5000条一个批次,但是es还是比较慢!这里分享几个优化的小技巧

1. refresh间隔

调整refresh时间间隔,优化点: 减少刷新频率,降低潜在的写磁盘性能损耗, 默认的刷新时间间隔是1s,对于写入量很大的场景,这样的配置会导致写入吞吐量很低,适当提高刷新间隔,可以提升写入量,代价就是让新写入的数据在60s之后可以被搜索,新数据可见的及时性有所下降。

在bulk大量数据到ES集群的时候可以关闭刷新频率,把其值设置为-1就是关闭了刷新频率,在导入完之后设置成合理的值即可。

2. replica数目

调整replica数目,在bulk大量数据到ES集群的可以把副本数设置为0,在数据导入完成之后再设置为1或者你集群的适合的数目。

3. 去掉_all字段

Index中默认会有_all这个字段(es6.x已经禁用),默认会把所有字段的内容都拷贝到这一个字段里面,这样会给查询带来方便,但是会增加索引时间和索引尺寸。

4. translog优化

translog默认为512MB,flush操作达到512MB fsync刷新到硬盘(这个问题不大),而translog是默认是每次index请求都写磁盘,优化点: 减少写磁盘的频率,调整为index.translog.durability=async,index.translog.sync_interval=30s(默认值是5s)

5. segment合并

更多

6. mapping优化

由于es自动检测和添加新字段称为动态映射,我见过由于环境问题发生mapping漏设置,这时有300~400个字段自动映射为text类型(太多),导致每批次(5000条)插入响应时间都大于3分钟。总之,检查mapping的合理性很重要。

7. ES的JVM内存大小

修改配置文件调整ES的JVM内存大小,这个值不能超过32g,一般机器好点设置成十几个g速度就非常快了。具体要看自己机器的内存。

优化项按顺序进行,越靠前优化效果越明显。

上一篇下一篇

猜你喜欢

热点阅读