Spark Elasticsearch Bad Request(400)

Posted 柚子聊大数据

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spark Elasticsearch Bad Request(400)相关的知识,希望对你有一定的参考价值。

一、问题描述

据现场同事反馈——系统升级前,每天大概100+w的数据量,但升级后数据量仅剩几w。前端设备是不是推送的量变少了?出现了“脏数据”?都没有~~~

最终在Spark UI界面发现导入es时,每个批次es job均有若干个任务是失败的,从而导致数据量锐减。(虽然批次任务失败,但是spark streaming流依然存在)具体的异常如下:

Job aborted due to stage failure: Task 2 in stage 36560.0 failed 4 times, most recent failure: Lost task 2.3 in stage 36560.0 (TID 2091370, fuding-12, executor 2): org.apache.spark.util.TaskCompletionListenerException: Found unrecoverable error [127.0.0.1:9200returned Bad Request(400) - failed to parse; Bailing out..

Job aborted due to stage failure: Task 2 in stage 36560.0 failed 4 times, most recent failure: Lost task 2.3 in stage 36560.0 (TID 2091370, fuding-12, executor 2): org.apache.spark.util.TaskCompletionListenerException: Found unrecoverable error [127.0.0.1:9200returned Bad Request(400) - failed to parse; Bailing out..
 at org.apache.spark.TaskContextImpl.invokeListeners(TaskContextImpl.scala:138)
 at org.apache.spark.TaskContextImpl.markTaskCompleted(TaskContextImpl.scala:116)
 at org.apache.spark.scheduler.Task.run(Task.scala:124)
 at org.apache.spark.executor.Executor$TaskRunner.run(Executor.scala:335)
 at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
 at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
 at java.lang.Thread.run(Thread.java:748)
Driver stacktrace:

HTTP状态码是400,印象中是client端错误~但是task并非全部都失败,按道理来说项目代码应该是没问题的~

二、定位过程

2.1、查看es集群是否正常

查看索引状态

curl '192.168.0.7:9200/_cat/indices/20201219?v'

结果索引状态为yellow。

ES集群状态有三种状态——green、yellow、red;
green,primary shard、replica shard均正常使用;
yellow,primary shard可用,部分replica shard不可用;
red,部分primary shard不可用;

该项目ES集群总共两台机器,其中master node 2个,data node 6个。索引副本为2,理论上不应该会出现green状态,于是再去查看es集群在线节点。

// 这里假设192.168.0.7、192.168.0.8就是集群里的两台机器;
curl '192.168.0.7:9200/_cat/nodes?v'
curl '192.168.0.8:9200/_cat/nodes?v'

查询发现,此时的es集群出现了脑裂(上述两个请求结果显示的cluster_uuid不一样)

首先,复习一下es集群节点类型:master、data、ingest、ml、remote_cluster_client、transform
本现场使用elasticsearch版本时6.1.3,且其中node仅有master、data两种类型.
正常情况下,在master角色的节点中,通过选举机制,任意时刻仅仅会选举出一个leader.但是,当follower master node节点与leader master node节点在通信过程中,比如leader master node GC时间长,返回响应较慢,那么follower master node可能会重新触发一下选举,从而在es集群中,出现两个leader master node.
触发master选举的条件:
超过discovery.zen.minimum_master_nodes的候选master node觉得es集群没有leader master node .(官方建议该参数设置为N/2+1,即当集群有master类型节点3个时,该值设为2)

最终,通过重启的方式解决了脑裂的问题,集群、索引慢慢的从yellow状态恢复成green状态。

当集群状态恢复成green时,再次运行业务流程,报错仍然存在。

2.2、查看es服务端日志

尽管HTTP 400在我的印象中是客户端问题,服务端应该没有什么有用的日志,但没有其他可行思路,也只能去es服务端日志找找看~

无意中竟然发现了如下报错:

[2020-12-16T14:44:18,963][DEBUG][o.e.a.b.TransportShardBulkAction] [20201216][2failed to execute bulk item (index) BulkShardRequest [[20201216][2]] containing [index {[20201216][type1][6703f93f2a277c9db342f04aa7ca9023], source[{..."location":"120.20235,120.20235"...}]}]
org.elasticsearch.index.mapper.MapperParsingException: failed to parse
at org.elasticsearch.index.mapper.DocumentParser.wrapInMapperParsingException(DocumentParser.java:175) ~[elasticsearch-6.1.3.jar:6.1.3]
...
Caused by: java.lang.IllegalArgumentException: illegal latitude value [120.20235for location
at org.elasticsearch.index.mapper.GeoPointFieldMapper.parse(GeoPointFieldMapper.java:209) ~[elasticsearch-6.1.3.jar:6.1.3]
at org.elasticsearch.index.mapper.GeoPointFieldMapper.parsePointFromString(GeoPointFieldMapper.java:309) ~[elasticsearch-6.1.3.jar:6.1.3]
at org.elasticsearch.index.mapper.GeoPointFieldMapper.parse(GeoPointFieldMapper.java:289) ~[elasticsearch-6.1.3.jar:6.1.3]
at org.elasticsearch.index.mapper.DocumentParser.parseObjectOrField(DocumentParser.java:485) ~[elasticsearch-6.1.3.jar:6.1.3]
at org.elasticsearch.index.mapper.DocumentParser.parseValue(DocumentParser.java:607) ~[elasticsearch-6.1.3.jar:6.1.3]
at org.elasticsearch.index.mapper.DocumentParser.innerParseObject(DocumentParser.java:407) ~[elasticsearch-6.1.3.jar:6.1.3]
at org.elasticsearch.index.mapper.DocumentParser.parseObjectOrNested(DocumentParser.java:384) ~[elasticsearch-6.1.3.jar:6.1.3]
at org.elasticsearch.index.mapper.DocumentParser.internalParseDocument(DocumentParser.java:93) ~[elasticsearch-6.1.3.jar:6.1.3]
at org.elasticsearch.index.mapper.DocumentParser.parseDocument(DocumentParser.java:67) ~[elasticsearch-6.1.3.jar:6.1.3]
... 32 more
[2020-12-16T14:44:18,964][DEBUG][o.e.a.b.TransportShardBulkAction] [20201216][2failed to execute bulk item (index) BulkShardRequest [[20201216][2]] containing [3] requests

该堆栈信息明确的显示了bulk requests失败的原因——纬度值120+,超出了范围(纬度的范围为-90~+90,经度的范围为-180~+180)

最终修正业务字段,最终解决了该问题~

三、总结

  • http 400错误虽然是客户端发送请求时,请求体的内容有问题,但是服务器端是接收到了请求,只不过处理有异常而已。
  • es集群的健康状态分为三种类型:green、yellow、red。
  • es集群在leader master响应时间长时,可能会出现脑裂现象,目前es尚不能完全避免脑裂现象。
  • 纬度的范围为-90~+90,经度的范围为-180~+180

四、参考链接

1、http://mp.weixin.qq.com/s?__biz=MzI3NDc4NTQ0Nw==&mid=2247495035&idx=2&sn=05d56806e9dd42774d2982e8e28f7146&scene=6#wechat_redirect
2、https://www.cnblogs.com/zhukunrong/p/5224558.html
3、https://blog.csdn.net/wfs1994/article/details/80322529


以上是关于Spark Elasticsearch Bad Request(400)的主要内容,如果未能解决你的问题,请参考以下文章

Amazon s3a 使用 Spark 返回 400 Bad Request

尝试从 Spark 访问 S3 时出现 400 Bad Request

spark集群--elasticsearch

Spark-Cassandra 与 Spark-Elasticsearch

spark出现task不能序列化错误的解决方法 org.apache.spark.SparkException: Task not serializable

elasticsearch spark hadoop integration