几次成功后,Elasticsearch查询突然失败
After several successes, Elasticsearch queries suddenly fail
我编写了一个 Perl 脚本,简而言之,它将从 Elasticsearch 数据库中提取数据并以特定格式打印出来。
如果有任何特定的代码片段有助于解决我的问题,请告诉我,我将非常乐意在此处 post。我不会剪切和粘贴整个脚本,因为它差不多有 1000 行长,而且是我公司的 属性.
当前使用的模块: strict, warnings, LWP::UserAgent, CGI, POSIX, JSON, Modern::Perl, Term::ANSIColor, & Scalar::Util
声明等:
# Declare user agent object
my $ua = LWP::UserAgent->new;
# Set custom HTTP request header fields
my $req = HTTP::Request->new( POST => $serverEndpoint );
$req->header( 'content-type' => 'application/json' );
my $post_data = '{
"fields" : [' . $arrayList . '],
"sort" : [
{ "@timestamp" : { "order" : "asc" } }
],
"query" : {
"filtered" : {
"filter" : {
"range" : {
"@timestamp" : {
"gte" : "' . $lowerBound . '",
"lte" : "' . $upperBound . '"
}
}
}
}
}
}';
$arrayList 之前被定义为一串字段,并用引号括起来(例如 "field1"、"field2"、"field3")。
# Receives results from ES (this is Perl syntax for querying ES)
$req->content( $post_data );
$resp = $ua->request( $req );
$myResults = $resp->content();
#say $myResults; die;
# Changes string (as returned by http request) to JSON format that is compatible with Perl
$decoded = JSON::XS::decode_json( $myResults );
@data = @{ $decoded->{ "hits" }{ "hits" } };
@tempResponse = @data;
my $lengthOfArray = scalar @tempResponse;
至此,@data 已经有了我需要的信息。我已经检查过了,看起来不错。我保存了当前响应的长度以备将来使用。
$scrollID = $decoded->{ "_scroll_id" };
我为下一部分保存卷轴 ID。
现在我有了初始数据集,我反复查询数据库,直到(好吧,至少,应该如此)数据库被完全查询。
如果 $lengthOfArray < 0,我可以知道数据库何时被完全查询。如果这是真的,那么就没有更多的数据可以获取了。
while ( $lengthOfArray > 0 ) {
$ua = LWP::UserAgent->new;
$serverEndpoint = "http://localhost:9200/_search/scroll?scroll=1m&scroll_id=" . $scrollID;
$req = HTTP::Request->new( POST => $serverEndpoint );
$req->header( 'content-type' => 'application/json' );
$req->content( $post_data );
#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
$resp = $ua->request( $req );
#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
$myResults = $resp->content();
# Changes string (as returned by http request) to JSON format that is compatible with Perl
$decoded = JSON::XS::decode_json( $myResults );
@tempResponse = @{ $decoded->{ "hits" }{ "hits" } };
#print "@tempResponse\n";
@data = ( @data, @tempResponse );
$lengthOfArray = scalar @tempResponse;
}
我正在处理的数据集非常庞大。一切都非常顺利(我已经测试过了。如果我只让它 运行 循环 600 次,它就没问题)直到它达到循环计数 #801。 在循环的第 801 次,它挂断了。它在那里停留了大约一分钟,然后死于错误消息:
malformed JSON string, neither tag, array, object, number, string or atom, at character offset 0 (before "read timeout at /usr...")
我已将错误追踪到上面所有 !!!!!s 周围的行。循环在第 801 次循环时挂在该行上。
没有真正的迹象表明为什么会发生此错误。同样,如果我通过循环 800 次而不是 801 次,它会起作用。
我知道所有数据都在 Elasticsearch 中。我应该从中获得大约 12,000 个哈希值。我可以通过@data[0]、@data[1] 等访问前 800 个哈希值,但在那之后我就不走运了。
如有任何帮助,我们将不胜感激。我今天花了整整 9 个小时的工作时间来尝试解决这个问题,但没有成功。真的,如果你甚至可以要求澄清我解释的某些部分,这可能足以找到答案。
所以,如果有任何事情我可以做些什么来清理我输入的内容(显示 ES URL 给出的内容),请告诉我。
非常非常感谢!
======================================== ==================
编辑 #1: 我找到了问题的根源。没有意义,但就是这样。
在 $post_data 我有 $arrayList。它包含我之前从字段数组中获取的 36 个字段的列表。它的格式如下:
"field1","field2","field3","field4"
我注意到,如果我删除其中一个字段,无论是哪个字段,请求都会顺利通过。
哪个字段都无所谓
======================================== ==================
编辑 #2: 这可能会有用。如果我让请求超时,它会给出以下错误消息:
malformed JSON string, neither tag, array, object, number, string or atom, at character offset 0 (before "read timeout at /usr..." at *scriptName.pl* line 403, <STDIN> line 5.
403行如下:
$decoded = JSON::XS::decode_json( $myResults );
就在
的正下方
#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
$resp = $ua->request( $req );
#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
======================================== ==================
编辑 #3: 我尝试打印出 $resp->content() 以查看在挂断之前是否有任何东西看起来很奇怪。它最初并不......内容看起来就像它应该的那样。
不过,过了一会儿,它放弃并打印出以下消息:
{"error":"SearchPhaseExecutionException[Failed to execute phase [query], all shards failed; shardFailures{SearchContextMissingException[No search context found for id [2378]]}{SearchContextMissingException[No search context found for id [2379]]}{SearchContextMissingException[No search context found for id [2380]]}","status:404"}
这完全覆盖了屏幕,直到我打断它。
======================================== ==================
最终编辑:有效!
声明部分确实不需要更改任何内容。我 did 更改了查询的大小,以便减少查询(我认为 ES 的 RAM 已满)。所以现在这就是 $post_data 的样子:
my $post_data = '{
"size": 1000,
"fields" : [' . $arrayList . '],
"sort" : [
{ "@timestamp" : { "order" : "asc" } }
],
"query" : {
"filtered" : {
"filter" : {
"range" : {
"@timestamp" : {
"gte" : "' . $lowerBound . '",
"lte" : "' . $upperBound . '"
}
}
}
}
}
}';
请注意顶部附近的尺寸发生了怎样的变化。我不认为这是解决我的问题的原因,但无论如何它应该有助于提高性能。
我认为我遇到的问题是 while 循环。最初循环被设计为继续 运行 直到 hits 数组为空,但由于某种原因它甚至在那之后继续进行。不知道为什么,也许我稍后会弄清楚。
我所做的是检查是否定义了我期望在 hits 数组中找到的成员之一。如果未定义,则循环失败。
还有其他一些小的变化,但那才是真正的大变化。现在效果很好! ...仅仅2天后。
感谢 Stack Overflow!
每个滚动请求都应该使用最新的 scroll id
即 scroll_id 在上一个滚动响应中返回。
从代码摘录来看,您似乎正在使用第一个响应中的滚动 ID,可能将其更改为使用最新的 scroll_id 应该会有所帮助
即在 while 块中你需要 $scrollID = $decoded->{ "_scroll_id" };
while ( $lengthOfArray > 0 ) {
$ua = LWP::UserAgent->new;
$serverEndpoint = "http://localhost:9200/_search/scroll?scroll=1m&scroll_id=" . $scrollID;
$req = HTTP::Request->new( POST => $serverEndpoint );
$req->header( 'content-type' => 'application/json' );
$req->content( $post_data );
#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
$resp = $ua->request( $req );
#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
$myResults = $resp->content();
# Changes string (as returned by http request) to JSON format that is compatible with Perl
$decoded = JSON::XS::decode_json( $myResults );
$scrollID = $decoded->{ "_scroll_id" };
@tempResponse = @{ $decoded->{ "hits" }{ "hits" } };
#print "@tempResponse\n";
@data = ( @data, @tempResponse );
$lengthOfArray = scalar @tempResponse;
}
可能这应该有所帮助。
我编写了一个 Perl 脚本,简而言之,它将从 Elasticsearch 数据库中提取数据并以特定格式打印出来。
如果有任何特定的代码片段有助于解决我的问题,请告诉我,我将非常乐意在此处 post。我不会剪切和粘贴整个脚本,因为它差不多有 1000 行长,而且是我公司的 属性.
当前使用的模块: strict, warnings, LWP::UserAgent, CGI, POSIX, JSON, Modern::Perl, Term::ANSIColor, & Scalar::Util
声明等:
# Declare user agent object
my $ua = LWP::UserAgent->new;
# Set custom HTTP request header fields
my $req = HTTP::Request->new( POST => $serverEndpoint );
$req->header( 'content-type' => 'application/json' );
my $post_data = '{
"fields" : [' . $arrayList . '],
"sort" : [
{ "@timestamp" : { "order" : "asc" } }
],
"query" : {
"filtered" : {
"filter" : {
"range" : {
"@timestamp" : {
"gte" : "' . $lowerBound . '",
"lte" : "' . $upperBound . '"
}
}
}
}
}
}';
$arrayList 之前被定义为一串字段,并用引号括起来(例如 "field1"、"field2"、"field3")。
# Receives results from ES (this is Perl syntax for querying ES)
$req->content( $post_data );
$resp = $ua->request( $req );
$myResults = $resp->content();
#say $myResults; die;
# Changes string (as returned by http request) to JSON format that is compatible with Perl
$decoded = JSON::XS::decode_json( $myResults );
@data = @{ $decoded->{ "hits" }{ "hits" } };
@tempResponse = @data;
my $lengthOfArray = scalar @tempResponse;
至此,@data 已经有了我需要的信息。我已经检查过了,看起来不错。我保存了当前响应的长度以备将来使用。
$scrollID = $decoded->{ "_scroll_id" };
我为下一部分保存卷轴 ID。
现在我有了初始数据集,我反复查询数据库,直到(好吧,至少,应该如此)数据库被完全查询。
如果 $lengthOfArray < 0,我可以知道数据库何时被完全查询。如果这是真的,那么就没有更多的数据可以获取了。
while ( $lengthOfArray > 0 ) {
$ua = LWP::UserAgent->new;
$serverEndpoint = "http://localhost:9200/_search/scroll?scroll=1m&scroll_id=" . $scrollID;
$req = HTTP::Request->new( POST => $serverEndpoint );
$req->header( 'content-type' => 'application/json' );
$req->content( $post_data );
#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
$resp = $ua->request( $req );
#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
$myResults = $resp->content();
# Changes string (as returned by http request) to JSON format that is compatible with Perl
$decoded = JSON::XS::decode_json( $myResults );
@tempResponse = @{ $decoded->{ "hits" }{ "hits" } };
#print "@tempResponse\n";
@data = ( @data, @tempResponse );
$lengthOfArray = scalar @tempResponse;
}
我正在处理的数据集非常庞大。一切都非常顺利(我已经测试过了。如果我只让它 运行 循环 600 次,它就没问题)直到它达到循环计数 #801。 在循环的第 801 次,它挂断了。它在那里停留了大约一分钟,然后死于错误消息:
malformed JSON string, neither tag, array, object, number, string or atom, at character offset 0 (before "read timeout at /usr...")
我已将错误追踪到上面所有 !!!!!s 周围的行。循环在第 801 次循环时挂在该行上。
没有真正的迹象表明为什么会发生此错误。同样,如果我通过循环 800 次而不是 801 次,它会起作用。
我知道所有数据都在 Elasticsearch 中。我应该从中获得大约 12,000 个哈希值。我可以通过@data[0]、@data[1] 等访问前 800 个哈希值,但在那之后我就不走运了。
如有任何帮助,我们将不胜感激。我今天花了整整 9 个小时的工作时间来尝试解决这个问题,但没有成功。真的,如果你甚至可以要求澄清我解释的某些部分,这可能足以找到答案。
所以,如果有任何事情我可以做些什么来清理我输入的内容(显示 ES URL 给出的内容),请告诉我。
非常非常感谢!
======================================== ==================
编辑 #1: 我找到了问题的根源。没有意义,但就是这样。
在 $post_data 我有 $arrayList。它包含我之前从字段数组中获取的 36 个字段的列表。它的格式如下:
"field1","field2","field3","field4"
我注意到,如果我删除其中一个字段,无论是哪个字段,请求都会顺利通过。
哪个字段都无所谓
======================================== ==================
编辑 #2: 这可能会有用。如果我让请求超时,它会给出以下错误消息:
malformed JSON string, neither tag, array, object, number, string or atom, at character offset 0 (before "read timeout at /usr..." at *scriptName.pl* line 403, <STDIN> line 5.
403行如下:
$decoded = JSON::XS::decode_json( $myResults );
就在
的正下方#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
$resp = $ua->request( $req );
#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
======================================== ==================
编辑 #3: 我尝试打印出 $resp->content() 以查看在挂断之前是否有任何东西看起来很奇怪。它最初并不......内容看起来就像它应该的那样。
不过,过了一会儿,它放弃并打印出以下消息:
{"error":"SearchPhaseExecutionException[Failed to execute phase [query], all shards failed; shardFailures{SearchContextMissingException[No search context found for id [2378]]}{SearchContextMissingException[No search context found for id [2379]]}{SearchContextMissingException[No search context found for id [2380]]}","status:404"}
这完全覆盖了屏幕,直到我打断它。
======================================== ==================
最终编辑:有效!
声明部分确实不需要更改任何内容。我 did 更改了查询的大小,以便减少查询(我认为 ES 的 RAM 已满)。所以现在这就是 $post_data 的样子:
my $post_data = '{
"size": 1000,
"fields" : [' . $arrayList . '],
"sort" : [
{ "@timestamp" : { "order" : "asc" } }
],
"query" : {
"filtered" : {
"filter" : {
"range" : {
"@timestamp" : {
"gte" : "' . $lowerBound . '",
"lte" : "' . $upperBound . '"
}
}
}
}
}
}';
请注意顶部附近的尺寸发生了怎样的变化。我不认为这是解决我的问题的原因,但无论如何它应该有助于提高性能。
我认为我遇到的问题是 while 循环。最初循环被设计为继续 运行 直到 hits 数组为空,但由于某种原因它甚至在那之后继续进行。不知道为什么,也许我稍后会弄清楚。
我所做的是检查是否定义了我期望在 hits 数组中找到的成员之一。如果未定义,则循环失败。
还有其他一些小的变化,但那才是真正的大变化。现在效果很好! ...仅仅2天后。
感谢 Stack Overflow!
每个滚动请求都应该使用最新的 scroll id 即 scroll_id 在上一个滚动响应中返回。
从代码摘录来看,您似乎正在使用第一个响应中的滚动 ID,可能将其更改为使用最新的 scroll_id 应该会有所帮助
即在 while 块中你需要 $scrollID = $decoded->{ "_scroll_id" };
while ( $lengthOfArray > 0 ) {
$ua = LWP::UserAgent->new;
$serverEndpoint = "http://localhost:9200/_search/scroll?scroll=1m&scroll_id=" . $scrollID;
$req = HTTP::Request->new( POST => $serverEndpoint );
$req->header( 'content-type' => 'application/json' );
$req->content( $post_data );
#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
$resp = $ua->request( $req );
#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
$myResults = $resp->content();
# Changes string (as returned by http request) to JSON format that is compatible with Perl
$decoded = JSON::XS::decode_json( $myResults );
$scrollID = $decoded->{ "_scroll_id" };
@tempResponse = @{ $decoded->{ "hits" }{ "hits" } };
#print "@tempResponse\n";
@data = ( @data, @tempResponse );
$lengthOfArray = scalar @tempResponse;
}
可能这应该有所帮助。