gpt4 book ai didi

perl - 成功几次后,Elasticsearch查询突然失败

转载 作者:行者123 更新时间:2023-12-02 22:24:41 26 4
gpt4 key购买 nike

我已经编写了一个Perl脚本,简单来说,它将从Elasticsearch数据库中提取数据并以特定格式打印出来。

如果有任何特定的代码片段有助于解决我的问题,请告诉我,我很乐意在此处发布它们。我不会剪切和粘贴整个脚本,因为它几乎有1000行,这是我公司的属性(property)。

当前使用的模块:严格,警告,LWP::UserAgent,CGI,POSIX,JSON,现代语言:: Perl,术语:: ANSIColor和标量:: 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是否完全查询了数据库。如果为true,则没有更多数据可获取。
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"

我注意到,如果我删除了其中一个字段,那么不管哪个字段,请求都可以顺利通过。

不管是哪个 Realm 。

================================================ =========

编辑#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"}

这完全覆盖了屏幕,直到我中断它为止。

================================================ =========

最终编辑:成功!

声明部分实际上不需要进行任何更改。我确实更改了查询的大小,以便必须进行的查询减少了(我认为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数组中找到的成员之一。如果未定义,则循环失败。

还有其他一些小的变化,但这是真正的大变化。现在效果很好! ...仅两天后。

感谢堆栈溢出!

最佳答案

每个滚动请求都应使用最新的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查询突然失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31689482/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com